diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-11-26 16:59:20 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-11-26 16:59:20 -0200 |
| commit | d015f1fc02e03864b0ed3ad668a6e0660417a718 (patch) | |
| tree | 00b5962e40540bbb8a71bf8665fed256182aa6c7 /ltable.c | |
| parent | 790690a2236ab0ad0cce35551c17e62064b4c85b (diff) | |
| download | lua-d015f1fc02e03864b0ed3ad668a6e0660417a718.tar.gz lua-d015f1fc02e03864b0ed3ad668a6e0660417a718.tar.bz2 lua-d015f1fc02e03864b0ed3ad668a6e0660417a718.zip | |
table sizes don't need to be primes; power of 2 gives the same performance.
Diffstat (limited to 'ltable.c')
| -rw-r--r-- | ltable.c | 14 |
1 files changed, 8 insertions, 6 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.c,v 1.29 1999/11/10 15:39:35 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 1.30 1999/11/22 13:12:07 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 | */ |
| @@ -65,7 +65,9 @@ Node *luaH_mainposition (lua_State *L, const Hash *t, const TObject *key) { | |||
| 65 | lua_error(L, "unexpected type to index table"); | 65 | lua_error(L, "unexpected type to index table"); |
| 66 | h = 0; /* to avoid warnings */ | 66 | h = 0; /* to avoid warnings */ |
| 67 | } | 67 | } |
| 68 | return &t->node[h%(unsigned int)t->size]; | 68 | LUA_ASSERT(L, h%(unsigned int)t->size == (h&((unsigned int)t->size-1)), |
| 69 | "a&(x-1) == a%x, for x power of 2"); | ||
| 70 | return &t->node[h&((unsigned int)t->size-1)]; | ||
| 69 | } | 71 | } |
| 70 | 72 | ||
| 71 | 73 | ||
| @@ -109,7 +111,7 @@ static void setnodevector (lua_State *L, Hash *t, int size) { | |||
| 109 | 111 | ||
| 110 | Hash *luaH_new (lua_State *L, int size) { | 112 | Hash *luaH_new (lua_State *L, int size) { |
| 111 | Hash *t = luaM_new(L, Hash); | 113 | Hash *t = luaM_new(L, Hash); |
| 112 | setnodevector(L, t, luaO_redimension(L, size+1)); | 114 | setnodevector(L, t, luaO_power2(size)); |
| 113 | t->htag = TagDefault; | 115 | t->htag = TagDefault; |
| 114 | t->next = L->roottable; | 116 | t->next = L->roottable; |
| 115 | L->roottable = t; | 117 | L->roottable = t; |
| @@ -125,7 +127,7 @@ void luaH_free (lua_State *L, Hash *t) { | |||
| 125 | } | 127 | } |
| 126 | 128 | ||
| 127 | 129 | ||
| 128 | static int newsize (lua_State *L, const Hash *t) { | 130 | static int newsize (const Hash *t) { |
| 129 | Node *v = t->node; | 131 | Node *v = t->node; |
| 130 | int size = t->size; | 132 | int size = t->size; |
| 131 | int realuse = 0; | 133 | int realuse = 0; |
| @@ -134,7 +136,7 @@ static int newsize (lua_State *L, const Hash *t) { | |||
| 134 | if (ttype(&v[i].val) != LUA_T_NIL) | 136 | if (ttype(&v[i].val) != LUA_T_NIL) |
| 135 | realuse++; | 137 | realuse++; |
| 136 | } | 138 | } |
| 137 | return luaO_redimension(L, realuse*2); | 139 | return luaO_power2(realuse+realuse/4+1); |
| 138 | } | 140 | } |
| 139 | 141 | ||
| 140 | 142 | ||
| @@ -148,7 +150,7 @@ static void rehash (lua_State *L, Hash *t) { | |||
| 148 | Node *nold = t->node; | 150 | Node *nold = t->node; |
| 149 | int i; | 151 | int i; |
| 150 | L->nblocks -= gcsize(L, oldsize); | 152 | L->nblocks -= gcsize(L, oldsize); |
| 151 | setnodevector(L, t, newsize(L, t)); /* create new array of nodes */ | 153 | setnodevector(L, t, newsize(t)); /* create new array of nodes */ |
| 152 | /* first loop; set only elements that can go in their main positions */ | 154 | /* first loop; set only elements that can go in their main positions */ |
| 153 | for (i=0; i<oldsize; i++) { | 155 | for (i=0; i<oldsize; i++) { |
| 154 | Node *old = nold+i; | 156 | Node *old = nold+i; |
