aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-03-24 11:18:42 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-03-24 11:18:42 -0300
commitb858161fbcd3992e91c1e555ca7797ec8bec3f84 (patch)
tree8c885b22a4154af416a4d66bd7b21922065c4357
parent80bac182db4bba6fc0dcfdb0d4d6abe4183083d1 (diff)
downloadlua-b858161fbcd3992e91c1e555ca7797ec8bec3f84.tar.gz
lua-b858161fbcd3992e91c1e555ca7797ec8bec3f84.tar.bz2
lua-b858161fbcd3992e91c1e555ca7797ec8bec3f84.zip
new hash method for lua_Number (double) (due to a performance problem)
-rw-r--r--ltable.c53
1 files changed, 38 insertions, 15 deletions
diff --git a/ltable.c b/ltable.c
index db04faaf..bba96497 100644
--- a/ltable.c
+++ b/ltable.c
@@ -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)))) 83static 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*/
74Node *luaH_mainposition (const Table *t, const TObject *key) { 99Node *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);