diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2013-08-22 12:21:48 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2013-08-22 12:21:48 -0300 |
commit | 33c49f7fa03cf7e3bf7bb3aa697dc567d910c661 (patch) | |
tree | 15af62f7b744bcb0e5abfc6fd935af592cbb5da2 /lstring.c | |
parent | 0df6635711230ab306710056f621b6da59fac5ea (diff) | |
download | lua-33c49f7fa03cf7e3bf7bb3aa697dc567d910c661.tar.gz lua-33c49f7fa03cf7e3bf7bb3aa697dc567d910c661.tar.bz2 lua-33c49f7fa03cf7e3bf7bb3aa697dc567d910c661.zip |
some details over new implementation of string table
Diffstat (limited to 'lstring.c')
-rw-r--r-- | lstring.c | 34 |
1 files changed, 18 insertions, 16 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.c,v 2.28 2013/08/05 16:58:28 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 2.29 2013/08/21 19:21:16 roberto Exp roberto $ |
3 | ** String table (keeps all strings handled by Lua) | 3 | ** String table (keeps all strings handled by Lua) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -13,6 +13,7 @@ | |||
13 | #include "lua.h" | 13 | #include "lua.h" |
14 | 14 | ||
15 | #include "ldebug.h" | 15 | #include "ldebug.h" |
16 | #include "ldo.h" | ||
16 | #include "lmem.h" | 17 | #include "lmem.h" |
17 | #include "lobject.h" | 18 | #include "lobject.h" |
18 | #include "lstate.h" | 19 | #include "lstate.h" |
@@ -24,7 +25,7 @@ | |||
24 | 25 | ||
25 | 26 | ||
26 | /* second hash (for double hash) */ | 27 | /* second hash (for double hash) */ |
27 | #define h2(h1,hash,size) lmod(h1 + ((hash % 31) | 1), size) | 28 | #define h2(h1,hash,size) lmod(h1 + ((hash % 61) | 1), size) |
28 | 29 | ||
29 | 30 | ||
30 | /* | 31 | /* |
@@ -116,19 +117,18 @@ static TString *createstrobj (lua_State *L, const char *str, size_t l, | |||
116 | 117 | ||
117 | 118 | ||
118 | static void rehash (lua_State *L, stringtable *tb) { | 119 | static void rehash (lua_State *L, stringtable *tb) { |
119 | int newsize; | 120 | int size = tb->size; |
120 | if (tb->nuse < tb->size / 2) { /* using less than half the size? */ | 121 | if (tb->nuse < size / 2) { /* using less than half the size? */ |
121 | if (tb->nuse < tb->size / 4) /* using less than half of that? */ | 122 | if (tb->nuse < size / 4) /* using less than half of that? */ |
122 | newsize = tb->size / 2; /* shrink table */ | 123 | size /= 2; /* shrink table */ |
123 | else | 124 | /* else keep size (but reorganize table) */ |
124 | newsize = tb->size; /* keep size (but reorganize table) */ | ||
125 | } | 125 | } |
126 | else { /* table must grow */ | 126 | else { /* table must grow */ |
127 | if (tb->size >= MAX_INT/2) | 127 | if (size >= MAX_INT/2) /* avoid arith. overflow */ |
128 | luaG_runerror(L, "string-table overflow: too many strings"); | 128 | luaD_throw(L, LUA_ERRMEM); /* regular errors need new strings... */ |
129 | newsize = tb->size * 2; | 129 | size *= 2; |
130 | } | 130 | } |
131 | luaS_resize(L, newsize); | 131 | luaS_resize(L, size); |
132 | } | 132 | } |
133 | 133 | ||
134 | 134 | ||
@@ -154,12 +154,10 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) { | |||
154 | stringtable *tb = &G(L)->strt; | 154 | stringtable *tb = &G(L)->strt; |
155 | int vacant = -1; | 155 | int vacant = -1; |
156 | int h1; | 156 | int h1; |
157 | if (tb->empty <= 0) | ||
158 | rehash(L, tb); | ||
159 | h1 = lmod(hash, tb->size); /* previous call can changed 'size' */ | 157 | h1 = lmod(hash, tb->size); /* previous call can changed 'size' */ |
160 | while ((ts = tb->hash[h1]) != NULL) { /* search the string in hash table */ | 158 | while ((ts = tb->hash[h1]) != NULL) { /* search the string in hash table */ |
161 | if (ts == VACANTK) { | 159 | if (ts == VACANTK) { |
162 | if (vacant < 0) vacant = h1; /* keep track of a vacant place */ | 160 | if (vacant < 0) vacant = h1; /* keep track of first vacant place */ |
163 | } | 161 | } |
164 | else if (l == ts->tsv.len && | 162 | else if (l == ts->tsv.len && |
165 | (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { | 163 | (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { |
@@ -174,12 +172,16 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) { | |||
174 | } | 172 | } |
175 | h1 = h2(h1, hash, tb->size); | 173 | h1 = h2(h1, hash, tb->size); |
176 | } | 174 | } |
175 | if (tb->empty <= 0) { /* no more empty spaces? */ | ||
176 | rehash(L, tb); | ||
177 | return internshrstr(L, str, l); /* recompute insertion with new size */ | ||
178 | } | ||
177 | ts = createstrobj(L, str, l, LUA_TSHRSTR, hash); | 179 | ts = createstrobj(L, str, l, LUA_TSHRSTR, hash); |
178 | tb->nuse++; | 180 | tb->nuse++; |
179 | if (vacant < 0) /* found no vacant place? */ | 181 | if (vacant < 0) /* found no vacant place? */ |
180 | tb->empty--; /* will have to use the empty place */ | 182 | tb->empty--; /* will have to use the empty place */ |
181 | else | 183 | else |
182 | h1 = vacant; /* insert string into vacant place */ | 184 | h1 = vacant; /* use vacant place */ |
183 | tb->hash[h1] = ts; | 185 | tb->hash[h1] = ts; |
184 | return ts; | 186 | return ts; |
185 | } | 187 | } |