diff options
-rw-r--r-- | lstate.h | 8 | ||||
-rw-r--r-- | lstring.c | 34 | ||||
-rw-r--r-- | ltests.c | 4 |
3 files changed, 24 insertions, 22 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.h,v 2.86 2013/08/21 19:21:16 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 2.87 2013/08/21 20:09:51 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -59,9 +59,9 @@ struct lua_longjmp; /* defined in ldo.c */ | |||
59 | 59 | ||
60 | typedef struct stringtable { | 60 | typedef struct stringtable { |
61 | TString **hash; | 61 | TString **hash; |
62 | unsigned int nuse; /* number of elements */ | 62 | int nuse; /* number of elements */ |
63 | unsigned int empty; /* number of available empty slots */ | 63 | int empty; /* number of available empty slots */ |
64 | unsigned int size; | 64 | int size; |
65 | } stringtable; | 65 | } stringtable; |
66 | 66 | ||
67 | 67 | ||
@@ -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 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltests.c,v 2.146 2013/08/20 17:46:34 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 2.147 2013/08/21 19:21:16 roberto Exp roberto $ |
3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -747,7 +747,7 @@ static int string_query (lua_State *L) { | |||
747 | lua_pushinteger(L ,tb->size); | 747 | lua_pushinteger(L ,tb->size); |
748 | return 2; | 748 | return 2; |
749 | } | 749 | } |
750 | else if ((unsigned int)s < tb->size) { | 750 | else if (s < tb->size) { |
751 | TString *ts = tb->hash[s]; | 751 | TString *ts = tb->hash[s]; |
752 | setsvalue2s(L, L->top, ts); | 752 | setsvalue2s(L, L->top, ts); |
753 | api_incr_top(L); | 753 | api_incr_top(L); |