mirror of https://github.com/rusefi/lua.git
better performance for table operations (mainly for integer indices)
This commit is contained in:
parent
dc4e0ecdaf
commit
654b16e83a
125
ltable.c
125
ltable.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: ltable.c,v 1.81 2001/06/15 20:36:57 roberto Exp roberto $
|
||||
** $Id: ltable.c,v 1.82 2001/06/26 13:20:45 roberto Exp roberto $
|
||||
** Lua tables (hash)
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -41,14 +41,14 @@
|
|||
** returns the `main' position of an element in a table (that is, the index
|
||||
** of its hash value)
|
||||
*/
|
||||
Node *luaH_mainposition (const Hash *t, const Node *n) {
|
||||
switch (ttype(key(n))) {
|
||||
Node *luaH_mainposition (const Hash *t, const TObject *key) {
|
||||
switch (ttype(key)) {
|
||||
case LUA_TNUMBER:
|
||||
return hashnum(t, nvalue(key(n)));
|
||||
return hashnum(t, nvalue(key));
|
||||
case LUA_TSTRING:
|
||||
return hashstr(t, tsvalue(key(n)));
|
||||
return hashstr(t, tsvalue(key));
|
||||
default: /* all other types are hashed as (void *) */
|
||||
return hashpointer(t, tsvalue(key(n)));
|
||||
return hashpointer(t, tsvalue(key));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,8 +61,8 @@ Node *luaH_next (lua_State *L, Hash *t, const TObject *key) {
|
|||
const TObject *v = luaH_get(t, key);
|
||||
if (v == &luaO_nilobject)
|
||||
luaD_error(L, l_s("invalid key for `next'"));
|
||||
i = (int)(((const l_char *)v -
|
||||
(const l_char *)(val(node(t, 0)))) / sizeof(Node)) + 1;
|
||||
i = (int)(((const lu_byte *)v -
|
||||
(const lu_byte *)(val(node(t, 0)))) / sizeof(Node)) + 1;
|
||||
}
|
||||
for (; i<t->size; i++) {
|
||||
Node *n = node(t, i);
|
||||
|
@ -74,7 +74,7 @@ Node *luaH_next (lua_State *L, Hash *t, const TObject *key) {
|
|||
|
||||
|
||||
int luaH_nexti (Hash *t, int i) {
|
||||
for (i++; i<t->size; i++) {
|
||||
while ((++i)<t->size) {
|
||||
if (ttype(val(node(t, i))) != LUA_TNIL) /* a non-nil value? */
|
||||
return i;
|
||||
}
|
||||
|
@ -177,9 +177,10 @@ static void rehash (lua_State *L, Hash *t) {
|
|||
** put new key in its main position; otherwise (colliding node is in its main
|
||||
** position), new key goes to an empty position.
|
||||
*/
|
||||
static TObject *newkey (lua_State *L, Hash *t, Node *mp, const TObject *key) {
|
||||
static TObject *newkey (lua_State *L, Hash *t, const TObject *key) {
|
||||
Node *mp = luaH_mainposition(t, key);
|
||||
if (ttype(val(mp)) != LUA_TNIL) { /* main position is not free? */
|
||||
Node *othern = luaH_mainposition(t, mp); /* `mp' of colliding node */
|
||||
Node *othern = luaH_mainposition(t, key(mp)); /* `mp' of colliding node */
|
||||
Node *n = t->firstfree; /* get a free place */
|
||||
if (othern != mp) { /* is colliding node out of its main position? */
|
||||
/* yes; move colliding node into free position */
|
||||
|
@ -210,68 +211,92 @@ static TObject *newkey (lua_State *L, Hash *t, Node *mp, const TObject *key) {
|
|||
|
||||
|
||||
/*
|
||||
** search function for numbers
|
||||
** generic search function
|
||||
*/
|
||||
TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key) {
|
||||
TObject kobj;
|
||||
Node *mp = hashnum(t, key);
|
||||
Node *n = mp;
|
||||
static const TObject *luaH_getany (Hash *t, const TObject *key) {
|
||||
if (ttype(key) == LUA_TNIL) return &luaO_nilobject;
|
||||
else {
|
||||
Node *n = luaH_mainposition(t, key);
|
||||
do { /* check whether `key' is somewhere in the chain */
|
||||
if (luaO_equalObj(key(n), key)) return val(n); /* that's it */
|
||||
else n = n->next;
|
||||
} while (n);
|
||||
return &luaO_nilobject;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** search function for integers
|
||||
*/
|
||||
const TObject *luaH_getnum (Hash *t, int key) {
|
||||
Node *n = hashnum(t, key);
|
||||
do { /* check whether `key' is somewhere in the chain */
|
||||
if (ttype(key(n)) == LUA_TNUMBER && nvalue(key(n)) == key)
|
||||
return val(n); /* that's all */
|
||||
if (ttype(key(n)) == LUA_TNUMBER && nvalue(key(n)) == (lua_Number)key)
|
||||
return val(n); /* that's it */
|
||||
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);
|
||||
return &luaO_nilobject;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** search function for strings
|
||||
*/
|
||||
TObject *luaH_setstr (lua_State *L, Hash *t, TString *key) {
|
||||
TObject kobj;
|
||||
Node *mp = hashstr(t, key);
|
||||
Node *n = mp;
|
||||
const TObject *luaH_getstr (Hash *t, TString *key) {
|
||||
Node *n = hashstr(t, key);
|
||||
do { /* check whether `key' is somewhere in the chain */
|
||||
if (ttype(key(n)) == LUA_TSTRING && tsvalue(key(n)) == key)
|
||||
return val(n); /* that's all */
|
||||
return val(n); /* that's it */
|
||||
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);
|
||||
return &luaO_nilobject;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** search function for 'pointer' types
|
||||
** main search function
|
||||
*/
|
||||
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 `tsvalue', but may be other pointers (it is the same) */
|
||||
if (ttype(key(n)) == ttype(key) && tsvalue(key(n)) == tsvalue(key))
|
||||
return val(n); /* 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 */
|
||||
const TObject *luaH_get (Hash *t, const TObject *key) {
|
||||
switch (ttype(key)) {
|
||||
case LUA_TSTRING: return luaH_getstr(t, tsvalue(key));
|
||||
case LUA_TNUMBER: {
|
||||
int k = (int)nvalue(key);
|
||||
if ((lua_Number)k == nvalue(key)) /* is an integer index? */
|
||||
return luaH_getnum(t, k); /* use specialized version */
|
||||
/* else go through */
|
||||
}
|
||||
default: return luaH_getany(t, key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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, l_s("table index is nil"));
|
||||
return (TObject *)&luaO_nilobject; /* get option */
|
||||
default: return luaH_setany(L, t, key);
|
||||
const TObject *p = luaH_get(t, key);
|
||||
if (p != &luaO_nilobject) return (TObject *)p;
|
||||
else if (ttype(key) == LUA_TNIL) luaD_error(L, l_s("table index is nil"));
|
||||
return newkey(L, t, key);
|
||||
}
|
||||
|
||||
|
||||
TObject *luaH_setstr (lua_State *L, Hash *t, TString *key) {
|
||||
const TObject *p = luaH_getstr(t, key);
|
||||
if (p != &luaO_nilobject) return (TObject *)p;
|
||||
else {
|
||||
TObject k;
|
||||
setsvalue(&k, key);
|
||||
return newkey(L, t, &k);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TObject *luaH_setnum (lua_State *L, Hash *t, int key) {
|
||||
const TObject *p = luaH_getnum(t, key);
|
||||
if (p != &luaO_nilobject) return (TObject *)p;
|
||||
else {
|
||||
TObject k;
|
||||
setnvalue(&k, key);
|
||||
return newkey(L, t, &k);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
18
ltable.h
18
ltable.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: ltable.h,v 1.32 2001/02/02 16:32:00 roberto Exp roberto $
|
||||
** $Id: ltable.h,v 1.33 2001/06/26 13:20:45 roberto Exp roberto $
|
||||
** Lua tables (hash)
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -14,21 +14,19 @@
|
|||
#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)
|
||||
|
||||
const TObject *luaH_getnum (Hash *t, int key);
|
||||
TObject *luaH_setnum (lua_State *L, Hash *t, int key);
|
||||
const TObject *luaH_getstr (Hash *t, TString *key);
|
||||
TObject *luaH_setstr (lua_State *L, Hash *t, TString *key);
|
||||
const TObject *luaH_get (Hash *t, const TObject *key);
|
||||
TObject *luaH_set (lua_State *L, Hash *t, const TObject *key);
|
||||
Hash *luaH_new (lua_State *L, int nhash);
|
||||
void luaH_free (lua_State *L, Hash *t);
|
||||
TObject *luaH_set (lua_State *L, Hash *t, const TObject *key);
|
||||
Node *luaH_next (lua_State *L, Hash *t, const TObject *r);
|
||||
int luaH_nexti (Hash *t, int i);
|
||||
TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key);
|
||||
TObject *luaH_setstr (lua_State *L, Hash *t, TString *key);
|
||||
|
||||
/* exported only for debugging */
|
||||
Node *luaH_mainposition (const Hash *t, const Node *n);
|
||||
Node *luaH_mainposition (const Hash *t, const TObject *key);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
8
ltests.c
8
ltests.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: ltests.c,v 1.85 2001/06/28 15:06:20 roberto Exp roberto $
|
||||
** $Id: ltests.c,v 1.86 2001/06/28 19:58:57 roberto Exp roberto $
|
||||
** Internal Module for Debugging of the Lua Implementation
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -251,13 +251,11 @@ static int hash_query (lua_State *L) {
|
|||
lua_pushnumber(L, tsvalue(luaA_index(L, 1))->tsv.hash);
|
||||
}
|
||||
else {
|
||||
Hash *t;
|
||||
Node n;
|
||||
TObject *o = luaA_index(L, 1);
|
||||
Hash *t;
|
||||
luaL_checktype(L, 2, LUA_TTABLE);
|
||||
t = hvalue(luaA_index(L, 2));
|
||||
setobj(key(&n), o);
|
||||
lua_pushnumber(L, luaH_mainposition(t, &n) - t->node);
|
||||
lua_pushnumber(L, luaH_mainposition(t, o) - t->node);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue