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)
|
** Lua tables (hash)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -41,14 +41,14 @@
|
||||||
** returns the `main' position of an element in a table (that is, the index
|
** returns the `main' position of an element in a table (that is, the index
|
||||||
** of its hash value)
|
** of its hash value)
|
||||||
*/
|
*/
|
||||||
Node *luaH_mainposition (const Hash *t, const Node *n) {
|
Node *luaH_mainposition (const Hash *t, const TObject *key) {
|
||||||
switch (ttype(key(n))) {
|
switch (ttype(key)) {
|
||||||
case LUA_TNUMBER:
|
case LUA_TNUMBER:
|
||||||
return hashnum(t, nvalue(key(n)));
|
return hashnum(t, nvalue(key));
|
||||||
case LUA_TSTRING:
|
case LUA_TSTRING:
|
||||||
return hashstr(t, tsvalue(key(n)));
|
return hashstr(t, tsvalue(key));
|
||||||
default: /* all other types are hashed as (void *) */
|
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);
|
const TObject *v = luaH_get(t, key);
|
||||||
if (v == &luaO_nilobject)
|
if (v == &luaO_nilobject)
|
||||||
luaD_error(L, l_s("invalid key for `next'"));
|
luaD_error(L, l_s("invalid key for `next'"));
|
||||||
i = (int)(((const l_char *)v -
|
i = (int)(((const lu_byte *)v -
|
||||||
(const l_char *)(val(node(t, 0)))) / sizeof(Node)) + 1;
|
(const lu_byte *)(val(node(t, 0)))) / sizeof(Node)) + 1;
|
||||||
}
|
}
|
||||||
for (; i<t->size; i++) {
|
for (; i<t->size; i++) {
|
||||||
Node *n = node(t, 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) {
|
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? */
|
if (ttype(val(node(t, i))) != LUA_TNIL) /* a non-nil value? */
|
||||||
return i;
|
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
|
** put new key in its main position; otherwise (colliding node is in its main
|
||||||
** position), new key goes to an empty position.
|
** 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? */
|
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 */
|
Node *n = t->firstfree; /* get a free place */
|
||||||
if (othern != mp) { /* is colliding node out of its main position? */
|
if (othern != mp) { /* is colliding node out of its main position? */
|
||||||
/* yes; move colliding node into free 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) {
|
static const TObject *luaH_getany (Hash *t, const TObject *key) {
|
||||||
TObject kobj;
|
if (ttype(key) == LUA_TNIL) return &luaO_nilobject;
|
||||||
Node *mp = hashnum(t, key);
|
else {
|
||||||
Node *n = mp;
|
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 */
|
do { /* check whether `key' is somewhere in the chain */
|
||||||
if (ttype(key(n)) == LUA_TNUMBER && nvalue(key(n)) == key)
|
if (ttype(key(n)) == LUA_TNUMBER && nvalue(key(n)) == (lua_Number)key)
|
||||||
return val(n); /* that's all */
|
return val(n); /* that's it */
|
||||||
else n = n->next;
|
else n = n->next;
|
||||||
} while (n);
|
} while (n);
|
||||||
if (L == NULL) return (TObject *)&luaO_nilobject; /* get option */
|
return &luaO_nilobject;
|
||||||
/* `key' not found; must insert it */
|
|
||||||
setnvalue(&kobj, key);
|
|
||||||
return newkey(L, t, mp, &kobj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** search function for strings
|
** search function for strings
|
||||||
*/
|
*/
|
||||||
TObject *luaH_setstr (lua_State *L, Hash *t, TString *key) {
|
const TObject *luaH_getstr (Hash *t, TString *key) {
|
||||||
TObject kobj;
|
Node *n = hashstr(t, key);
|
||||||
Node *mp = hashstr(t, key);
|
|
||||||
Node *n = mp;
|
|
||||||
do { /* check whether `key' is somewhere in the chain */
|
do { /* check whether `key' is somewhere in the chain */
|
||||||
if (ttype(key(n)) == LUA_TSTRING && tsvalue(key(n)) == key)
|
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;
|
else n = n->next;
|
||||||
} while (n);
|
} while (n);
|
||||||
if (L == NULL) return (TObject *)&luaO_nilobject; /* get option */
|
return &luaO_nilobject;
|
||||||
/* `key' not found; must insert it */
|
|
||||||
setsvalue(&kobj, key);
|
|
||||||
return newkey(L, t, mp, &kobj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** search function for 'pointer' types
|
** main search function
|
||||||
*/
|
*/
|
||||||
static TObject *luaH_setany (lua_State *L, Hash *t, const TObject *key) {
|
const TObject *luaH_get (Hash *t, const TObject *key) {
|
||||||
Node *mp = hashpointer(t, hvalue(key));
|
switch (ttype(key)) {
|
||||||
Node *n = mp;
|
case LUA_TSTRING: return luaH_getstr(t, tsvalue(key));
|
||||||
do { /* check whether `key' is somewhere in the chain */
|
case LUA_TNUMBER: {
|
||||||
/* compare as `tsvalue', but may be other pointers (it is the same) */
|
int k = (int)nvalue(key);
|
||||||
if (ttype(key(n)) == ttype(key) && tsvalue(key(n)) == tsvalue(key))
|
if ((lua_Number)k == nvalue(key)) /* is an integer index? */
|
||||||
return val(n); /* that's all */
|
return luaH_getnum(t, k); /* use specialized version */
|
||||||
else n = n->next;
|
/* else go through */
|
||||||
} while (n);
|
}
|
||||||
if (L == NULL) return (TObject *)&luaO_nilobject; /* get option */
|
default: return luaH_getany(t, key);
|
||||||
return newkey(L, t, mp, key); /* `key' not found; must insert it */
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TObject *luaH_set (lua_State *L, Hash *t, const TObject *key) {
|
TObject *luaH_set (lua_State *L, Hash *t, const TObject *key) {
|
||||||
switch (ttype(key)) {
|
const TObject *p = luaH_get(t, key);
|
||||||
case LUA_TNUMBER: return luaH_setnum(L, t, nvalue(key));
|
if (p != &luaO_nilobject) return (TObject *)p;
|
||||||
case LUA_TSTRING: return luaH_setstr(L, t, tsvalue(key));
|
else if (ttype(key) == LUA_TNIL) luaD_error(L, l_s("table index is nil"));
|
||||||
case LUA_TNIL:
|
return newkey(L, t, key);
|
||||||
if (L) luaD_error(L, l_s("table index is nil"));
|
}
|
||||||
return (TObject *)&luaO_nilobject; /* get option */
|
|
||||||
default: return luaH_setany(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)
|
** Lua tables (hash)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -14,21 +14,19 @@
|
||||||
#define key(_n) (&(_n)->key)
|
#define key(_n) (&(_n)->key)
|
||||||
#define val(_n) (&(_n)->val)
|
#define val(_n) (&(_n)->val)
|
||||||
|
|
||||||
|
const TObject *luaH_getnum (Hash *t, int key);
|
||||||
#define luaH_get(_t,_k) luaH_set(NULL,_t,_k)
|
TObject *luaH_setnum (lua_State *L, Hash *t, int key);
|
||||||
#define luaH_getnum(_t,_k) luaH_setnum(NULL,_t,_k)
|
const TObject *luaH_getstr (Hash *t, TString *key);
|
||||||
#define luaH_getstr(_t,_k) luaH_setstr(NULL,_t,_k)
|
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);
|
Hash *luaH_new (lua_State *L, int nhash);
|
||||||
void luaH_free (lua_State *L, Hash *t);
|
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);
|
Node *luaH_next (lua_State *L, Hash *t, const TObject *r);
|
||||||
int luaH_nexti (Hash *t, int i);
|
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 */
|
/* exported only for debugging */
|
||||||
Node *luaH_mainposition (const Hash *t, const Node *n);
|
Node *luaH_mainposition (const Hash *t, const TObject *key);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#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
|
** Internal Module for Debugging of the Lua Implementation
|
||||||
** See Copyright Notice in lua.h
|
** 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);
|
lua_pushnumber(L, tsvalue(luaA_index(L, 1))->tsv.hash);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Hash *t;
|
|
||||||
Node n;
|
|
||||||
TObject *o = luaA_index(L, 1);
|
TObject *o = luaA_index(L, 1);
|
||||||
|
Hash *t;
|
||||||
luaL_checktype(L, 2, LUA_TTABLE);
|
luaL_checktype(L, 2, LUA_TTABLE);
|
||||||
t = hvalue(luaA_index(L, 2));
|
t = hvalue(luaA_index(L, 2));
|
||||||
setobj(key(&n), o);
|
lua_pushnumber(L, luaH_mainposition(t, o) - t->node);
|
||||||
lua_pushnumber(L, luaH_mainposition(t, &n) - t->node);
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue