summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-02-14 19:41:08 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-02-14 19:41:08 -0200
commitbee86e23be69f9c009fd4ae57ba894f944c0952b (patch)
tree460459a3f39d314a573bb4867bae4647e8a9d8dc
parent0056ed413519c6767b6b6f502cbc1a5254f41eda (diff)
downloadlua-bee86e23be69f9c009fd4ae57ba894f944c0952b.tar.gz
lua-bee86e23be69f9c009fd4ae57ba894f944c0952b.tar.bz2
lua-bee86e23be69f9c009fd4ae57ba894f944c0952b.zip
`luaH_next' works like `next' + better hash for pointers
-rw-r--r--ltable.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/ltable.c b/ltable.c
index 364a0309..098109ff 100644
--- a/ltable.c
+++ b/ltable.c
@@ -53,7 +53,12 @@
53 (node(t, lmod(cast(lu_hash, cast(ls_hash, n)), sizenode(t)))) 53 (node(t, lmod(cast(lu_hash, cast(ls_hash, n)), sizenode(t))))
54#define hashstr(t,str) (node(t, lmod((str)->tsv.hash, sizenode(t)))) 54#define hashstr(t,str) (node(t, lmod((str)->tsv.hash, sizenode(t))))
55#define hashboolean(t,p) (node(t, p)) /* `p' in [0,1] < minimum table size */ 55#define hashboolean(t,p) (node(t, p)) /* `p' in [0,1] < minimum table size */
56#define hashpointer(t,p) (node(t, lmod(IntPoint(p), sizenode(t)))) 56
57/*
58** for pointers, avoid modulus by power of 2, as they tend to have many
59** 2 factors.
60*/
61#define hashpointer(t,p) (node(t, (IntPoint(p) % (sizenode(t)-1))))
57 62
58 63
59/* 64/*
@@ -93,7 +98,7 @@ static int arrayindex (const TObject *key) {
93** elements in the array part, then elements in the hash part. The 98** elements in the array part, then elements in the hash part. The
94** beginning and end of a traversal are signalled by -1. 99** beginning and end of a traversal are signalled by -1.
95*/ 100*/
96int luaH_index (lua_State *L, Table *t, const TObject *key) { 101static int luaH_index (lua_State *L, Table *t, const TObject *key) {
97 int i; 102 int i;
98 if (ttype(key) == LUA_TNIL) return -1; /* first iteration */ 103 if (ttype(key) == LUA_TNIL) return -1; /* first iteration */
99 i = arrayindex(key); 104 i = arrayindex(key);
@@ -111,22 +116,23 @@ int luaH_index (lua_State *L, Table *t, const TObject *key) {
111} 116}
112 117
113 118
114int luaH_nexti (Table *t, int i, TObject *where) { 119int luaH_next (lua_State *L, Table *t, TObject *key) {
120 int i = luaH_index(L, t, key); /* find original element */
115 for (i++; i < t->sizearray; i++) { /* try first array part */ 121 for (i++; i < t->sizearray; i++) { /* try first array part */
116 if (ttype(&t->array[i]) != LUA_TNIL) { /* a non-nil value? */ 122 if (ttype(&t->array[i]) != LUA_TNIL) { /* a non-nil value? */
117 setnvalue(where, i+1); 123 setnvalue(key, i+1);
118 setobj(where+1, &t->array[i]); 124 setobj(key+1, &t->array[i]);
119 return i; 125 return 1;
120 } 126 }
121 } 127 }
122 for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ 128 for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */
123 if (ttype(val(node(t, i))) != LUA_TNIL) { /* a non-nil value? */ 129 if (ttype(val(node(t, i))) != LUA_TNIL) { /* a non-nil value? */
124 setobj(where, key(node(t, i))); 130 setobj(key, key(node(t, i)));
125 setobj(where+1, val(node(t, i))); 131 setobj(key+1, val(node(t, i)));
126 return i + t->sizearray; 132 return 1;
127 } 133 }
128 } 134 }
129 return -1; /* no more elements */ 135 return 0; /* no more elements */
130} 136}
131 137
132 138