optimizations based on all types but number and nil are pointers

This commit is contained in:
Roberto Ierusalimschy 2001-01-26 12:16:35 -02:00
parent 9b45439860
commit ac390020e9
3 changed files with 47 additions and 91 deletions

View File

@ -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 */
}
}

114
ltable.c
View File

@ -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 */
}
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);
default: /* all other types are hashed as (void *) */
return hashpointer(t, hvalue(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);
}
}

View File

@ -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);