Browse Source

easier way to erase 'dead' keys

Roberto Ierusalimschy 24 years ago
parent
commit
7959f3aebb
3 changed files with 29 additions and 42 deletions
  1. 26 14
      lgc.c
  2. 2 26
      ltable.c
  3. 1 2
      ltable.h

+ 26 - 14
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 */
   }

+ 2 - 26
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? */

+ 1 - 2
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);