diff options
author | Jason Ekstrand <[email protected]> | 2015-01-15 09:31:18 -0800 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2015-01-15 13:21:27 -0800 |
commit | 153b8b35257fb5d68735b5e43e48b0cdb8b15170 (patch) | |
tree | 05db6c87edc7a57a0b7b3457a35448962b4c1c76 /src/util/set.c | |
parent | 4c99e3ae78ed3524d188f00b558f803a943aaa00 (diff) |
util/hash_set: Rework the API to know about hashing
Previously, the set API required the user to do all of the hashing of keys
as it passed them in. Since the hashing function is intrinsically tied to
the comparison function, it makes sense for the hash set to know about
it. Also, it makes for a somewhat clumsy API as the user is constantly
calling hashing functions many of which have long names. This is
especially bad when the standard call looks something like
_mesa_set_add(ht, _mesa_pointer_hash(key), key);
In the above case, there is no reason why the hash set shouldn't do the
hashing for you. We leave the option for you to do your own hashing if
it's more efficient, but it's no longer needed. Also, if you do do your
own hashing, the hash set will assert that your hash matches what it
expects out of the hashing function. This should make it harder to mess up
your hashing.
This is analygous to 94303a0750 where we did this for hash_table
Signed-off-by: Jason Ekstrand <[email protected]>
Reviewed-by: Matt Turner <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src/util/set.c')
-rw-r--r-- | src/util/set.c | 47 |
1 files changed, 42 insertions, 5 deletions
diff --git a/src/util/set.c b/src/util/set.c index 3f4a4acb2ce..d170b5007bd 100644 --- a/src/util/set.c +++ b/src/util/set.c @@ -33,6 +33,7 @@ */ #include <stdlib.h> +#include <assert.h> #include "macros.h" #include "ralloc.h" @@ -103,6 +104,7 @@ entry_is_present(struct set_entry *entry) struct set * _mesa_set_create(void *mem_ctx, + uint32_t (*key_hash_function)(const void *key), bool (*key_equals_function)(const void *a, const void *b)) { @@ -116,6 +118,7 @@ _mesa_set_create(void *mem_ctx, ht->size = hash_sizes[ht->size_index].size; ht->rehash = hash_sizes[ht->size_index].rehash; ht->max_entries = hash_sizes[ht->size_index].max_entries; + ht->key_hash_function = key_hash_function; ht->key_equals_function = key_equals_function; ht->table = rzalloc_array(ht, struct set_entry, ht->size); ht->entries = 0; @@ -157,8 +160,8 @@ _mesa_set_destroy(struct set *ht, void (*delete_function)(struct set_entry *entr * * Returns NULL if no entry is found. */ -struct set_entry * -_mesa_set_search(const struct set *ht, uint32_t hash, const void *key) +static struct set_entry * +set_search(const struct set *ht, uint32_t hash, const void *key) { uint32_t hash_address; @@ -184,6 +187,25 @@ _mesa_set_search(const struct set *ht, uint32_t hash, const void *key) return NULL; } +struct set_entry * +_mesa_set_search(const struct set *set, const void *key) +{ + assert(set->key_hash_function); + return set_search(set, set->key_hash_function(key), key); +} + +struct set_entry * +_mesa_set_search_pre_hashed(const struct set *set, uint32_t hash, + const void *key) +{ + assert(set->key_hash_function == NULL || + hash == set->key_hash_function(key)); + return set_search(set, hash, key); +} + +static struct set_entry * +set_add(struct set *ht, uint32_t hash, const void *key); + static void set_rehash(struct set *ht, int new_size_index) { @@ -212,7 +234,7 @@ set_rehash(struct set *ht, int new_size_index) entry != old_ht.table + old_ht.size; entry++) { if (entry_is_present(entry)) { - _mesa_set_add(ht, entry->hash, entry->key); + set_add(ht, entry->hash, entry->key); } } @@ -225,8 +247,8 @@ set_rehash(struct set *ht, int new_size_index) * Note that insertion may rearrange the table on a resize or rehash, * so previously found hash_entries are no longer valid after this function. */ -struct set_entry * -_mesa_set_add(struct set *ht, uint32_t hash, const void *key) +static struct set_entry * +set_add(struct set *ht, uint32_t hash, const void *key) { uint32_t hash_address; @@ -277,6 +299,21 @@ _mesa_set_add(struct set *ht, uint32_t hash, const void *key) return NULL; } +struct set_entry * +_mesa_set_add(struct set *set, const void *key) +{ + assert(set->key_hash_function); + return set_add(set, set->key_hash_function(key), key); +} + +struct set_entry * +_mesa_set_add_pre_hashed(struct set *set, uint32_t hash, const void *key) +{ + assert(set->key_hash_function == NULL || + hash == set->key_hash_function(key)); + return set_add(set, hash, key); +} + /** * This function deletes the given hash table entry. * |