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 | |
| parent | 0df6635711230ab306710056f621b6da59fac5ea (diff) | |
| download | lua-33c49f7fa03cf7e3bf7bb3aa697dc567d910c661.tar.gz lua-33c49f7fa03cf7e3bf7bb3aa697dc567d910c661.tar.bz2 lua-33c49f7fa03cf7e3bf7bb3aa697dc567d910c661.zip | |
some details over new implementation of string table
| -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); |
