瀏覽代碼

optimizations based on all types but number and nil are pointers

Roberto Ierusalimschy 24 年之前
父節點
當前提交
ac390020e9
共有 3 個文件被更改,包括 47 次插入91 次删除
  1. 4 9
      lobject.c
  2. 37 77
      ltable.c
  3. 6 5
      ltable.h

+ 4 - 9
lobject.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.c,v 1.60 2001/01/24 15:45:33 roberto Exp roberto $
+** $Id: lobject.c,v 1.61 2001/01/25 16:45:36 roberto Exp roberto $
 ** Some generic functions over Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -37,15 +37,10 @@ int luaO_equalObj (const TObject *t1, const TObject *t2) {
   switch (ttype(t1)) {
     case LUA_TNUMBER:
       return nvalue(t1) == nvalue(t2);
-    case LUA_TSTRING: case LUA_TUSERDATA:
+    case LUA_TNIL:
+      return 1;
+    default:  /* all other types are equal if pointers are equal */
       return tsvalue(t1) == tsvalue(t2);
-    case LUA_TTABLE: 
-      return hvalue(t1) == hvalue(t2);
-    case LUA_TFUNCTION:
-      return clvalue(t1) == clvalue(t2);
-    default:
-      lua_assert(ttype(t1) == LUA_TNIL);
-      return 1; /* LUA_TNIL */
   }
 }
 

+ 37 - 77
ltable.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.c,v 1.67 2001/01/25 16:45:36 roberto Exp roberto $
+** $Id: ltable.c,v 1.68 2001/01/26 13:18:00 roberto Exp roberto $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -31,8 +31,9 @@
 #define TagDefault LUA_TTABLE
 
 
-#define hashnum(t,n)	(&t->node[(luint32)(lint32)(n)&(t->size-1)])
-#define hashstr(t,str)	(&t->node[(str)->u.s.hash&(t->size-1)])
+#define hashnum(t,n)		(&t->node[(luint32)(lint32)(n)&(t->size-1)])
+#define hashstr(t,str)		(&t->node[(str)->u.s.hash&(t->size-1)])
+#define hashpointer(t,p)	(&t->node[IntPoint(p)&(t->size-1)])
 
 
 /*
@@ -40,73 +41,18 @@
 ** of its hash value)
 */
 Node *luaH_mainposition (const Hash *t, const TObject *key) {
-  luint32 h;
   switch (ttype(key)) {
     case LUA_TNUMBER:
       return hashnum(t, nvalue(key));
     case LUA_TSTRING:
       return hashstr(t, tsvalue(key));
-    case LUA_TUSERDATA:
-      h = IntPoint(tsvalue(key));
-      break;
-    case LUA_TTABLE:
-      h = IntPoint(hvalue(key));
-      break;
-    case LUA_TFUNCTION:
-      h = IntPoint(clvalue(key));
-      break;
-    default:
-      return NULL;  /* invalid key */
+    default:  /* all other types are hashed as (void *) */
+      return hashpointer(t, hvalue(key));
   }
-  return &t->node[h&(t->size-1)];
 }
 
 
