From ac390020e91e14f00200ad3df97682b715d3e59b Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 26 Jan 2001 12:16:35 -0200 Subject: optimizations based on all types but number and nil are pointers --- lobject.c | 13 +++---- ltable.c | 114 ++++++++++++++++++++------------------------------------------ ltable.h | 11 +++--- 3 files changed, 47 insertions(+), 91 deletions(-) diff --git a/lobject.c b/lobject.c index a10dfeab..fec0c5e7 100644 --- 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 index a13e8c24..6453bf85 100644 --- 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 index 565a8606..482f0ee6 100644 --- 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); -- cgit v1.2.3-55-g6feb