summaryrefslogtreecommitdiff
path: root/ltable.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2021-03-29 15:47:18 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2021-03-29 15:47:18 -0300
commit7fbe2158089898f09d741e991737f282e514ffaa (patch)
tree798f3843c162f260beea1ca2c334dd76a34708eb /ltable.c
parentbf10593a3a912cd3cac69569c7474e687c0d0cd8 (diff)
downloadlua-github-7fbe2158089898f09d741e991737f282e514ffaa.tar.gz
New hash function for integer keys
When integer keys do not form a sequence, it is better to use all their bits to compute their hashes. (The previous implementation was quite bad for integer keys with common lower bits, and disastrous for integer keys changing only in their upper 32 bits.)
Diffstat (limited to 'ltable.c')
-rw-r--r--ltable.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/ltable.c b/ltable.c
index 33c1ab30..af878368 100644
--- a/ltable.c
+++ b/ltable.c
@@ -84,8 +84,6 @@
#define hashstr(t,str) hashpow2(t, (str)->hash)
#define hashboolean(t,p) hashpow2(t, p)
-#define hashint(t,i) hashpow2(t, i)
-
#define hashpointer(t,p) hashmod(t, point2uint(p))
@@ -101,6 +99,20 @@ static const Node dummynode_ = {
static const TValue absentkey = {ABSTKEYCONSTANT};
+/*
+** Hash for integers. To allow a good hash, use the remainder operator
+** ('%'). If integer fits as a non-negative int, compute an int
+** remainder, which is faster. Otherwise, use an unsigned-integer
+** remainder, which uses all bits and ensures a non-negative result.
+*/
+static Node *hashint (const Table *t, lua_Integer i) {
+ lua_Unsigned ui = l_castS2U(i);
+ if (ui <= (unsigned int)INT_MAX)
+ return hashmod(t, cast_int(ui));
+ else
+ return hashmod(t, ui);
+}
+
/*
** Hash for floating-point numbers.