Lua原始碼閱讀筆記 string字串

2021-09-12 09:15:50 字數 2065 閱讀 5025

// 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中給的是最簡...