diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-01-26 12:16:35 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-01-26 12:16:35 -0200 |
| commit | ac390020e91e14f00200ad3df97682b715d3e59b (patch) | |
| tree | e86c7128814f6c754e9bebf4bbdad08ba4e8aeff | |
| parent | 9b45439860879dd282e6d0896c4ee8102febc7fd (diff) | |
| download | lua-ac390020e91e14f00200ad3df97682b715d3e59b.tar.gz lua-ac390020e91e14f00200ad3df97682b715d3e59b.tar.bz2 lua-ac390020e91e14f00200ad3df97682b715d3e59b.zip | |
optimizations based on all types but number and nil are pointers
| -rw-r--r-- | lobject.c | 13 | ||||
| -rw-r--r-- | ltable.c | 114 | ||||
| -rw-r--r-- | ltable.h | 11 |
3 files changed, 47 insertions, 91 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.c,v 1.60 2001/01/24 15:45:33 roberto Exp roberto $ | 2 | ** $Id: lobject.c,v 1.61 2001/01/25 16:45:36 roberto Exp roberto $ |
| 3 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -37,15 +37,10 @@ int luaO_equalObj (const TObject *t1, const TObject *t2) { | |||
| 37 | switch (ttype(t1)) { | 37 | switch (ttype(t1)) { |
| 38 | case LUA_TNUMBER: | 38 | case LUA_TNUMBER: |
| 39 | return nvalue(t1) == nvalue(t2); | 39 | return nvalue(t1) == nvalue(t2); |
| 40 | case LUA_TSTRING: case LUA_TUSERDATA: | 40 | case LUA_TNIL: |
| 41 | return 1; | ||
| 42 | default: /* all other types are equal if pointers are equal */ | ||
| 41 | return tsvalue(t1) == tsvalue(t2); | 43 | return tsvalue(t1) == tsvalue(t2); |
| 42 | case LUA_TTABLE: | ||
| 43 | return hvalue(t1) == hvalue(t2); | ||
| 44 | case LUA_TFUNCTION: | ||
| 45 | return clvalue(t1) == clvalue(t2); | ||
| 46 | default: | ||
| 47 | lua_assert(ttype(t1) == LUA_TNIL); | ||
| 48 | return 1; /* LUA_TNIL */ | ||
| 49 | } | 44 | } |
| 50 | } | 45 | } |
| 51 | 46 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.c,v 1.67 2001/01/25 16:45:36 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 1.68 2001/01/26 13:18:00 roberto Exp roberto $ |
| 3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -31,8 +31,9 @@ | |||
| 31 | #define TagDefault LUA_TTABLE | 31 | #define TagDefault LUA_TTABLE |
| 32 | 32 | ||
| 33 | 33 | ||
| 34 | #define hashnum(t,n) (&t->node[(luint32)(lint32)(n)&(t->size-1)]) | 34 | #define hashnum(t,n) (&t->node[(luint32)(lint32)(n)&(t->size-1)]) |
| 35 | #define hashstr(t,str) (&t->node[(str)->u.s.hash&(t->size-1)]) | 35 | #define hashstr(t,str) (&t->node[(str)->u.s.hash&(t->size-1)]) |
| 36 | #define hashpointer(t,p) (&t->node[IntPoint(p)&(t->size-1)]) | ||
| 36 | 37 | ||
| 37 | 38 | ||
| 38 | /* | 39 | /* |
| @@ -40,73 +41,18 @@ | |||
| 40 | ** of its hash value) | 41 | ** of its hash value) |
| 41 | */ | 42 | */ |
| 42 | Node *luaH_mainposition (const Hash *t, const TObject *key) { | 43 | Node *luaH_mainposition (const Hash *t, const TObject *key) { |
| 43 | luint32 h; | ||
| 44 | switch (ttype(key)) { | 44 | switch (ttype(key)) { |
| 45 | case LUA_TNUMBER: | 45 | case LUA_TNUMBER: |
| 46 | return hashnum(t, nvalue(key)); | 46 | return hashnum(t, nvalue(key)); |
| 47 | case LUA_TSTRING: | 47 | case LUA_TSTRING: |
| 48 | return hashstr(t, tsvalue(key)); | 48 | return hashstr(t, tsvalue(key)); |
| 49 | case LUA_TUSERDATA: | 49 | default: /* all other types are hashed as (void *) */ |
| 50 | h = IntPoint(tsvalue(key)); | 50 | return hashpointer(t, hvalue(key)); |
| 51 | break; | ||
| 52 | case LUA_TTABLE: | ||
| 53 | h = IntPoint(hvalue(key)); | ||
| 54 | break; | ||
| 55 | case LUA_TFUNCTION: | ||
| 56 | h = IntPoint(clvalue(key)); | ||
| 57 | break; | ||
| 58 | default: | ||
| 59 | return NULL; /* invalid key */ | ||
| 60 | } | 51 | } |
| 61 | return &t->node[h&(t->size-1)]; | ||
| 62 | } | 52 | } |
| 63 | 53 | ||
| 64 | 54 | ||
| 65 | static const TObject *luaH_getany (const Hash *t, const TObject *key) { | 55 | Node *luaH_next (lua_State *L, Hash *t, const TObject *key) { |
| 66 | Node *n = luaH_mainposition(t, key); | ||
| 67 | while (n) { | ||
| 68 | if (luaO_equalObj(key, &n->key)) | ||
| 69 | return &n->val; | ||
| 70 | n = n->next; | ||
| 71 | } | ||
| 72 | return &luaO_nilobject; /* key not found */ | ||
| 73 | } | ||
| 74 | |||
| 75 | |||
| 76 | /* specialized version for numbers */ | ||
| 77 | const TObject *luaH_getnum (const Hash *t, lua_Number key) { | ||
| 78 | Node *n = hashnum(t, key); | ||
| 79 | do { | ||
| 80 | if (nvalue(&n->key) == key && ttype(&n->key) == LUA_TNUMBER) | ||
| 81 | return &n->val; | ||
| 82 | n = n->next; | ||
| 83 | } while (n); | ||
| 84 | return &luaO_nilobject; /* key not found */ | ||
| 85 | } | ||
| 86 | |||
| 87 | |||
| 88 | /* specialized version for strings */ | ||
| 89 | const TObject *luaH_getstr (const Hash *t, TString *key) { | ||
| 90 | Node *n = hashstr(t, key); | ||
| 91 | do { | ||
| 92 | if (tsvalue(&n->key) == key && ttype(&n->key) == LUA_TSTRING) | ||
| 93 | return &n->val; | ||
| 94 | n = n->next; | ||
| 95 | } while (n); | ||
| 96 | return &luaO_nilobject; /* key not found */ | ||
| 97 | } | ||
| 98 | |||
| 99 | |||
| 100 | const TObject *luaH_get (const Hash *t, const TObject *key) { | ||
| 101 | switch (ttype(key)) { | ||
| 102 | case LUA_TNUMBER: return luaH_getnum(t, nvalue(key)); | ||
| 103 | case LUA_TSTRING: return luaH_getstr(t, tsvalue(key)); | ||
| 104 | default: return luaH_getany(t, key); | ||
| 105 | } | ||
| 106 | } | ||
| 107 | |||
| 108 | |||
| 109 | Node *luaH_next (lua_State *L, const Hash *t, const TObject *key) { | ||
| 110 | int i; | 56 | int i; |
| 111 | if (ttype(key) == LUA_TNIL) | 57 | if (ttype(key) == LUA_TNIL) |
| 112 | i = 0; /* first iteration */ | 58 | i = 0; /* first iteration */ |
| @@ -197,8 +143,8 @@ static void rehash (lua_State *L, Hash *t) { | |||
| 197 | 143 | ||
| 198 | /* | 144 | /* |
| 199 | ** inserts a new key into a hash table; first, check whether key's main | 145 | ** inserts a new key into a hash table; first, check whether key's main |
| 200 | ** position is free; if not, check whether colliding node is in its main | 146 | ** position is free. If not, check whether colliding node is in its main |
| 201 | ** position or not; if it is not, move colliding node to an empty place and | 147 | ** position or not: if it is not, move colliding node to an empty place and |
| 202 | ** put new key in its main position; otherwise (colliding node is in its main | 148 | ** put new key in its main position; otherwise (colliding node is in its main |
| 203 | ** position), new key goes to an empty position. | 149 | ** position), new key goes to an empty position. |
| 204 | */ | 150 | */ |
| @@ -234,20 +180,9 @@ static TObject *newkey (lua_State *L, Hash *t, Node *mp, const TObject *key) { | |||
| 234 | } | 180 | } |
| 235 | 181 | ||
| 236 | 182 | ||
| 237 | static TObject *luaH_setany (lua_State *L, Hash *t, const TObject *key) { | 183 | /* |
| 238 | Node *mp = luaH_mainposition(t, key); | 184 | ** search function for numbers |
| 239 | Node *n = mp; | 185 | */ |
| 240 | if (!mp) | ||
| 241 | luaD_error(L, "table index is nil"); | ||
| 242 | do { /* check whether `key' is somewhere in the chain */ | ||
| 243 | if (luaO_equalObj(key, &n->key)) | ||
| 244 | return &n->val; /* that's all */ | ||
| 245 | else n = n->next; | ||
| 246 | } while (n); | ||
| 247 | return newkey(L, t, mp, key); /* `key' not found; must insert it */ | ||
| 248 | } | ||
| 249 | |||
| 250 | |||
| 251 | TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key) { | 186 | TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key) { |
| 252 | TObject kobj; | 187 | TObject kobj; |
| 253 | Node *mp = hashnum(t, key); | 188 | Node *mp = hashnum(t, key); |
| @@ -257,12 +192,16 @@ TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key) { | |||
| 257 | return &n->val; /* that's all */ | 192 | return &n->val; /* that's all */ |
| 258 | else n = n->next; | 193 | else n = n->next; |
| 259 | } while (n); | 194 | } while (n); |
| 195 | if (L == NULL) return (TObject *)&luaO_nilobject; /* get option */ | ||
| 260 | /* `key' not found; must insert it */ | 196 | /* `key' not found; must insert it */ |
| 261 | setnvalue(&kobj, key); | 197 | setnvalue(&kobj, key); |
| 262 | return newkey(L, t, mp, &kobj); | 198 | return newkey(L, t, mp, &kobj); |
| 263 | } | 199 | } |
| 264 | 200 | ||
| 265 | 201 | ||
| 202 | /* | ||
| 203 | ** search function for strings | ||
| 204 | */ | ||
| 266 | TObject *luaH_setstr (lua_State *L, Hash *t, TString *key) { | 205 | TObject *luaH_setstr (lua_State *L, Hash *t, TString *key) { |
| 267 | TObject kobj; | 206 | TObject kobj; |
| 268 | Node *mp = hashstr(t, key); | 207 | Node *mp = hashstr(t, key); |
| @@ -272,16 +211,37 @@ TObject *luaH_setstr (lua_State *L, Hash *t, TString *key) { | |||
| 272 | return &n->val; /* that's all */ | 211 | return &n->val; /* that's all */ |
| 273 | else n = n->next; | 212 | else n = n->next; |
| 274 | } while (n); | 213 | } while (n); |
| 214 | if (L == NULL) return (TObject *)&luaO_nilobject; /* get option */ | ||
| 275 | /* `key' not found; must insert it */ | 215 | /* `key' not found; must insert it */ |
| 276 | setsvalue(&kobj, key); | 216 | setsvalue(&kobj, key); |
| 277 | return newkey(L, t, mp, &kobj); | 217 | return newkey(L, t, mp, &kobj); |
| 278 | } | 218 | } |
| 279 | 219 | ||
| 280 | 220 | ||
| 221 | /* | ||
| 222 | ** search function for 'pointer' types | ||
| 223 | */ | ||
| 224 | static TObject *luaH_setany (lua_State *L, Hash *t, const TObject *key) { | ||
| 225 | Node *mp = hashpointer(t, hvalue(key)); | ||
| 226 | Node *n = mp; | ||
| 227 | do { /* check whether `key' is somewhere in the chain */ | ||
| 228 | /* compare as `hvalue', but may be other pointers (it is the same) */ | ||
| 229 | if (hvalue(&n->key) == hvalue(key) && ttype(&n->key) == ttype(key)) | ||
| 230 | return &n->val; /* that's all */ | ||
| 231 | else n = n->next; | ||
| 232 | } while (n); | ||
| 233 | if (L == NULL) return (TObject *)&luaO_nilobject; /* get option */ | ||
| 234 | return newkey(L, t, mp, key); /* `key' not found; must insert it */ | ||
| 235 | } | ||
| 236 | |||
| 237 | |||
| 281 | TObject *luaH_set (lua_State *L, Hash *t, const TObject *key) { | 238 | TObject *luaH_set (lua_State *L, Hash *t, const TObject *key) { |
| 282 | switch (ttype(key)) { | 239 | switch (ttype(key)) { |
| 283 | case LUA_TNUMBER: return luaH_setnum(L, t, nvalue(key)); | 240 | case LUA_TNUMBER: return luaH_setnum(L, t, nvalue(key)); |
| 284 | case LUA_TSTRING: return luaH_setstr(L, t, tsvalue(key)); | 241 | case LUA_TSTRING: return luaH_setstr(L, t, tsvalue(key)); |
| 242 | case LUA_TNIL: | ||
| 243 | if (L) luaD_error(L, "table index is nil"); | ||
| 244 | return (TObject *)&luaO_nilobject; /* get option */ | ||
| 285 | default: return luaH_setany(L, t, key); | 245 | default: return luaH_setany(L, t, key); |
| 286 | } | 246 | } |
| 287 | } | 247 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.h,v 1.27 2001/01/10 18:56:11 roberto Exp roberto $ | 2 | ** $Id: ltable.h,v 1.28 2001/01/26 13:18:00 roberto Exp roberto $ |
| 3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -14,13 +14,14 @@ | |||
| 14 | #define key(n) (&(n)->key) | 14 | #define key(n) (&(n)->key) |
| 15 | #define val(n) (&(n)->val) | 15 | #define val(n) (&(n)->val) |
| 16 | 16 | ||
| 17 | #define luaH_get(t,k) luaH_set(NULL,t,k) | ||
| 18 | #define luaH_getnum(t,k) luaH_setnum(NULL,t,k) | ||
| 19 | #define luaH_getstr(t,k) luaH_setstr(NULL,t,k) | ||
| 20 | |||
| 17 | Hash *luaH_new (lua_State *L, int nhash); | 21 | Hash *luaH_new (lua_State *L, int nhash); |
| 18 | void luaH_free (lua_State *L, Hash *t); | 22 | void luaH_free (lua_State *L, Hash *t); |
| 19 | const TObject *luaH_get (const Hash *t, const TObject *key); | ||
| 20 | const TObject *luaH_getnum (const Hash *t, lua_Number key); | ||
| 21 | const TObject *luaH_getstr (const Hash *t, TString *key); | ||
| 22 | TObject *luaH_set (lua_State *L, Hash *t, const TObject *key); | 23 | TObject *luaH_set (lua_State *L, Hash *t, const TObject *key); |
| 23 | Node * luaH_next (lua_State *L, const Hash *t, const TObject *r); | 24 | Node * luaH_next (lua_State *L, Hash *t, const TObject *r); |
| 24 | TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key); | 25 | TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key); |
| 25 | TObject *luaH_setstr (lua_State *L, Hash *t, TString *key); | 26 | TObject *luaH_setstr (lua_State *L, Hash *t, TString *key); |
| 26 | 27 | ||
