This article focuses on the string Cache Management in Lua (the file lstring. c involved ).
Among the nine Data Types of Lua, the string is a type that can be recycled by GC. In Lua, the Operation string is actually referenced in the Operation string. When the character string is not used, GC will be recycled by some algorithm.
-- Lua9 data types:
# Define lua_tnil0 <br/> # define lua_tlightuserdata2 <br/> # define lua_tnumber3 <br/> # define lua_tstring4 <br/> # define lua_ttable5 <br/> /># define lua_tfunction6 <br/> # define lua_tuserdata7 <br/> # define lua_tthread8
String allocation
-- Source code:
Static tstring * newlstr (lua_state * l, const char * STR, size_t L, <br/> unsigned int h) {<br/> tstring * ts; <br/> stringtable * TB; <br/> If (L + 1> (max_sizet-sizeof (tstring)/sizeof (char )) <br/> luam_toobig (l); <br/> TS = cast (tstring *, luam_malloc (L, (L + 1) * sizeof (char) + sizeof (tstring); <br/> TS-> TSV. len = L; <br/> TS-> TSV. hash = H; <br/> TS-> TSV. marked = luac_white (G (l); <br/> TS-> TSV. tt = lua_tstring; <br/> TS-> TSV. reserved = 0; <br/> memcpy (TS + 1, STR, L * sizeof (char); <br/> (char *) (TS + 1 )) [l] = '/0';/* ending 0 */<br/> TB = & G (l)-> strt; <br/> H = lmod (H, TB-> size); <br/> TS-> TSV. next = Tb-> hash [H];/* chain new entry */<br/> TB-> hash [H] = obj2gco (TS ); <br/> TB-> nuse ++; <br/> If (Tb-> nuse> cast (lu_int32, Tb-> size) & TB-> size <= max_int/2) <br/> luas_resize (L, Tb-> size * 2 ); /* too crowded */<br/> return ts; <br/>}< br/>
TS = cast (tstring *, luam_malloc (L, (L + 1) * sizeof (char) + sizeof (tstring )));
-- This line of code applies for storing the string memory. luam_malloc is a macro definition for applying for memory. It calls the luam_realloc _ function mentioned in the previous article to allocate memory. In Lua, the string is structured.
/* <Br/> ** string headers for string table <br/> */<br/> typedef Union tstring {<br/> l_umaxalign dummy; /* ensures maximum alignment for strings */<br/> struct {<br/> commonheader; <br/> lu_byte reserved; <br/> unsigned int hash; <br/> size_t Len; <br/>} TSV; <br/>} tstring; </P> <p> # define commonheadergcobject * Next; lu_byte tt; lu_byte marked
Therefore, the applied memory size is (L + 1) * sizeof (char) + sizeof (tstring). Memory Distribution: tstring + STR + '/0 ', assign hash code, Len, marted, reserved to tstring and copy the string.
TB = & G (l)-> strt;
H = lmod (H, Tb-> size );
Ts-> TSV. Next = Tb-> hash [H];/* chain new entry */
TB-> hash [H] = obj2gco (TS );
TB-> nuse ++;
-- Next, mount the allocated string to the global string management object strt.
If (Tb-> nuse> cast (lu_int32, Tb-> size) & TB-> size <= max_int/2)
Luas_resize (L, Tb-> size * 2);/* too crowded */
-- Expand the string size
String cache
-- Source code:
Tstring * luas_newlstr (lua_state * l, const char * STR, size_t L) {<br/> gcobject * O; <br/> unsigned int H = cast (unsigned int, l);/* seed */<br/> size_t step = (L> 5) + 1;/* If string is too long, don't hash all its chars */<br/> size_t L1; <br/> for (L1 = L; L1> = step; L1-= step) /* compute hash */<br/> H = H ^ (h <5) + (h> 2) + Cast (unsigned char, STR [l1-1]); <br/> for (O = g (l)-> strt. hash [lmod (H, G (L)-> strt. Size)]; <br/> O! = NULL; <br/> O = o-> gch. next) {<br/> tstring * Ts = rawgco2ts (o); <br/> If (ts-> TSV. len = L & (memcmp (STR, getstr (TS), L) = 0 )) {<br/>/* string may be dead */<br/> If (isdead (G (L), O) changewhite (O ); <br/> return ts; <br/>}< br/> return newlstr (L, STR, L, H ); /* not found */<br/>}< br/>
Unsigned int H = cast (unsigned int, L);/* seed */
Size_t step = (L> 5) + 1;/* If string is too long, don't hash all its chars */
Size_t L1;
For (L1 = L; L1> = step; L1-= step)/* compute hash */
H = H ^ (h <5) + (h> 2) + Cast (unsigned char, STR [l1-1]);
--- Calculate the string hash code based on the string length (L) and string content (STR). The string hash code is used as the key of the string and subsequently used as the String cache key. This algorithm can ensure one-to-one matching of the key-value.
For (O = g (l)-> strt. Hash [lmod (H, g (l)-> strt. Size)];
O! = NULL;
O = o-> gch. Next ){
Tstring * Ts = rawgco2ts (O );
If (ts-> TSV. Len = L & (memcmp (STR, getstr (TS), L) = 0 )){
/* String may be dead */
If (isdead (G (L), O) changewhite (O );
Return ts;
}
}
-- Search for this string in the string global management object. If yes, use this string to return the result. otherwise:
Return newlstr (L, STR, L, H );
Apply for memory placement strings.