// lobject.h
/*** string headers for string table
*/typedef
union tstring tsv;
} tstring;
上面是lua中字串的資料結構。可以看到,tstring
中並沒有出現顯式的char*
變數,而是儲存了雜湊值和長度。
所以,這裡面沒有儲存字元嗎?我們來看一下tstring
的建立函式。
先貼一下對應的原始碼:
// lstring.c
tstring *luas_newlstr (lua_state *l,
const
char
*str, size_t l)
}return
newlstr
(l, str, l, h)
;/* not found */
}
函式傳入字串str
和長度l
,首先計算字串的雜湊值h
,然後在全域性的字串表中查詢,比較字串長度和記憶體,如果找到則直接返回已經建立好的字串,否則新建。
看一下全域性字串表strt
的定義:
// lstate.h
/*** `global state', shared by all threads of this state
*/typedef
struct global_state stringtable;
strt
定義在全域性狀態中,hash
是乙個儲存了所有tstring
的雜湊表。遍歷這個表可以找到lua中所有的字串。
在hash
的查詢過程中有乙個條件:if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0))
,這裡先比較了長度,然後又比較了字串記憶體,來看一下getstr
:
// lobject.h
#define getstr(ts) cast(const char *, (ts) + 1)
這裡把str
與已建立字串ts
後面的記憶體進行比較,所以我們可以猜測,tstring
中也儲存了字串,就在緊鄰的記憶體區域中。
進一步來看一下新建字串的函式tstring *newlstr (lua_state *l, const char *str, size_t l, unsigned int h)
:
// lstring.c
static tstring *newlstr (lua_state *l,
const
char
*str, size_t l,
unsigned
int h)
字串表中沒有找到時,就會進入這個函式新建字串。
分配記憶體時,除了tstring
的空間,還多分配了l+1
位元組,用來儲存傳入的字串,這裡也驗證了之前的猜想。tstring
新建之後,根據字串雜湊值再次計算新的雜湊值h
,然後插入全域性字串表strt
中。可以看到,strt
的雜湊表與table
的雜湊表不同:table
的雜湊表採用的是開放定址法,而strt
的雜湊表則用的鏈位址法。
如果插入後發現全域性字串錶太大,就會呼叫void luas_resize (lua_state *l, int newsize)
重新給雜湊表分配記憶體,空間為之前的兩倍,並且把舊雜湊表中的資料插入到新雜湊表中,然後釋放掉之前的記憶體。
LUA 原始碼閱讀筆記(一)
背景介紹 因為工作的需要,後台svr要能夠動態修改更新,使用c當然沒有問題,問題就在於修改原始碼後,需要重啟服務。所以就想到在c裡能夠嵌入一種指令碼,最好是和c無縫結合的。因此就想到使用到lua,lua的大名圈內人士應該早有耳聞,只不過一直沒有機會接觸。機緣巧合,有幸一見。俗話說得好,耳聞不如一見。...
lua 原始碼閱讀 1 1 2 1
lua 1.1 閱讀 1.hash.c 中 a 對建立的 hash array 用 listhead 鏈式結構來管理,新增lua hashcollector,用來做 hash 的 處理。ps 1.0 用的是個 512 的陣列,用乙個少乙個 b hash lua createarray int nha...
閱讀筆記 fsnotify原始碼閱讀
fsnotify的github位址是 fsnotify是乙個資料夾監控應用。可以使用建立乙個watcher來對某個資料夾進行監控 檔案目錄很簡單,實際就兩個程式檔案,fsnotify.go 和 各平台的fsnotify go 後乙個檔案是各個不同平台的實現 example test.go中給的是最簡...