Lua - lstring
2015-10-30 12:55
756 查看
lstring
lstring数据结构
lua_State和global_State
API
lstring实现了Lua对于字符串的管理.
字符串对象的结构体声明在lobject中. Lua中的字符串可以是C语言的
'\0'结尾的连续字符数组, 也可以单纯是一块连续内存的内容, 包含任何字节内容.
#define LUA_TSTRING 4 /* Variant tags for strings */ #define LUA_TSHRSTR (LUA_TSTRING | (0 << 4)) /* short strings */ #define LUA_TLNGSTR (LUA_TSTRING | (1 << 4)) /* long strings */
在Lua中, 字符串根据长度
LUAI_MAXSHORTLEN( 默认40) 区分长短字符串, 分为
LUA_TLNGSTR和
LUA_TSHRSTR. 对短字符串进行hash后, 保存起来, 进行复用.
数据结构
/* ** Header for string value; string bytes follow the end of this structure ** (aligned according to 'UTString'; see next). */ typedef struct TString { CommonHeader; lu_byte extra; /* reserved words for short strings; "has hash" for longs */ lu_byte shrlen; /* length for short strings */ unsigned int hash; union { size_t lnglen; /* length for long strings */ struct TString *hnext; /* linked list for hash table */ } u; } TString;
CommonHeader
extra: luaX_init中使用到这个, 用来表示是关键字类别.
shrlen: 短字符串的长度
hash: hash值
u.lnglen: 长字符串的长度
u.hnext: 如果出现hash碰撞, 则将碰撞内容链接到链表内
/* ** Ensures that address after this type is always fully aligned. */ typedef union UTString { L_Umaxalign dummy; /* ensures maximum alignment for strings */ TString tsv; } UTString;
将
TString进行内存对齐.
L_Umaxalign默认是一个union, 内容和部分union Value一致.
lua_State
和global_State
在lua_State的l_G中引用了这个
lua_State所属的
global_State. 在
global_State中有几个被用到的域
TString *strcache[STRCACHE_SIZE][1]; /* cache for strings in API */
strcache是长字符串的hash表, 默认长字符串使用地址对strcache的大小取余来获取存取地址. 可以通过
luaS_clearcache来清空.
都是以
'\0'结尾的字符串.
TString *memerrmsg; /* memory-error message */
memerrmsg是在
luaS_init的时候没设置成
MEMERRMSG(
"not enough memory"). 在
luaS_init中调用了
luaC_fix将这个字符串强制标记为不可被GC回收. 也是所有短字符串的默认值. rehash后
stringtable strt; /* hash table for strings */
strt保存hash过的短字符串. 用
luaS_remove从中删除字符串对象,
API
luaS_eqlngstr比较长字符串, assert同类型, 先看是否指向同一对象, 在比较长度是否相等, 最后利用字符串长度, 用
memcmp比较内存内容.
luaS_hash计算字符串的hash值. 对于长度小于
2^LUAI_HASHLIMIT的字符串, 每字节都参加计算hash(
LUAI_HASHLIMIT默认为5). 长度大于32的字符串, 从末尾开始, 每
(l >> LUAI_HASHLIMIT) + 1参加计算hash值.
如果长度一样, 但是参加计算的字符也是一样的, 就会增加hash碰撞
luaS_resize拓展
L->l_G->strt并将拓展部分置
NULL. 如果
newsize小于
strt的长度, 那么就会截取.
所以必须保证, 截取的时候, 截取位置之后没有hash.
luaS_clearcache: 如果
g->strcache[i][0]为
white, 则将里面的指向
g->memerrmsg
为什么不置为
NULL, 而要置为一个不可回收的字符串呢?
luaS_init利用
luaS_resize初始化
L->l_G->strt为
MINSTRTABSIZE(128)个元素. 将
g->memerrmsg置为
MEMERRMSG(
"not enough memory") , 并使其不可被GC回收. 初始化
g->strcache的每个元素指向
g->memerrmsg.
createstrobj创建字符串对象. 调用到了
luaC_newobj, 等看到GC的时候再返回看这个函数.
luaS_remove将
TString从
L->l_G->strt中移除, 这个
TString需要已经计算出hash值.
internshrstr检查短字符串是否在
strt内, 如果存在, 则复用, 否则检查是否需要rehash, 最后, 创建新的短字符串对象, 并放入
strt中.
luaS_newlstr创建字符串对象. 对短字符串进行
internshrstr, 对长字符串, 字节创建对象. 长字符串对象的hash是他的长度, 末尾会添加
'\0'
luaS_new创建或复用
'\0'结尾的字符串, 首先在
L->l_G->strcache内用地址作为hash键值查找, 看是否有内容相同的
'\0'结尾的字符串. 有则复用, 没有则利用
luaS_newlstr创建长字符串对象.
luaS_newudata和创建
userdata相关
相关文章推荐
- Lua篇(第06章):Lua调用C++的函数
- Lua篇(第05章):C++调用Lua的函数
- Lua篇(第04章):来点高难度的,获取Lua表结构数据
- Lua篇(第03章):简单解析Lua的堆栈
- Lua篇(第02章):Demo讲解之Lua和C++牵手
- Lua篇(第01章):让Lua和C++牵手
- lua的时间和日期函数
- Lua 元表
- Ngx_lua 最佳技术实践 | UPYUN技术现场
- Lua(一)
- C言扩展lua模块(入门)
- coocs2dx3.2 绑定自定义C++类到lua
- lua垃圾回收机制
- 用C语言扩展lua模块(入门)
- lua字符串分割
- Lua协程
- Lua语言实现简单的多线程模型
- 当mac升级到EI Caption后绑定到Js、lua出现LibclangError: dlopen(libclang.dylib, 6)的错误
- Lua视频教程连载(第一课)
- lua State加载部分库