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 --- ltable.c | 114 +++++++++++++++++++++------------------------------------------ 1 file changed, 37 insertions(+), 77 deletions(-) (limited to 'ltable.c') 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); } } -- cgit v1.2.3-55-g6feb