diff options
| -rw-r--r-- | ltable.c | 53 |
1 files changed, 38 insertions, 15 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.c,v 1.129 2003/03/18 12:50:04 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 1.130 2003/03/20 20:26:33 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 | */ |
| @@ -21,6 +21,7 @@ | |||
| 21 | ** performance penalties. | 21 | ** performance penalties. |
| 22 | */ | 22 | */ |
| 23 | 23 | ||
| 24 | #include <string.h> | ||
| 24 | 25 | ||
| 25 | #define ltable_c | 26 | #define ltable_c |
| 26 | 27 | ||
| @@ -54,17 +55,41 @@ | |||
| 54 | #endif | 55 | #endif |
| 55 | 56 | ||
| 56 | 57 | ||
| 57 | #define hashg(t,n) (gnode(t, lmod((n), sizenode(t)))) | 58 | #define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) |
| 58 | 59 | ||
| 59 | #define hashnum(t,n) hashg(t, cast(lu_hash, cast(ls_hash, (n)))) | 60 | #define hashstr(t,str) hashpow2(t, (str)->tsv.hash) |
| 60 | #define hashstr(t,str) hashg(t, (str)->tsv.hash) | 61 | #define hashboolean(t,p) hashpow2(t, p) |
| 61 | #define hashboolean(t,p) hashg(t, p) | 62 | |
| 63 | |||
| 64 | /* | ||
| 65 | ** for some types, it is better to avoid modulus by power of 2, as | ||
| 66 | ** they tend to have many 2 factors. | ||
| 67 | */ | ||
| 68 | #define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) | ||
| 69 | |||
| 70 | |||
| 71 | #define hashpointer(t,p) hashmod(t, IntPoint(p)) | ||
| 72 | |||
| 73 | |||
| 74 | /* | ||
| 75 | ** number of ints inside a lua_Number | ||
| 76 | */ | ||
| 77 | #define numints cast(int, sizeof(lua_Number)/sizeof(int)) | ||
| 78 | |||
| 62 | 79 | ||
| 63 | /* | 80 | /* |
| 64 | ** avoid modulus by power of 2 for pointers, as they tend to have many | 81 | ** hash for lua_Numbers |
| 65 | ** 2 factors. | ||
| 66 | */ | 82 | */ |
| 67 | #define hashpointer(t,p) (gnode(t, (IntPoint(p) % ((sizenode(t)-1)|1)))) | 83 | static Node *hashnum (const Table *t, lua_Number n) { |
| 84 | unsigned int a[numints]; | ||
| 85 | int i; | ||
| 86 | n += 1; /* normalize number (avoid -0) */ | ||
| 87 | lua_assert(sizeof(a) <= sizeof(n)); | ||
| 88 | memcpy(a, &n, sizeof(a)); | ||
| 89 | for (i = 1; i < numints; i++) a[0] += a[i]; | ||
| 90 | return hashmod(t, cast(lu_hash, a[0])); | ||
| 91 | } | ||
| 92 | |||
| 68 | 93 | ||
| 69 | 94 | ||
| 70 | /* | 95 | /* |
| @@ -73,11 +98,8 @@ | |||
| 73 | */ | 98 | */ |
| 74 | Node *luaH_mainposition (const Table *t, const TObject *key) { | 99 | Node *luaH_mainposition (const Table *t, const TObject *key) { |
| 75 | switch (ttype(key)) { | 100 | switch (ttype(key)) { |
| 76 | case LUA_TNUMBER: { | 101 | case LUA_TNUMBER: |
| 77 | int ikey; | 102 | return hashnum(t, nvalue(key)); |
| 78 | lua_number2int(ikey, nvalue(key)); | ||
| 79 | return hashnum(t, ikey); | ||
| 80 | } | ||
| 81 | case LUA_TSTRING: | 103 | case LUA_TSTRING: |
| 82 | return hashstr(t, tsvalue(key)); | 104 | return hashstr(t, tsvalue(key)); |
| 83 | case LUA_TBOOLEAN: | 105 | case LUA_TBOOLEAN: |
| @@ -416,9 +438,10 @@ const TObject *luaH_getnum (Table *t, int key) { | |||
| 416 | if (1 <= key && key <= t->sizearray) | 438 | if (1 <= key && key <= t->sizearray) |
| 417 | return &t->array[key-1]; | 439 | return &t->array[key-1]; |
| 418 | else { | 440 | else { |
| 419 | Node *n = hashnum(t, key); | 441 | lua_Number nk = cast(lua_Number, key); |
| 442 | Node *n = hashnum(t, nk); | ||
| 420 | do { /* check whether `key' is somewhere in the chain */ | 443 | do { /* check whether `key' is somewhere in the chain */ |
| 421 | if (ttisnumber(gkey(n)) && nvalue(gkey(n)) == (lua_Number)key) | 444 | if (ttisnumber(gkey(n)) && nvalue(gkey(n)) == nk) |
| 422 | return gval(n); /* that's it */ | 445 | return gval(n); /* that's it */ |
| 423 | else n = n->next; | 446 | else n = n->next; |
| 424 | } while (n); | 447 | } while (n); |