-static const TObject *luaH_getany (const Hash *t, const TObject *key) {
-  Node *n = luaH_mainposition(t, key);
-  while (n) {
-    if (luaO_equalObj(key, &n->key))
-      return &n->val;
-    n = n->next;
-  }
-  return &luaO_nilobject;  /* key not found */
-}
-
-
-/* specialized version for numbers */
-const TObject *luaH_getnum (const Hash *t, lua_Number key) {
-  Node *n = hashnum(t, key);
-  do {
-    if (nvalue(&n->key) == key && ttype(&n->key) == LUA_TNUMBER)
-      return &n->val;
-    n = n->next;
-  } while (n);
-  return &luaO_nilobject;  /* key not found */
-}
-
-
-/* specialized version for strings */
-const TObject *luaH_getstr (const Hash *t, TString *key) {
-  Node *n = hashstr(t, key);
-  do {
-    if (tsvalue(&n->key) == key && ttype(&n->key) == LUA_TSTRING)
-      return &n->val;
-    n = n->next;
-  } while (n);
-  return &luaO_nilobject;  /* key not found */
-}
-
-
-const TObject *luaH_get (const Hash *t, const TObject *key) {
-  switch (ttype(key)) {
-    case LUA_TNUMBER: return luaH_getnum(t, nvalue(key));
-    case LUA_TSTRING: return luaH_getstr(t, tsvalue(key));
-    default:         return luaH_getany(t, key);
-  }
-}
-
-
-Node *luaH_next (lua_State *L, const Hash *t, const TObject *key) {
+Node *luaH_next (lua_State *L, Hash *t, const TObject *key) {
   int i;
   if (ttype(key) == LUA_TNIL)
     i = 0;  /* first iteration */
@@ -197,8 +143,8 @@ static void rehash (lua_State *L, Hash *t) {
 
 /*
 ** inserts a new key into a hash table; first, check whether key's main 
-** position is free; if not, check whether colliding node is in its main 
-** position or not; if it is not, move colliding node to an empty place and 
+** position is free. If not, check whether colliding node is in its main 
+** position or not: if it is not, move colliding node to an empty place and 
 ** put new key in its main position; otherwise (colliding node is in its main 
 ** position), new key goes to an empty position. 
 */
@@ -234,20 +180,9 @@ static TObject *newkey (lua_State *L, Hash *t, Node *mp, const TObject *key) {
 }
 
 
-static TObject *luaH_setany (lua_State *L, Hash *t, const TObject *key) {
-  Node *mp = luaH_mainposition(t, key);
-  Node *n = mp;
-  if (!mp)
-    luaD_error(L, "table index is nil");
-  do {  /* check whether `key' is somewhere in the chain */
-    if (luaO_equalObj(key, &n->key))
-      return &n->val;  /* that's all */
-    else n = n->next;
-  } while (n);
-  return newkey(L, t, mp, key);  /* `key' not found; must insert it */
-}
-
-
+/*
+** search function for numbers
+*/
 TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key) {
   TObject kobj;
   Node *mp = hashnum(t, key);
@@ -257,12 +192,16 @@ TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key) {
       return &n->val;  /* that's all */
     else n = n->next;
   } while (n);
+  if (L == NULL) return (TObject *)&luaO_nilobject;  /* get option */
   /* `key' not found; must insert it */
   setnvalue(&kobj, key);
   return newkey(L, t, mp, &kobj);
 }
 
 
+/*
+** search function for strings
+*/
 TObject *luaH_setstr (lua_State *L, Hash *t, TString *key) {
   TObject kobj;
   Node *mp = hashstr(t, key);
@@ -272,16 +211,37 @@ TObject *luaH_setstr (lua_State *L, Hash *t, TString *key) {
       return &n->val;  /* that's all */
     else n = n->next;
   } while (n);
+  if (L == NULL) return (TObject *)&luaO_nilobject;  /* get option */
   /* `key' not found; must insert it */
   setsvalue(&kobj, key);
   return newkey(L, t, mp, &kobj);
 }
 
 
+/*
+** search function for 'pointer' types
+*/
+static TObject *luaH_setany (lua_State *L, Hash *t, const TObject *key) {
+  Node *mp = hashpointer(t, hvalue(key));
+  Node *n = mp;
+  do {  /* check whether `key' is somewhere in the chain */
+    /* compare as `hvalue', but may be other pointers (it is the same) */
+    if (hvalue(&n->key) == hvalue(key) && ttype(&n->key) == ttype(key))
+      return &n->val;  /* that's all */
+    else n = n->next;
+  } while (n);
+  if (L == NULL) return (TObject *)&luaO_nilobject;  /* get option */
+  return newkey(L, t, mp, key);  /* `key' not found; must insert it */
+}
+
+
 TObject *luaH_set (lua_State *L, Hash *t, const TObject *key) {
   switch (ttype(key)) {
     case LUA_TNUMBER: return luaH_setnum(L, t, nvalue(key));
     case LUA_TSTRING: return luaH_setstr(L, t, tsvalue(key));
+    case LUA_TNIL:
+      if (L) luaD_error(L, "table index is nil");
+      return (TObject *)&luaO_nilobject;  /* get option */
     default:         return luaH_setany(L, t, key);
   }
 }

+ 6 - 5
ltable.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.h,v 1.27 2001/01/10 18:56:11 roberto Exp roberto $
+** $Id: ltable.h,v 1.28 2001/01/26 13:18:00 roberto Exp roberto $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -14,13 +14,14 @@
 #define key(n)		(&(n)->key)
 #define val(n)		(&(n)->val)
 
+#define luaH_get(t,k)	luaH_set(NULL,t,k)
+#define luaH_getnum(t,k)	luaH_setnum(NULL,t,k)
+#define luaH_getstr(t,k)	luaH_setstr(NULL,t,k)
+
 Hash *luaH_new (lua_State *L, int nhash);
 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);
 TObject *luaH_set (lua_State *L, Hash *t, const TObject *key);
-Node * luaH_next (lua_State *L, const Hash *t, const TObject *r);
+Node * luaH_next (lua_State *L, Hash *t, const TObject *r);
 TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key);
 TObject *luaH_setstr (lua_State *L, Hash *t, TString *key);