summaryrefslogtreecommitdiff
path: root/ltable.c
diff options
context:
space:
mode:
Diffstat (limited to 'ltable.c')
-rw-r--r--ltable.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/ltable.c b/ltable.c
index 3af51b62..a7d4f36a 100644
--- a/ltable.c
+++ b/ltable.c
@@ -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
125static void setnodevector (lua_State *L, Hash *t, int size) { 125static 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
156static int newsize (const Hash *t) { 158static 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
169static void rehash (lua_State *L, Hash *t) { 171static 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) {
249const TObject *luaH_getglobal (lua_State *L, const char *name) { 259const 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