summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Canciani <ranma42@gmail.com>2011-08-01 18:18:31 +0200
committerAndrea Canciani <ranma42@gmail.com>2011-08-01 19:21:31 +0200
commit02665975d3ef0204bc512de1be55f898637f2d21 (patch)
tree0f91d1900a41e050d1892c59d948c1a46ae57cbb
parentc5405f732410fe851b8d4c73365336ec2490358b (diff)
hash: Improve double hashing
Instead of artificially introducing collisions in the step value by replacing 0 with 1 (which causes the value 1 to have twice the frequency of any other value), the step value can simply be computed as an uniformly distributed value in the range [1, rehash], extremes included. This is safe because any step value smaller than the hash modulus is co-prime with it, hence induces an orbit which includes every integer in [0, table_size - 1].
-rw-r--r--src/cairo-hash.c18
1 files changed, 5 insertions, 13 deletions
diff --git a/src/cairo-hash.c b/src/cairo-hash.c
index 81a48a235..7cab89d90 100644
--- a/src/cairo-hash.c
+++ b/src/cairo-hash.c
@@ -72,7 +72,7 @@
* prime chosen to be a little more than double the high water mark for a
* given arrangement, so the tables should remain < 50% full. The table
* size makes for the "first" hash modulus; a second prime (2 less than the
- * first prime) serves as the "second" hash modulus, which is co-prime and
+ * first prime) serves as the "second" hash modulus, which is smaller and
* thus guarantees a complete permutation of table indices.
*
* This structure, and accompanying table, is borrowed/modified from the
@@ -218,9 +218,7 @@ _cairo_hash_table_lookup_unique_key (cairo_hash_table_t *hash_table,
return entry;
i = 1;
- step = key->hash % hash_table->arrangement->rehash;
- if (step == 0)
- step = 1;
+ step = 1 + key->hash % hash_table->arrangement->rehash;
do {
idx += step;
if (idx >= table_size)
@@ -324,9 +322,7 @@ _cairo_hash_table_lookup (cairo_hash_table_t *hash_table,
return NULL;
i = 1;
- step = key->hash % hash_table->arrangement->rehash;
- if (step == 0)
- step = 1;
+ step = 1 + key->hash % hash_table->arrangement->rehash;
do {
idx += step;
if (idx >= table_size)
@@ -381,9 +377,7 @@ _cairo_hash_table_random_entry (cairo_hash_table_t *hash_table,
return entry;
i = 1;
- step = hash % hash_table->arrangement->rehash;
- if (step == 0)
- step = 1;
+ step = 1 + hash % hash_table->arrangement->rehash;
do {
idx += step;
if (idx >= table_size)
@@ -455,9 +449,7 @@ _cairo_hash_table_lookup_exact_key (cairo_hash_table_t *hash_table,
return entry;
i = 1;
- step = key->hash % hash_table->arrangement->rehash;
- if (step == 0)
- step = 1;
+ step = 1 + key->hash % hash_table->arrangement->rehash;
do {
idx += step;
if (idx >= table_size)