<div dir="ltr"><div>If people like this change, I'll do the same thing to the hash set implementation.<br></div>--Jason<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Nov 24, 2014 at 10:19 PM, Jason Ekstrand <span dir="ltr"><<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Previously, the hash_table API required the user to do all of the hashing<br>
of keys as it passed them in.  Since the hashing function is intrinsicly<br>
tied to the comparison function, it makes sense for the hash table to know<br>
about it.  Also, it makes for a somewhat clumsy API as the user is<br>
constantly calling hashing functions many of which have long names.  This<br>
is especially bad when the standard call looks something like<br>
<br>
_mesa_hash_table_insert(ht, _mesa_pointer_hash(key), key, data);<br>
<br>
In the above case, there is no reason why the hash table shouldn't do the<br>
hashing for you.  We leave the option for you to do your own hashing if<br>
it's more efficient, but it's no longer needed.  Also, if you do do your<br>
own hashing, the hash table will assert that your hash matches what it<br>
expects out of the hashing function.  This should make it harder to mess up<br>
your hashing.<br>
<br>
Signed-off-by: Jason Ekstrand <<a href="mailto:jason.ekstrand@intel.com">jason.ekstrand@intel.com</a>><br>
---<br>
 src/gallium/drivers/vc4/vc4_opt_cse.c          |  7 +--<br>
 src/glsl/ir_variable_refcount.cpp              |  9 ++--<br>
 src/glsl/link_uniform_block_active_visitor.cpp |  6 +--<br>
 src/glsl/link_uniform_blocks.cpp               |  3 +-<br>
 src/mesa/main/hash.c                           | 17 ++++--<br>
 src/util/hash_table.c                          | 75 +++++++++++++++++++-------<br>
 src/util/hash_table.h                          | 19 +++++--<br>
 src/util/tests/hash_table/collision.c          | 22 ++++----<br>
 src/util/tests/hash_table/delete_and_lookup.c  | 16 +++---<br>
 src/util/tests/hash_table/delete_management.c  |  9 ++--<br>
 src/util/tests/hash_table/destroy_callback.c   |  9 ++--<br>
 src/util/tests/hash_table/insert_and_lookup.c  | 13 +++--<br>
 src/util/tests/hash_table/insert_many.c        |  6 +--<br>
 src/util/tests/hash_table/random_entry.c       |  4 +-<br>
 src/util/tests/hash_table/remove_null.c        |  2 +-<br>
 src/util/tests/hash_table/replacement.c        | 13 +++--<br>
 16 files changed, 138 insertions(+), 92 deletions(-)<br>
