diff options
Diffstat (limited to 'ltable.c')
-rw-r--r-- | ltable.c | 23 |
1 files changed, 17 insertions, 6 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltable.c,v 1.41 2000/05/08 19:32:53 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 1.42 2000/05/11 18:57:19 roberto Exp roberto $ |
3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -122,10 +122,12 @@ int luaH_pos (lua_State *L, const Hash *t, const TObject *key) { | |||
122 | } | 122 | } |
123 | 123 | ||
124 | 124 | ||
125 | static void setnodevector (lua_State *L, Hash *t, int size) { | 125 | static void setnodevector (lua_State *L, Hash *t, lint32 size) { |
126 | int i; | 126 | int i; |
127 | if (size > MAX_INT) | ||
128 | lua_error(L, "table overflow"); | ||
127 | t->node = luaM_newvector(L, size, Node); | 129 | t->node = luaM_newvector(L, size, Node); |
128 | for (i=0; i<size; i++) { | 130 | for (i=0; i<(int)size; i++) { |
129 | ttype(&t->node[i].key) = ttype(&t->node[i].val) = TAG_NIL; | 131 | ttype(&t->node[i].key) = ttype(&t->node[i].val) = TAG_NIL; |
130 | t->node[i].next = NULL; | 132 | t->node[i].next = NULL; |
131 | } | 133 | } |
@@ -153,7 +155,7 @@ void luaH_free (lua_State *L, Hash *t) { | |||
153 | } | 155 | } |
154 | 156 | ||
155 | 157 | ||
156 | static int newsize (const Hash *t) { | 158 | static int numuse (const Hash *t) { |
157 | Node *v = t->node; | 159 | Node *v = t->node; |
158 | int size = t->size; | 160 | int size = t->size; |
159 | int realuse = 0; | 161 | int realuse = 0; |
@@ -162,16 +164,24 @@ static int newsize (const Hash *t) { | |||
162 | if (ttype(&v[i].val) != TAG_NIL) | 164 | if (ttype(&v[i].val) != TAG_NIL) |
163 | realuse++; | 165 | realuse++; |
164 | } | 166 | } |
165 | return luaO_power2(realuse+realuse/4+1); | 167 | return realuse; |
166 | } | 168 | } |
167 | 169 | ||
168 | 170 | ||
169 | static void rehash (lua_State *L, Hash *t) { | 171 | static void rehash (lua_State *L, Hash *t) { |
170 | int oldsize = t->size; | 172 | int oldsize = t->size; |
171 | Node *nold = t->node; | 173 | Node *nold = t->node; |
174 | int newsize = numuse(t); | ||
172 | int i; | 175 | int i; |
176 | LUA_ASSERT(L, newsize<=oldsize, "wrong count"); | ||
177 | if (newsize >= oldsize-oldsize/4) /* using more than 3/4? */ | ||
178 | setnodevector(L, t, (lint32)oldsize*2); | ||
179 | else if (newsize <= oldsize/4 && /* less than 1/4? */ | ||
180 | oldsize > MINPOWER2) | ||
181 | setnodevector(L, t, oldsize/2); | ||
182 | else | ||
183 | setnodevector(L, t, oldsize); | ||
173 | L->nblocks -= gcsize(L, oldsize); | 184 | L->nblocks -= gcsize(L, oldsize); |
174 | setnodevector(L, t, newsize(t)); /* create new array of nodes */ | ||
175 | for (i=0; i<oldsize; i++) { | 185 | for (i=0; i<oldsize; i++) { |
176 | Node *old = nold+i; | 186 | Node *old = nold+i; |
177 | if (ttype(&old->val) != TAG_NIL) | 187 | if (ttype(&old->val) != TAG_NIL) |
@@ -249,3 +259,4 @@ void luaH_setint (lua_State *L, Hash *t, int key, const TObject *val) { | |||
249 | const TObject *luaH_getglobal (lua_State *L, const char *name) { | 259 | const TObject *luaH_getglobal (lua_State *L, const char *name) { |
250 | return luaH_getstr(L->gt, luaS_new(L, name)); | 260 | return luaH_getstr(L->gt, luaS_new(L, name)); |
251 | } | 261 | } |
262 | |||