commit ac390020e91e14f00200ad3df97682b715d3e59b
parent 9b45439860879dd282e6d0896c4ee8102febc7fd
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Fri, 26 Jan 2001 12:16:13 -0200
optimizations based on all types but number and nil are pointers
Diffstat:
M | lobject.c | | | 13 | ++++--------- |
M | ltable.c | | | 114 | ++++++++++++++++++++++++++----------------------------------------------------- |
M | ltable.h | | | 11 | ++++++----- |
3 files changed, 47 insertions(+), 91 deletions(-)
diff --git a/lobject.c b/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 */
}
}
diff --git a/ltable.c b/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);
}
}
diff --git a/ltable.h b/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);