commit 7959f3aebb5b12f474b65429dedf550b28223e08
parent bce6572579a7e6c7a96895d9280396b3b33b8f3f
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Fri, 26 Jan 2001 11:17:38 -0200
easier way to erase 'dead' keys
Diffstat:
M | lgc.c | | | 40 | ++++++++++++++++++++++++++-------------- |
M | ltable.c | | | 28 | ++-------------------------- |
M | ltable.h | | | 3 | +-- |
3 files changed, 29 insertions(+), 42 deletions(-)
diff --git a/lgc.c b/lgc.c
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.c,v 1.78 2001/01/22 18:01:38 roberto Exp roberto $
+** $Id: lgc.c,v 1.79 2001/01/25 16:45:36 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -121,6 +121,29 @@ static void marktagmethods (global_State *G, GCState *st) {
}
+static void traverseclosure (GCState *st, Closure *f) {
+ int i;
+ for (i=0; i<f->nupvalues; i++) /* mark its upvalues */
+ markobject(st, &f->upvalue[i]);
+}
+
+
+static void traversetable (GCState *st, Hash *h) {
+ int i;
+ for (i=0; i<h->size; i++) {
+ Node *n = node(h, i);
+ if (ttype(val(n)) == LUA_TNIL) {
+ if (ttype(key(n)) != LUA_TNIL)
+ sethvalue(key(n), NULL); /* dead key; remove it */
+ }
+ else {
+ markobject(st, &n->key);
+ markobject(st, &n->val);
+ }
+ }
+}
+
+
static void markall (lua_State *L) {
GCState st;
st.cmark = NULL;
@@ -131,25 +154,14 @@ static void markall (lua_State *L) {
marktable(&st, G(L)->type2tag);
for (;;) { /* mark tables and closures */
if (st.cmark) {
- int i;
Closure *f = st.cmark; /* get first closure from list */
st.cmark = f->mark; /* remove it from list */
- for (i=0; i<f->nupvalues; i++) /* mark its upvalues */
- markobject(&st, &f->upvalue[i]);
+ traverseclosure(&st, f);
}
else if (st.tmark) {
- int i;
Hash *h = st.tmark; /* get first table from list */
st.tmark = h->mark; /* remove it from list */
- for (i=0; i<h->size; i++) {
- Node *n = node(h, i);
- if (ttype(key(n)) != LUA_TNIL) {
- if (ttype(val(n)) == LUA_TNIL)
- luaH_remove(h, key(n)); /* dead element; try to remove it */
- markobject(&st, &n->key);
- markobject(&st, &n->val);
- }
- }
+ traversetable(&st, h);
}
else break; /* nothing else to mark */
}
diff --git a/ltable.c b/ltable.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.c,v 1.66 2001/01/24 15:45:33 roberto Exp roberto $
+** $Id: ltable.c,v 1.67 2001/01/25 16:45:36 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -126,30 +126,6 @@ Node *luaH_next (lua_State *L, const Hash *t, const TObject *key) {
}
-/*
-** 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) {
- if (ttype(key) == LUA_TNUMBER ||
- (ttype(key) == LUA_TSTRING && tsvalue(key)->len <= 30))
- return; /* do not remove numbers nor small strings */
- else {
- /* 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 (n >= MAX_INT - t->size)
- return; /* give up; (to avoid overflow) */
- n += t->size;
- }
- setnvalue(key, n);
- lua_assert(luaH_mainposition(t, key) == mp);
- }
-}
-
-
static void setnodevector (lua_State *L, Hash *t, luint32 size) {
int i;
if (size > MAX_INT)
@@ -227,7 +203,7 @@ static void rehash (lua_State *L, Hash *t) {
** position), new key goes to an empty position.
*/
static TObject *newkey (lua_State *L, Hash *t, Node *mp, const TObject *key) {
- if (ttype(&mp->key) != LUA_TNIL) { /* main position is not free? */
+ if (ttype(&mp->val) != LUA_TNIL) { /* main position is not free? */
Node *othern = luaH_mainposition(t, &mp->key); /* `mp' of colliding node */
Node *n = t->firstfree; /* get a free place */
if (othern != mp) { /* is colliding node out of its main position? */
diff --git a/ltable.h b/ltable.h
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.h,v 1.26 2000/12/04 18:33:40 roberto Exp roberto $
+** $Id: ltable.h,v 1.27 2001/01/10 18:56:11 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -19,7 +19,6 @@ void luaH_free (lua_State *L, Hash *t);
const TObject *luaH_get (const Hash *t, const TObject *key);
const TObject *luaH_getnum (const Hash *t, lua_Number key);
const TObject *luaH_getstr (const Hash *t, TString *key);
-void luaH_remove (Hash *t, TObject *key);
TObject *luaH_set (lua_State *L, Hash *t, const TObject *key);
Node * luaH_next (lua_State *L, const Hash *t, const TObject *r);
TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key);