mirror of https://github.com/rusefi/lua.git
tables can become full of "emptys" slots, and keep growing without limits.
This commit is contained in:
parent
07ff251a17
commit
6cdf0d8768
6
bugs
6
bugs
|
@ -21,7 +21,7 @@ Mon Jan 19 18:17:18 EDT 1998
|
|||
|
||||
** lstrlib.c
|
||||
Tue Jan 27 15:27:49 EDT 1998
|
||||
>> formats like "%020d" were considered too big (3 algarithms); moreover,
|
||||
>> formats like "%020d" were considered too big (3 digits); moreover,
|
||||
>> some sistems limit printf to at most 500 chars, so we can limit sizes
|
||||
>> to 2 digits (99).
|
||||
|
||||
|
@ -29,3 +29,7 @@ Tue Jan 27 15:27:49 EDT 1998
|
|||
Tue Jan 27 17:12:36 EDT 1998
|
||||
>> "lua_getstring" may create a new string, so should check GC
|
||||
|
||||
** lstring.c / ltable.c
|
||||
Wed Jan 28 14:48:12 EDT 1998
|
||||
>> tables can become full of "emptys" slots, and keep growing without limits.
|
||||
|
||||
|
|
33
lstring.c
33
lstring.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lstring.c,v 1.9 1997/12/30 19:15:52 roberto Exp roberto $
|
||||
** $Id: lstring.c,v 1.10 1998/01/13 18:06:27 roberto Exp roberto $
|
||||
** String table (keeps all strings handled by Lua)
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -50,26 +50,43 @@ static unsigned long hash (char *s, int tag)
|
|||
}
|
||||
|
||||
|
||||
static int newsize (stringtable *tb)
|
||||
{
|
||||
int size = tb->size;
|
||||
int realuse = 0;
|
||||
int i;
|
||||
/* count how many entries are really in use */
|
||||
for (i=0; i<size; i++)
|
||||
if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY)
|
||||
realuse++;
|
||||
if (2*(realuse+1) <= size) /* +1 is the new element */
|
||||
return size; /* don't need to grow, just rehash to clear EMPTYs */
|
||||
else
|
||||
return luaO_redimension(size);
|
||||
}
|
||||
|
||||
|
||||
static void grow (stringtable *tb)
|
||||
{
|
||||
int newsize = luaO_redimension(tb->size);
|
||||
TaggedString **newhash = luaM_newvector(newsize, TaggedString *);
|
||||
|
||||
int ns = newsize(tb);
|
||||
TaggedString **newhash = luaM_newvector(ns, TaggedString *);
|
||||
int i;
|
||||
for (i=0; i<newsize; i++)
|
||||
for (i=0; i<ns; i++)
|
||||
newhash[i] = NULL;
|
||||
/* rehash */
|
||||
tb->nuse = 0;
|
||||
for (i=0; i<tb->size; i++) {
|
||||
if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) {
|
||||
int h = tb->hash[i]->hash%newsize;
|
||||
int h = tb->hash[i]->hash%ns;
|
||||
while (newhash[h])
|
||||
h = (h+1)%newsize;
|
||||
h = (h+1)%ns;
|
||||
newhash[h] = tb->hash[i];
|
||||
tb->nuse++;
|
||||
}
|
||||
}
|
||||
luaM_free(tb->hash);
|
||||
tb->size = newsize;
|
||||
tb->size = ns;
|
||||
tb->hash = newhash;
|
||||
}
|
||||
|
||||
|
@ -86,7 +103,7 @@ static TaggedString *newone (char *buff, int tag, unsigned long h)
|
|||
L->nblocks += gcsizestring(l);
|
||||
}
|
||||
else {
|
||||
ts = (TaggedString *)luaM_malloc(sizeof(TaggedString));
|
||||
ts = luaM_new(TaggedString);
|
||||
ts->u.d.v = buff;
|
||||
ts->u.d.tag = tag == LUA_ANYTAG ? 0 : tag;
|
||||
ts->constindex = -1; /* tag -> this is a userdata */
|
||||
|
|
34
ltable.c
34
ltable.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: ltable.c,v 1.10 1998/01/09 14:44:55 roberto Exp roberto $
|
||||
** $Id: ltable.c,v 1.11 1998/01/13 18:06:27 roberto Exp roberto $
|
||||
** Lua tables (hash)
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -121,36 +121,36 @@ Hash *luaH_new (int nhash)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
** Rehash:
|
||||
** Check if table has deleted slots. It it has, it does not need to
|
||||
** grow, since rehash will reuse them.
|
||||
*/
|
||||
static int emptyslots (Hash *t)
|
||||
static int newsize (Hash *t)
|
||||
{
|
||||
Node *v = t->node;
|
||||
int size = nhash(t);
|
||||
int realuse = 0;
|
||||
int i;
|
||||
for (i=nhash(t)-1; i>=0; i--) {
|
||||
Node *n = node(t, i);
|
||||
if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) == LUA_T_NIL)
|
||||
return 1;
|
||||
for (i=0; i<size; i++) {
|
||||
if (ttype(ref(v+i)) != LUA_T_NIL && ttype(val(v+i)) != LUA_T_NIL)
|
||||
realuse++;
|
||||
}
|
||||
return 0;
|
||||
if (2*(realuse+1) <= size) /* +1 is the new element */
|
||||
return size; /* don't need to grow, just rehash */
|
||||
else
|
||||
return luaO_redimension(size);
|
||||
}
|
||||
|
||||
static void rehash (Hash *t)
|
||||
{
|
||||
int nold = nhash(t);
|
||||
int nold = nhash(t);
|
||||
Node *vold = nodevector(t);
|
||||
int nnew = newsize(t);
|
||||
int i;
|
||||
if (!emptyslots(t))
|
||||
nhash(t) = luaO_redimension(nhash(t));
|
||||
nodevector(t) = hashnodecreate(nhash(t));
|
||||
nodevector(t) = hashnodecreate(nnew);
|
||||
nhash(t) = nnew;
|
||||
for (i=0; i<nold; i++) {
|
||||
Node *n = vold+i;
|
||||
if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) != LUA_T_NIL)
|
||||
*node(t, present(t, ref(n))) = *n; /* copy old node to luaM_new hash */
|
||||
}
|
||||
L->nblocks += gcsize(t->nhash)-gcsize(nold);
|
||||
L->nblocks += gcsize(nnew)-gcsize(nold);
|
||||
luaM_free(vold);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue