From c542aac0b935a65203244c130cdfa700113f0bc8 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 5 Jun 2000 17:07:53 -0300 Subject: [PATCH] collect dead indices in tables --- lgc.c | 4 +++- ltable.c | 24 +++++++++++++++++++++++- ltable.h | 3 ++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/lgc.c b/lgc.c index b8cbc54f..f1296cde 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 1.53 2000/05/30 19:00:31 roberto Exp roberto $ +** $Id: lgc.c,v 1.54 2000/06/05 14:56:18 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -64,6 +64,8 @@ static void tablemark (lua_State *L, Hash *h) { for (i=h->size-1; i>=0; i--) { Node *n = node(h,i); if (ttype(key(n)) != TAG_NIL) { + if (ttype(val(n)) == TAG_NIL) + luaH_remove(h, key(n)); /* dead element; try to remove it */ markobject(L, &n->key); markobject(L, &n->val); } diff --git a/ltable.c b/ltable.c index a7d4f36a..9929146d 100644 --- a/ltable.c +++ b/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 1.42 2000/05/11 18:57:19 roberto Exp roberto $ +** $Id: ltable.c,v 1.43 2000/05/24 13:54:49 roberto Exp roberto $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -121,6 +121,28 @@ int luaH_pos (lua_State *L, const Hash *t, const TObject *key) { (int)(((const char *)v - (const char *)(&t->node[0].val))/sizeof(Node)); } +/* +** try to remove a key without value from a table. To avoid problems with +** hash, change `key' for a number with the same hash. +*/ +void luaH_remove (Hash *t, TObject *key) { + /* do not remove numbers */ + if (ttype(key) != TAG_NUMBER) { + /* try to find a number `n' with the same hash as `key' */ + Node *mp = luaH_mainposition(t, key); + int n = mp - &t->node[0]; + /* make sure `n' is not in `t' */ + while (luaH_getnum(t, n) != &luaO_nilobject) { + if (t->size >= MAX_INT-n) + return; /* give up; (to avoid overflow) */ + n += t->size; + } + ttype(key) = TAG_NUMBER; + nvalue(key) = n; + LUA_ASSERT(L, luaH_mainposition(t, key) == mp, "cannot change hash"); + } +} + static void setnodevector (lua_State *L, Hash *t, lint32 size) { int i; diff --git a/ltable.h b/ltable.h index 3d1f674a..df36e8a6 100644 --- a/ltable.h +++ b/ltable.h @@ -1,5 +1,5 @@ /* -** $Id: ltable.h,v 1.19 2000/04/25 16:55:09 roberto Exp roberto $ +** $Id: ltable.h,v 1.20 2000/05/08 19:32:53 roberto Exp roberto $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -21,6 +21,7 @@ void luaH_free (lua_State *L, Hash *t); const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key); const TObject *luaH_getnum (const Hash *t, Number key); const TObject *luaH_getstr (const Hash *t, TString *key); +void luaH_remove (Hash *t, TObject *key); void luaH_set (lua_State *L, Hash *t, const TObject *key, const TObject *val); int luaH_pos (lua_State *L, const Hash *t, const TObject *r); void luaH_setint (lua_State *L, Hash *t, int key, const TObject *val);