<br>
diff --git a/src/gallium/drivers/vc4/vc4_opt_cse.c b/src/gallium/drivers/vc4/vc4_opt_cse.c<br>
index bebfb652..0e9335e 100644<br>
--- a/src/gallium/drivers/vc4/vc4_opt_cse.c<br>
+++ b/src/gallium/drivers/vc4/vc4_opt_cse.c<br>
@@ -84,7 +84,7 @@ vc4_find_cse(struct vc4_compile *c, struct hash_table *ht,<br>
<br>
         uint32_t hash = _mesa_hash_data(&key, sizeof(key));<br>
         struct hash_entry *entry =<br>
-                _mesa_hash_table_search(ht, hash, &key);<br>
+                _mesa_hash_table_search_with_hash(ht, hash, &key);<br>
<br>
         if (entry) {<br>
                 if (debug) {<br>
@@ -106,7 +106,7 @@ vc4_find_cse(struct vc4_compile *c, struct hash_table *ht,<br>
         if (!alloc_key)<br>
                 return NULL;<br>
         memcpy(alloc_key, &key, sizeof(*alloc_key));<br>
-        _mesa_hash_table_insert(ht, hash, alloc_key, inst);<br>
+        _mesa_hash_table_insert_with_hash(ht, hash, alloc_key, inst);<br>
<br>
         if (debug) {<br>
                 fprintf(stderr, "Added to CSE HT: ");<br>
@@ -125,7 +125,8 @@ qir_opt_cse(struct vc4_compile *c)<br>
         struct qinst *last_sf = NULL;<br>
         uint32_t sf_count = 0, r4_count = 0;<br>
<br>
-        struct hash_table *ht = _mesa_hash_table_create(NULL, inst_key_equals);<br>
+        struct hash_table *ht = _mesa_hash_table_create(NULL, NULL,<br>
+                                                        inst_key_equals);<br>
         if (!ht)<br>
                 return false;<br>
<br>
diff --git a/src/glsl/ir_variable_refcount.cpp b/src/glsl/ir_variable_refcount.cpp<br>
index f67fe67..e4d825c 100644<br>
--- a/src/glsl/ir_variable_refcount.cpp<br>
+++ b/src/glsl/ir_variable_refcount.cpp<br>
@@ -38,7 +38,8 @@<br>
 ir_variable_refcount_visitor::ir_variable_refcount_visitor()<br>
 {<br>
    this->mem_ctx = ralloc_context(NULL);<br>
-   this->ht = _mesa_hash_table_create(NULL, _mesa_key_pointer_equal);<br>
+   this->ht = _mesa_hash_table_create(NULL, _mesa_hash_pointer,<br>
+                                      _mesa_key_pointer_equal);<br>
 }<br>
<br>
 static void<br>
@@ -70,15 +71,13 @@ ir_variable_refcount_visitor::get_variable_entry(ir_variable *var)<br>
 {<br>
    assert(var);<br>
<br>
-   struct hash_entry *e = _mesa_hash_table_search(this->ht,<br>
-                                                   _mesa_hash_pointer(var),<br>
-                                                   var);<br>
+   struct hash_entry *e = _mesa_hash_table_search(this->ht, var);<br>
    if (e)<br>
       return (ir_variable_refcount_entry *)e->data;<br>
<br>
    ir_variable_refcount_entry *entry = new ir_variable_refcount_entry(var);<br>
    assert(entry->referenced_count == 0);<br>
-   _mesa_hash_table_insert(this->ht, _mesa_hash_pointer(var), var, entry);<br>
+   _mesa_hash_table_insert(this->ht, var, entry);<br>
<br>
    return entry;<br>
 }<br>
diff --git a/src/glsl/link_uniform_block_active_visitor.cpp b/src/glsl/link_uniform_block_active_visitor.cpp<br>
index 9da6a4b..292cde3 100644<br>
--- a/src/glsl/link_uniform_block_active_visitor.cpp<br>
+++ b/src/glsl/link_uniform_block_active_visitor.cpp<br>
@@ -27,9 +27,8 @@<br>
 link_uniform_block_active *<br>
 process_block(void *mem_ctx, struct hash_table *ht, ir_variable *var)<br>
 {<br>
-   const uint32_t h = _mesa_hash_string(var->get_interface_type()->name);<br>
    const hash_entry *const existing_block =<br>
-      _mesa_hash_table_search(ht, h, var->get_interface_type()->name);<br>
+      _mesa_hash_table_search(ht, var->get_interface_type()->name);<br>
<br>
    const glsl_type *const block_type = var->is_interface_instance()<br>
       ? var->type : var->get_interface_type();<br>
@@ -54,8 +53,7 @@ process_block(void *mem_ctx, struct hash_table *ht, ir_variable *var)<br>
          b->binding = 0;<br>
       }<br>
<br>
-      _mesa_hash_table_insert(ht, h, var->get_interface_type()->name,<br>
-                             (void *) b);<br>
+      _mesa_hash_table_insert(ht, var->get_interface_type()->name, (void *) b);<br>
       return b;<br>
    } else {<br>
       link_uniform_block_active *const b =<br>
diff --git a/src/glsl/link_uniform_blocks.cpp b/src/glsl/link_uniform_blocks.cpp<br>
index 536fcd4..f5fc502 100644<br>
--- a/src/glsl/link_uniform_blocks.cpp<br>
+++ b/src/glsl/link_uniform_blocks.cpp<br>
@@ -182,7 +182,8 @@ link_uniform_blocks(void *mem_ctx,<br>
     * the hash is organized by block-name.<br>
     */<br>
    struct hash_table *block_hash =<br>
-      _mesa_hash_table_create(mem_ctx, _mesa_key_string_equal);<br>
+      _mesa_hash_table_create(mem_ctx, _mesa_key_hash_string,<br>
+                              _mesa_key_string_equal);<br>
<br>
    if (block_hash == NULL) {<br>
       _mesa_error_no_memory(__func__);<br>
diff --git a/src/mesa/main/hash.c b/src/mesa/main/hash.c<br>
index 52095f7..a73d4a3 100644<br>
--- a/src/mesa/main/hash.c<br>
+++ b/src/mesa/main/hash.c<br>
@@ -96,6 +96,12 @@ uint_hash(GLuint id)<br>
    return id;<br>
 }<br>
<br>
+static uint32_t<br>
+uint_key_hash(const void *key)<br>
+{<br>
+   return uint_hash((uintptr_t)key);<br>
+}<br>
+<br>
 static void *<br>
 uint_key(GLuint id)<br>
 {<br>
@@ -114,7 +120,8 @@ _mesa_NewHashTable(void)<br>
    struct _mesa_HashTable *table = CALLOC_STRUCT(_mesa_HashTable);<br>
<br>
    if (table) {<br>
-      table->ht = _mesa_hash_table_create(NULL, uint_key_compare);<br>
+      table->ht = _mesa_hash_table_create(NULL, uint_key_hash,<br>
+                                          uint_key_compare);<br>
       if (table->ht == NULL) {<br>
          free(table);<br>
          _mesa_error_no_memory(__func__);<br>
@@ -175,7 +182,7 @@ _mesa_HashLookup_unlocked(struct _mesa_HashTable *table, GLuint key)<br>
    if (key == DELETED_KEY_VALUE)<br>
       return table->deleted_key_data;<br>
<br>
-   entry = _mesa_hash_table_search(table->ht, uint_hash(key), uint_key(key));<br>
+   entry = _mesa_hash_table_search(table->ht, uint_key(key));<br>
    if (!entry)<br>
       return NULL;<br>
<br>
@@ -266,11 +273,11 @@ _mesa_HashInsert_unlocked(struct _mesa_HashTable *table, GLuint key, void *data)<br>
    if (key == DELETED_KEY_VALUE) {<br>
       table->deleted_key_data = data;<br>
    } else {<br>
-      entry = _mesa_hash_table_search(table->ht, hash, uint_key(key));<br>
+      entry = _mesa_hash_table_search_with_hash(table->ht, hash, uint_key(key));<br>
       if (entry) {<br>
          entry->data = data;<br>
       } else {<br>
-         _mesa_hash_table_insert(table->ht, hash, uint_key(key), data);<br>
+         _mesa_hash_table_insert_with_hash(table->ht, hash, uint_key(key), data);<br>
       }<br>
    }<br>
 }<br>
@@ -340,7 +347,7 @@ _mesa_HashRemove(struct _mesa_HashTable *table, GLuint key)<br>
    if (key == DELETED_KEY_VALUE) {<br>
       table->deleted_key_data = NULL;<br>
    } else {<br>
-      entry = _mesa_hash_table_search(table->ht, uint_hash(key), uint_key(key));<br>
+      entry = _mesa_hash_table_search(table->ht, uint_key(key));<br>
       _mesa_hash_table_remove(table->ht, entry);<br>
    }<br>
    mtx_unlock(&table->Mutex);<br>
diff --git a/src/util/hash_table.c b/src/util/hash_table.c<br>
index 1b6726c..8eb96f9 100644<br>
--- a/src/util/hash_table.c<br>
+++ b/src/util/hash_table.c<br>
@@ -42,6 +42,7 @@<br>
<br>
 #include <stdlib.h><br>
 #include <string.h><br>
+#include <assert.h><br>
<br>
 #include "hash_table.h"<br>
 #include "ralloc.h"<br>
@@ -110,6 +111,7 @@ entry_is_present(const struct hash_table *ht, struct hash_entry *entry)<br>
<br>
 struct hash_table *<br>
 _mesa_hash_table_create(void *mem_ctx,<br>
+                        uint32_t (*key_hash_function)(const void *key),<br>
                         bool (*key_equals_function)(const void *a,<br>
                                                     const void *b))<br>
 {<br>
@@ -123,6 +125,7 @@ _mesa_hash_table_create(void *mem_ctx,<br>
    ht->size = hash_sizes[ht->size_index].size;<br>
    ht->rehash = hash_sizes[ht->size_index].rehash;<br>
    ht->max_entries = hash_sizes[ht->size_index].max_entries;<br>
+   ht->key_hash_function = key_hash_function;<br>
    ht->key_equals_function = key_equals_function;<br>
    ht->table = rzalloc_array(ht, struct hash_entry, ht->size);<br>
    ht->entries = 0;<br>
@@ -176,15 +179,8 @@ _mesa_hash_table_set_deleted_key(struct hash_table *ht, const void *deleted_key)<br>
    ht->deleted_key = deleted_key;<br>
 }<br>
<br>
-/**<br>
- * Finds a hash table entry with the given key and hash of that key.<br>
- *<br>
- * Returns NULL if no entry is found.  Note that the data pointer may be<br>
- * modified by the user.<br>
- */<br>
-struct hash_entry *<br>
-_mesa_hash_table_search(struct hash_table *ht, uint32_t hash,<br>
-                        const void *key)<br>
+static struct hash_entry *<br>
+hash_table_search(struct hash_table *ht, uint32_t hash, const void *key)<br>
 {<br>
    uint32_t start_hash_address = hash % ht->size;<br>
    uint32_t hash_address = start_hash_address;<br>
@@ -210,6 +206,31 @@ _mesa_hash_table_search(struct hash_table *ht, uint32_t hash,<br>
    return NULL;<br>
 }<br>
<br>
+/**<br>
+ * Finds a hash table entry with the given key and hash of that key.<br>
+ *<br>
+ * Returns NULL if no entry is found.  Note that the data pointer may be<br>
+ * modified by the user.<br>
+ */<br>
+struct hash_entry *<br>
+_mesa_hash_table_search(struct hash_table *ht, const void *key)<br>
+{<br>
+   assert(ht->key_hash_function);<br>
+   return hash_table_search(ht, ht->key_hash_function(key), key);<br>
+}<br>
+<br>
+struct hash_entry *<br>
+_mesa_hash_table_search_with_hash(struct hash_table *ht, uint32_t hash,<br>
+                                  const void *key)<br>
+{<br>
+   assert(ht->key_hash_function == NULL || hash == ht->key_hash_function(key));<br>
+   return hash_table_search(ht, hash, key);<br>
+}<br>
+<br>
+static struct hash_entry *<br>
+hash_table_insert(struct hash_table *ht, uint32_t hash,<br>
+                  const void *key, void *data);<br>
+<br>
 static void<br>
 _mesa_hash_table_rehash(struct hash_table *ht, int new_size_index)<br>
 {<br>
@@ -235,22 +256,15 @@ _mesa_hash_table_rehash(struct hash_table *ht, int new_size_index)<br>
    ht->deleted_entries = 0;<br>
<br>
    hash_table_foreach(&old_ht, entry) {<br>
-      _mesa_hash_table_insert(ht, entry->hash,<br>
-                              entry->key, entry->data);<br>
+      hash_table_insert(ht, entry->hash, entry->key, entry->data);<br>
    }<br>
<br>
    ralloc_free(old_ht.table);<br>
 }<br>
<br>
-/**<br>
- * Inserts the key with the given hash into the table.<br>
- *<br>
- * Note that insertion may rearrange the table on a resize or rehash,<br>
- * so previously found hash_entries are no longer valid after this function.<br>
- */<br>
-struct hash_entry *<br>
-_mesa_hash_table_insert(struct hash_table *ht, uint32_t hash,<br>
-                        const void *key, void *data)<br>
+static struct hash_entry *<br>
+hash_table_insert(struct hash_table *ht, uint32_t hash,<br>
+                  const void *key, void *data)<br>
 {<br>
    uint32_t start_hash_address, hash_address;<br>
<br>
@@ -307,6 +321,27 @@ _mesa_hash_table_insert(struct hash_table *ht, uint32_t hash,<br>
 }<br>
<br>
 /**<br>
+ * Inserts the key with the given hash into the table.<br>
+ *<br>
+ * Note that insertion may rearrange the table on a resize or rehash,<br>
+ * so previously found hash_entries are no longer valid after this function.<br>
+ */<br>
+struct hash_entry *<br>
+_mesa_hash_table_insert(struct hash_table *ht, const void *key, void *data)<br>
+{<br>
+   assert(ht->key_hash_function);<br>
+   hash_table_insert(ht, ht->key_hash_function(key), key, data);<br>
+}<br>
+<br>
+struct hash_entry *<br>
+_mesa_hash_table_insert_with_hash(struct hash_table *ht, uint32_t hash,<br>
+                                  const void *key, void *data)<br>
+{<br>
+   assert(ht->key_hash_function == NULL || hash == ht->key_hash_function(key));<br>
+   hash_table_insert(ht, hash, key, data);<br>
+}<br>
+<br>
+/**<br>
  * This function deletes the given hash table entry.<br>
  *<br>
  * Note that deletion doesn't otherwise modify the table, so an iteration over<br>
diff --git a/src/util/hash_table.h b/src/util/hash_table.h<br>
index d6b6ebf..a65127f 100644<br>
--- a/src/util/hash_table.h<br>
+++ b/src/util/hash_table.h<br>
@@ -46,6 +46,7 @@ struct hash_entry {<br>
<br>
 struct hash_table {<br>
    struct hash_entry *table;<br>
+   uint32_t (*key_hash_function)(const void *key);<br>
    bool (*key_equals_function)(const void *a, const void *b);<br>
    const void *deleted_key;<br>
    uint32_t size;<br>
@@ -58,6 +59,7 @@ struct hash_table {<br>
<br>
 struct hash_table *<br>
 _mesa_hash_table_create(void *mem_ctx,<br>
+                        uint32_t (*key_hash_function)(const void *key),<br>
                         bool (*key_equals_function)(const void *a,<br>
                                                     const void *b));<br>
 void _mesa_hash_table_destroy(struct hash_table *ht,<br>
@@ -66,11 +68,15 @@ void _mesa_hash_table_set_deleted_key(struct hash_table *ht,<br>
                                       const void *deleted_key);<br>
<br>
 struct hash_entry *<br>
-_mesa_hash_table_insert(struct hash_table *ht, uint32_t hash,<br>
-                        const void *key, void *data);<br>
+_mesa_hash_table_insert(struct hash_table *ht, const void *key, void *data);<br>
 struct hash_entry *<br>
-_mesa_hash_table_search(struct hash_table *ht, uint32_t hash,<br>
-                        const void *key);<br>
+_mesa_hash_table_insert_with_hash(struct hash_table *ht, uint32_t hash,<br>
+                                  const void *key, void *data);<br>
+struct hash_entry *<br>
+_mesa_hash_table_search(struct hash_table *ht, const void *key);<br>
+struct hash_entry *<br>
+_mesa_hash_table_search_with_hash(struct hash_table *ht, uint32_t hash,<br>
+                                  const void *key);<br>
 void _mesa_hash_table_remove(struct hash_table *ht,<br>
                              struct hash_entry *entry);<br>
<br>
@@ -85,6 +91,11 @@ uint32_t _mesa_hash_string(const char *key);<br>
 bool _mesa_key_string_equal(const void *a, const void *b);<br>
 bool _mesa_key_pointer_equal(const void *a, const void *b);<br>
<br>
+static inline uint32_t _mesa_key_hash_string(const void *key)<br>
+{<br>
+   return _mesa_hash_string((const char *)key);<br>
+}<br>
+<br>
 static inline uint32_t _mesa_hash_pointer(const void *pointer)<br>
 {<br>
    return _mesa_hash_data(&pointer, sizeof(pointer));<br>
diff --git a/src/util/tests/hash_table/collision.c b/src/util/tests/hash_table/collision.c<br>
index 9174c39..e73c233 100644<br>
--- a/src/util/tests/hash_table/collision.c<br>
+++ b/src/util/tests/hash_table/collision.c<br>
@@ -40,38 +40,38 @@ main(int argc, char **argv)<br>
    uint32_t bad_hash = 5;<br>
    int i;<br>
<br>
-   ht = _mesa_hash_table_create(NULL, _mesa_key_string_equal);<br>
+   ht = _mesa_hash_table_create(NULL, NULL, _mesa_key_string_equal);<br>
<br>
-   _mesa_hash_table_insert(ht, bad_hash, str1, NULL);<br>
-   _mesa_hash_table_insert(ht, bad_hash, str2, NULL);<br>
+   _mesa_hash_table_insert_with_hash(ht, bad_hash, str1, NULL);<br>
+   _mesa_hash_table_insert_with_hash(ht, bad_hash, str2, NULL);<br>
<br>
-   entry1 = _mesa_hash_table_search(ht, bad_hash, str1);<br>
+   entry1 = _mesa_hash_table_search_with_hash(ht, bad_hash, str1);<br>
    assert(entry1->key == str1);<br>
<br>
-   entry2 = _mesa_hash_table_search(ht, bad_hash, str2);<br>
+   entry2 = _mesa_hash_table_search_with_hash(ht, bad_hash, str2);<br>
    assert(entry2->key == str2);<br>
<br>
    /* Check that we can still find #1 after inserting #2 */<br>
-   entry1 = _mesa_hash_table_search(ht, bad_hash, str1);<br>
+   entry1 = _mesa_hash_table_search_with_hash(ht, bad_hash, str1);<br>
    assert(entry1->key == str1);<br>
<br>
    /* Remove the collided entry and look again. */<br>
    _mesa_hash_table_remove(ht, entry1);<br>
-   entry2 = _mesa_hash_table_search(ht, bad_hash, str2);<br>
+   entry2 = _mesa_hash_table_search_with_hash(ht, bad_hash, str2);<br>
    assert(entry2->key == str2);<br>
<br>
    /* Put str1 back, then spam junk into the table to force a<br>
     * resize and make sure we can still find them both.<br>
     */<br>
-   _mesa_hash_table_insert(ht, bad_hash, str1, NULL);<br>
+   _mesa_hash_table_insert_with_hash(ht, bad_hash, str1, NULL);<br>
    for (i = 0; i < 100; i++) {<br>
       char *key = malloc(10);<br>
       sprintf(key, "spam%d", i);<br>
-      _mesa_hash_table_insert(ht, _mesa_hash_string(key), key, NULL);<br>
+      _mesa_hash_table_insert_with_hash(ht, _mesa_hash_string(key), key, NULL);<br>
    }<br>
-   entry1 = _mesa_hash_table_search(ht, bad_hash, str1);<br>
+   entry1 = _mesa_hash_table_search_with_hash(ht, bad_hash, str1);<br>
    assert(entry1->key == str1);<br>
-   entry2 = _mesa_hash_table_search(ht, bad_hash, str2);<br>
+   entry2 = _mesa_hash_table_search_with_hash(ht, bad_hash, str2);<br>
    assert(entry2->key == str2);<br>
<br>
    _mesa_hash_table_destroy(ht, NULL);<br>
diff --git a/src/util/tests/hash_table/delete_and_lookup.c b/src/util/tests/hash_table/delete_and_lookup.c<br>
index fc886ff..be54631 100644<br>
--- a/src/util/tests/hash_table/delete_and_lookup.c<br>
+++ b/src/util/tests/hash_table/delete_and_lookup.c<br>
@@ -45,27 +45,25 @@ main(int argc, char **argv)<br>
        struct hash_table *ht;<br>
        const char *str1 = "test1";<br>
        const char *str2 = "test2";<br>
-       uint32_t hash_str1 = badhash(str1);<br>
-       uint32_t hash_str2 = badhash(str2);<br>
        struct hash_entry *entry;<br>
<br>
-       ht = _mesa_hash_table_create(NULL, _mesa_key_string_equal);<br>
+       ht = _mesa_hash_table_create(NULL, badhash, _mesa_key_string_equal);<br>
<br>
-       _mesa_hash_table_insert(ht, hash_str1, str1, NULL);<br>
-       _mesa_hash_table_insert(ht, hash_str2, str2, NULL);<br>
+       _mesa_hash_table_insert(ht, str1, NULL);<br>
+       _mesa_hash_table_insert(ht, str2, NULL);<br>
<br>
-       entry = _mesa_hash_table_search(ht, hash_str2, str2);<br>
+       entry = _mesa_hash_table_search(ht, str2);<br>
        assert(strcmp(entry->key, str2) == 0);<br>
<br>
-       entry = _mesa_hash_table_search(ht, hash_str1, str1);<br>
+       entry = _mesa_hash_table_search(ht, str1);<br>
        assert(strcmp(entry->key, str1) == 0);<br>
<br>
        _mesa_hash_table_remove(ht, entry);<br>
<br>
-       entry = _mesa_hash_table_search(ht, hash_str1, str1);<br>
+       entry = _mesa_hash_table_search(ht, str1);<br>
        assert(entry == NULL);<br>
<br>
-       entry = _mesa_hash_table_search(ht, hash_str2, str2);<br>
+       entry = _mesa_hash_table_search(ht, str2);<br>
        assert(strcmp(entry->key, str2) == 0);<br>
<br>
        _mesa_hash_table_destroy(ht, NULL);<br>
diff --git a/src/util/tests/hash_table/delete_management.c b/src/util/tests/hash_table/delete_management.c<br>
index b8d7640..0a6bec3 100644<br>
--- a/src/util/tests/hash_table/delete_management.c<br>
+++ b/src/util/tests/hash_table/delete_management.c<br>
@@ -51,24 +51,23 @@ main(int argc, char **argv)<br>
    uint32_t keys[size];<br>
    uint32_t i;<br>
<br>
-   ht = _mesa_hash_table_create(NULL, uint32_t_key_equals);<br>
+   ht = _mesa_hash_table_create(NULL, key_value, uint32_t_key_equals);<br>
<br>
    for (i = 0; i < size; i++) {<br>
       keys[i] = i;<br>
<br>
-      _mesa_hash_table_insert(ht, i, keys + i, NULL);<br>
+      _mesa_hash_table_insert(ht, keys + i, NULL);<br>
<br>
       if (i >= 100) {<br>
          uint32_t delete_value = i - 100;<br>
-         entry = _mesa_hash_table_search(ht, delete_value,<br>
-                                              &delete_value);<br>
+         entry = _mesa_hash_table_search(ht, &delete_value);<br>
          _mesa_hash_table_remove(ht, entry);<br>
       }<br>
    }<br>
<br>
    /* Make sure that all our entries were present at the end. */<br>
    for (i = size - 100; i < size; i++) {<br>
-      entry = _mesa_hash_table_search(ht, i, keys + i);<br>
+      entry = _mesa_hash_table_search(ht, keys + i);<br>
       assert(entry);<br>
       assert(key_value(entry->key) == i);<br>
    }<br>
diff --git a/src/util/tests/hash_table/destroy_callback.c b/src/util/tests/hash_table/destroy_callback.c<br>
index dce2b33..79b4fda 100644<br>
--- a/src/util/tests/hash_table/destroy_callback.c<br>
+++ b/src/util/tests/hash_table/destroy_callback.c<br>
@@ -50,13 +50,12 @@ int<br>
 main(int argc, char **argv)<br>
 {<br>
    struct hash_table *ht;<br>
-   uint32_t hash_str1 = _mesa_hash_string(str1);<br>
-   uint32_t hash_str2 = _mesa_hash_string(str2);<br>
<br>
-   ht = _mesa_hash_table_create(NULL, _mesa_key_string_equal);<br>
+   ht = _mesa_hash_table_create(NULL, _mesa_key_hash_string,<br>
+                                _mesa_key_string_equal);<br>
<br>
-   _mesa_hash_table_insert(ht, hash_str1, str1, NULL);<br>
-   _mesa_hash_table_insert(ht, hash_str2, str2, NULL);<br>
+   _mesa_hash_table_insert(ht, str1, NULL);<br>
+   _mesa_hash_table_insert(ht, str2, NULL);<br>
<br>
    _mesa_hash_table_destroy(ht, delete_callback);<br>
<br>
diff --git a/src/util/tests/hash_table/insert_and_lookup.c b/src/util/tests/hash_table/insert_and_lookup.c<br>
index 402f3fd..0705b07 100644<br>
--- a/src/util/tests/hash_table/insert_and_lookup.c<br>
+++ b/src/util/tests/hash_table/insert_and_lookup.c<br>
@@ -36,19 +36,18 @@ main(int argc, char **argv)<br>
    struct hash_table *ht;<br>
    const char *str1 = "test1";<br>
    const char *str2 = "test2";<br>
-   uint32_t hash_str1 = _mesa_hash_string(str1);<br>
-   uint32_t hash_str2 = _mesa_hash_string(str2);<br>
    struct hash_entry *entry;<br>
<br>
-   ht = _mesa_hash_table_create(NULL, _mesa_key_string_equal);<br>
+   ht = _mesa_hash_table_create(NULL, _mesa_key_hash_string,<br>
+                                _mesa_key_string_equal);<br>
<br>
-   _mesa_hash_table_insert(ht, hash_str1, str1, NULL);<br>
-   _mesa_hash_table_insert(ht, hash_str2, str2, NULL);<br>
+   _mesa_hash_table_insert(ht, str1, NULL);<br>
+   _mesa_hash_table_insert(ht, str2, NULL);<br>
<br>
-   entry = _mesa_hash_table_search(ht, hash_str1, str1);<br>
+   entry = _mesa_hash_table_search(ht, str1);<br>
    assert(strcmp(entry->key, str1) == 0);<br>
<br>
-   entry = _mesa_hash_table_search(ht, hash_str2, str2);<br>
+   entry = _mesa_hash_table_search(ht, str2);<br>
    assert(strcmp(entry->key, str2) == 0);<br>
<br>
    _mesa_hash_table_destroy(ht, NULL);<br>
diff --git a/src/util/tests/hash_table/insert_many.c b/src/util/tests/hash_table/insert_many.c<br>
index b2122dc..c6c0591 100644<br>
--- a/src/util/tests/hash_table/insert_many.c<br>
+++ b/src/util/tests/hash_table/insert_many.c<br>
@@ -51,16 +51,16 @@ main(int argc, char **argv)<br>
    uint32_t keys[size];<br>
    uint32_t i;<br>
<br>
-   ht = _mesa_hash_table_create(NULL, uint32_t_key_equals);<br>
+   ht = _mesa_hash_table_create(NULL, key_value, uint32_t_key_equals);<br>
<br>
    for (i = 0; i < size; i++) {<br>
       keys[i] = i;<br>
<br>
-      _mesa_hash_table_insert(ht, i, keys + i, NULL);<br>
+      _mesa_hash_table_insert(ht, keys + i, NULL);<br>
    }<br>
<br>
    for (i = 0; i < size; i++) {<br>
-      entry = _mesa_hash_table_search(ht, i, keys + i);<br>
+      entry = _mesa_hash_table_search(ht, keys + i);<br>
       assert(entry);<br>
       assert(key_value(entry->key) == i);<br>
    }<br>
diff --git a/src/util/tests/hash_table/random_entry.c b/src/util/tests/hash_table/random_entry.c<br>
index 22cafa7..4a79181 100644<br>
--- a/src/util/tests/hash_table/random_entry.c<br>
+++ b/src/util/tests/hash_table/random_entry.c<br>
@@ -57,12 +57,12 @@ main(int argc, char **argv)<br>
    uint32_t keys[size];<br>
    uint32_t i, random_value;<br>
<br>
-   ht = _mesa_hash_table_create(NULL, uint32_t_key_equals);<br>
+   ht = _mesa_hash_table_create(NULL, key_value, uint32_t_key_equals);<br>
<br>
    for (i = 0; i < size; i++) {<br>
       keys[i] = i;<br>
<br>
-      _mesa_hash_table_insert(ht, i, keys + i, NULL);<br>
+      _mesa_hash_table_insert(ht, keys + i, NULL);<br>
    }<br>
<br>
    /* Test the no-predicate case. */<br>
diff --git a/src/util/tests/hash_table/remove_null.c b/src/util/tests/hash_table/remove_null.c<br>
index 90fb784..7042f5e 100644<br>
--- a/src/util/tests/hash_table/remove_null.c<br>
+++ b/src/util/tests/hash_table/remove_null.c<br>
@@ -35,7 +35,7 @@ main(int argc, char **argv)<br>
 {<br>
    struct hash_table *ht;<br>
<br>
-   ht = _mesa_hash_table_create(NULL, _mesa_key_string_equal);<br>
+   ht = _mesa_hash_table_create(NULL, NULL, _mesa_key_string_equal);<br>
<br>
    _mesa_hash_table_remove(ht, NULL);<br>
<br>
diff --git a/src/util/tests/hash_table/replacement.c b/src/util/tests/hash_table/replacement.c<br>
index 387cfc0..01ede68 100644<br>
--- a/src/util/tests/hash_table/replacement.c<br>
+++ b/src/util/tests/hash_table/replacement.c<br>
@@ -36,24 +36,23 @@ main(int argc, char **argv)<br>
    struct hash_table *ht;<br>
    char *str1 = strdup("test1");<br>
    char *str2 = strdup("test1");<br>
-   uint32_t hash_str1 = _mesa_hash_string(str1);<br>
-   uint32_t hash_str2 = _mesa_hash_string(str2);<br>
    struct hash_entry *entry;<br>
<br>
    assert(str1 != str2);<br>
<br>
-   ht = _mesa_hash_table_create(NULL, _mesa_key_string_equal);<br>
+   ht = _mesa_hash_table_create(NULL, _mesa_key_hash_string,<br>
+                                _mesa_key_string_equal);<br>
<br>
-   _mesa_hash_table_insert(ht, hash_str1, str1, str1);<br>
-   _mesa_hash_table_insert(ht, hash_str2, str2, str2);<br>
+   _mesa_hash_table_insert(ht, str1, str1);<br>
+   _mesa_hash_table_insert(ht, str2, str2);<br>
<br>
-   entry = _mesa_hash_table_search(ht, hash_str1, str1);<br>
+   entry = _mesa_hash_table_search(ht, str1);<br>
    assert(entry);<br>
    assert(entry->data == str2);<br>
<br>
    _mesa_hash_table_remove(ht, entry);<br>
<br>
-   entry = _mesa_hash_table_search(ht, hash_str1, str1);<br>
+   entry = _mesa_hash_table_search(ht, str1);<br>
    assert(!entry);<br>
<br>
    _mesa_hash_table_destroy(ht, NULL);<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.1.0<br>
<br>
</font></span></blockquote></div><br></div>