uint32_t hash = _mesa_hash_data(&key, sizeof(key));
struct hash_entry *entry =
- _mesa_hash_table_search(ht, hash, &key);
+ _mesa_hash_table_search_pre_hashed(ht, hash, &key);
if (entry) {
if (debug) {
if (!alloc_key)
return NULL;
memcpy(alloc_key, &key, sizeof(*alloc_key));
- _mesa_hash_table_insert(ht, hash, alloc_key, inst);
+ _mesa_hash_table_insert_with_hash(ht, hash, alloc_key, inst);
if (debug) {
fprintf(stderr, "Added to CSE HT: ");
struct qinst *last_sf = NULL;
uint32_t sf_count = 0, r4_count = 0;
- struct hash_table *ht = _mesa_hash_table_create(NULL, inst_key_equals);
+ struct hash_table *ht = _mesa_hash_table_create(NULL, NULL,
+ inst_key_equals);
if (!ht)
return false;
ir_variable_refcount_visitor::ir_variable_refcount_visitor()
{
this->mem_ctx = ralloc_context(NULL);
- this->ht = _mesa_hash_table_create(NULL, _mesa_key_pointer_equal);
+ this->ht = _mesa_hash_table_create(NULL, _mesa_hash_pointer,
+ _mesa_key_pointer_equal);
}
static void
{
assert(var);
- struct hash_entry *e = _mesa_hash_table_search(this->ht,
- _mesa_hash_pointer(var),
- var);
+ struct hash_entry *e = _mesa_hash_table_search(this->ht, var);
if (e)
return (ir_variable_refcount_entry *)e->data;
ir_variable_refcount_entry *entry = new ir_variable_refcount_entry(var);
assert(entry->referenced_count == 0);
- _mesa_hash_table_insert(this->ht, _mesa_hash_pointer(var), var, entry);
+ _mesa_hash_table_insert(this->ht, var, entry);
return entry;
}
link_uniform_block_active *
process_block(void *mem_ctx, struct hash_table *ht, ir_variable *var)
{
- const uint32_t h = _mesa_hash_string(var->get_interface_type()->name);
const hash_entry *const existing_block =
- _mesa_hash_table_search(ht, h, var->get_interface_type()->name);
+ _mesa_hash_table_search(ht, var->get_interface_type()->name);
const glsl_type *const block_type = var->is_interface_instance()
? var->type : var->get_interface_type();
b->binding = 0;
}
- _mesa_hash_table_insert(ht, h, var->get_interface_type()->name,
- (void *) b);
+ _mesa_hash_table_insert(ht, var->get_interface_type()->name, (void *) b);
return b;
} else {
link_uniform_block_active *const b =
* the hash is organized by block-name.
*/
struct hash_table *block_hash =
- _mesa_hash_table_create(mem_ctx, _mesa_key_string_equal);
+ _mesa_hash_table_create(mem_ctx, _mesa_key_hash_string,
+ _mesa_key_string_equal);
if (block_hash == NULL) {
_mesa_error_no_memory(__func__);
return id;
}
+static uint32_t
+uint_key_hash(const void *key)
+{
+ return uint_hash((uintptr_t)key);
+}
+
static void *
uint_key(GLuint id)
{
struct _mesa_HashTable *table = CALLOC_STRUCT(_mesa_HashTable);
if (table) {
- table->ht = _mesa_hash_table_create(NULL, uint_key_compare);
+ table->ht = _mesa_hash_table_create(NULL, uint_key_hash,
+ uint_key_compare);
if (table->ht == NULL) {
free(table);
_mesa_error_no_memory(__func__);
if (key == DELETED_KEY_VALUE)
return table->deleted_key_data;
- entry = _mesa_hash_table_search(table->ht, uint_hash(key), uint_key(key));
+ entry = _mesa_hash_table_search(table->ht, uint_key(key));
if (!entry)
return NULL;
if (key == DELETED_KEY_VALUE) {
table->deleted_key_data = data;
} else {
- entry = _mesa_hash_table_search(table->ht, hash, uint_key(key));
+ entry = _mesa_hash_table_search_pre_hashed(table->ht, hash, uint_key(key));
if (entry) {
entry->data = data;
} else {
- _mesa_hash_table_insert(table->ht, hash, uint_key(key), data);
+ _mesa_hash_table_insert_with_hash(table->ht, hash, uint_key(key), data);
}
}
}
if (key == DELETED_KEY_VALUE) {
table->deleted_key_data = NULL;
} else {
- entry = _mesa_hash_table_search(table->ht, uint_hash(key), uint_key(key));
+ entry = _mesa_hash_table_search(table->ht, uint_key(key));
_mesa_hash_table_remove(table->ht, entry);
}
mtx_unlock(&table->Mutex);
#include <stdlib.h>
#include <string.h>
+#include <assert.h>
#include "hash_table.h"
#include "ralloc.h"
struct hash_table *
_mesa_hash_table_create(void *mem_ctx,
+ uint32_t (*key_hash_function)(const void *key),
bool (*key_equals_function)(const void *a,
const void *b))
{
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 hash_entry, ht->size);
ht->entries = 0;
ht->deleted_key = deleted_key;
}
-/**
- * Finds a hash table entry with the given key and hash of that key.
- *
- * Returns NULL if no entry is found. Note that the data pointer may be
- * modified by the user.
- */
-struct hash_entry *
-_mesa_hash_table_search(struct hash_table *ht, uint32_t hash,
- const void *key)
+static struct hash_entry *
+hash_table_search(struct hash_table *ht, uint32_t hash, const void *key)
{
uint32_t start_hash_address = hash % ht->size;
uint32_t hash_address = start_hash_address;
return NULL;
}
+/**
+ * Finds a hash table entry with the given key and hash of that key.
+ *
+ * Returns NULL if no entry is found. Note that the data pointer may be
+ * modified by the user.
+ */
+struct hash_entry *
+_mesa_hash_table_search(struct hash_table *ht, const void *key)
+{
+ assert(ht->key_hash_function);
+ return hash_table_search(ht, ht->key_hash_function(key), key);
+}
+
+struct hash_entry *
+_mesa_hash_table_search_pre_hashed(struct hash_table *ht, uint32_t hash,
+ const void *key)
+{
+ assert(ht->key_hash_function == NULL || hash == ht->key_hash_function(key));
+ return hash_table_search(ht, hash, key);
+}
+
+static struct hash_entry *
+hash_table_insert(struct hash_table *ht, uint32_t hash,
+ const void *key, void *data);
+
static void
_mesa_hash_table_rehash(struct hash_table *ht, int new_size_index)
{
ht->deleted_entries = 0;
hash_table_foreach(&old_ht, entry) {
- _mesa_hash_table_insert(ht, entry->hash,
- entry->key, entry->data);
+ hash_table_insert(ht, entry->hash, entry->key, entry->data);
}
ralloc_free(old_ht.table);
}
-/**
- * Inserts the key with the given hash into the table.
- *
- * 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 hash_entry *
-_mesa_hash_table_insert(struct hash_table *ht, uint32_t hash,
- const void *key, void *data)
+static struct hash_entry *
+hash_table_insert(struct hash_table *ht, uint32_t hash,
+ const void *key, void *data)
{
uint32_t start_hash_address, hash_address;
return NULL;
}
+/**
+ * Inserts the key with the given hash into the table.
+ *
+ * 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 hash_entry *
+_mesa_hash_table_insert(struct hash_table *ht, const void *key, void *data)
+{
+ assert(ht->key_hash_function);
+ hash_table_insert(ht, ht->key_hash_function(key), key, data);
+}
+
+struct hash_entry *
+_mesa_hash_table_insert_with_hash(struct hash_table *ht, uint32_t hash,
+ const void *key, void *data)
+{
+ assert(ht->key_hash_function == NULL || hash == ht->key_hash_function(key));
+ hash_table_insert(ht, hash, key, data);
+}
+
/**
* This function deletes the given hash table entry.
*
struct hash_table {
struct hash_entry *table;
+ uint32_t (*key_hash_function)(const void *key);
bool (*key_equals_function)(const void *a, const void *b);
const void *deleted_key;
uint32_t size;
struct hash_table *
_mesa_hash_table_create(void *mem_ctx,
+ uint32_t (*key_hash_function)(const void *key),
bool (*key_equals_function)(const void *a,
const void *b));
void _mesa_hash_table_destroy(struct hash_table *ht,
const void *deleted_key);
struct hash_entry *
-_mesa_hash_table_insert(struct hash_table *ht, uint32_t hash,
- const void *key, void *data);
+_mesa_hash_table_insert(struct hash_table *ht, const void *key, void *data);
struct hash_entry *
-_mesa_hash_table_search(struct hash_table *ht, uint32_t hash,
- const void *key);
+_mesa_hash_table_insert_with_hash(struct hash_table *ht, uint32_t hash,
+ const void *key, void *data);
+struct hash_entry *
+_mesa_hash_table_search(struct hash_table *ht, const void *key);
+struct hash_entry *
+_mesa_hash_table_search_pre_hashed(struct hash_table *ht, uint32_t hash,
+ const void *key);
void _mesa_hash_table_remove(struct hash_table *ht,
struct hash_entry *entry);
bool _mesa_key_string_equal(const void *a, const void *b);
bool _mesa_key_pointer_equal(const void *a, const void *b);
+static inline uint32_t _mesa_key_hash_string(const void *key)
+{
+ return _mesa_hash_string((const char *)key);
+}
+
static inline uint32_t _mesa_hash_pointer(const void *pointer)
{
return _mesa_hash_data(&pointer, sizeof(pointer));
uint32_t bad_hash = 5;
int i;
- ht = _mesa_hash_table_create(NULL, _mesa_key_string_equal);
+ ht = _mesa_hash_table_create(NULL, NULL, _mesa_key_string_equal);
- _mesa_hash_table_insert(ht, bad_hash, str1, NULL);
- _mesa_hash_table_insert(ht, bad_hash, str2, NULL);
+ _mesa_hash_table_insert_with_hash(ht, bad_hash, str1, NULL);
+ _mesa_hash_table_insert_with_hash(ht, bad_hash, str2, NULL);
- entry1 = _mesa_hash_table_search(ht, bad_hash, str1);
+ entry1 = _mesa_hash_table_search_pre_hashed(ht, bad_hash, str1);
assert(entry1->key == str1);
- entry2 = _mesa_hash_table_search(ht, bad_hash, str2);
+ entry2 = _mesa_hash_table_search_pre_hashed(ht, bad_hash, str2);
assert(entry2->key == str2);
/* Check that we can still find #1 after inserting #2 */
- entry1 = _mesa_hash_table_search(ht, bad_hash, str1);
+ entry1 = _mesa_hash_table_search_pre_hashed(ht, bad_hash, str1);
assert(entry1->key == str1);
/* Remove the collided entry and look again. */
_mesa_hash_table_remove(ht, entry1);
- entry2 = _mesa_hash_table_search(ht, bad_hash, str2);
+ entry2 = _mesa_hash_table_search_pre_hashed(ht, bad_hash, str2);
assert(entry2->key == str2);
/* Put str1 back, then spam junk into the table to force a
* resize and make sure we can still find them both.
*/
- _mesa_hash_table_insert(ht, bad_hash, str1, NULL);
+ _mesa_hash_table_insert_with_hash(ht, bad_hash, str1, NULL);
for (i = 0; i < 100; i++) {
char *key = malloc(10);
sprintf(key, "spam%d", i);
- _mesa_hash_table_insert(ht, _mesa_hash_string(key), key, NULL);
+ _mesa_hash_table_insert_with_hash(ht, _mesa_hash_string(key), key, NULL);
}
- entry1 = _mesa_hash_table_search(ht, bad_hash, str1);
+ entry1 = _mesa_hash_table_search_pre_hashed(ht, bad_hash, str1);
assert(entry1->key == str1);
- entry2 = _mesa_hash_table_search(ht, bad_hash, str2);
+ entry2 = _mesa_hash_table_search_pre_hashed(ht, bad_hash, str2);
assert(entry2->key == str2);
_mesa_hash_table_destroy(ht, NULL);
struct hash_table *ht;
const char *str1 = "test1";
const char *str2 = "test2";
- uint32_t hash_str1 = badhash(str1);
- uint32_t hash_str2 = badhash(str2);
struct hash_entry *entry;
- ht = _mesa_hash_table_create(NULL, _mesa_key_string_equal);
+ ht = _mesa_hash_table_create(NULL, badhash, _mesa_key_string_equal);
- _mesa_hash_table_insert(ht, hash_str1, str1, NULL);
- _mesa_hash_table_insert(ht, hash_str2, str2, NULL);
+ _mesa_hash_table_insert(ht, str1, NULL);
+ _mesa_hash_table_insert(ht, str2, NULL);
- entry = _mesa_hash_table_search(ht, hash_str2, str2);
+ entry = _mesa_hash_table_search(ht, str2);
assert(strcmp(entry->key, str2) == 0);
- entry = _mesa_hash_table_search(ht, hash_str1, str1);
+ entry = _mesa_hash_table_search(ht, str1);
assert(strcmp(entry->key, str1) == 0);
_mesa_hash_table_remove(ht, entry);
- entry = _mesa_hash_table_search(ht, hash_str1, str1);
+ entry = _mesa_hash_table_search(ht, str1);
assert(entry == NULL);
- entry = _mesa_hash_table_search(ht, hash_str2, str2);
+ entry = _mesa_hash_table_search(ht, str2);
assert(strcmp(entry->key, str2) == 0);
_mesa_hash_table_destroy(ht, NULL);
uint32_t keys[size];
uint32_t i;
- ht = _mesa_hash_table_create(NULL, uint32_t_key_equals);
+ ht = _mesa_hash_table_create(NULL, key_value, uint32_t_key_equals);
for (i = 0; i < size; i++) {
keys[i] = i;
- _mesa_hash_table_insert(ht, i, keys + i, NULL);
+ _mesa_hash_table_insert(ht, keys + i, NULL);
if (i >= 100) {
uint32_t delete_value = i - 100;
- entry = _mesa_hash_table_search(ht, delete_value,
- &delete_value);
+ entry = _mesa_hash_table_search(ht, &delete_value);
_mesa_hash_table_remove(ht, entry);
}
}
/* Make sure that all our entries were present at the end. */
for (i = size - 100; i < size; i++) {
- entry = _mesa_hash_table_search(ht, i, keys + i);
+ entry = _mesa_hash_table_search(ht, keys + i);
assert(entry);
assert(key_value(entry->key) == i);
}
main(int argc, char **argv)
{
struct hash_table *ht;
- uint32_t hash_str1 = _mesa_hash_string(str1);
- uint32_t hash_str2 = _mesa_hash_string(str2);
- ht = _mesa_hash_table_create(NULL, _mesa_key_string_equal);
+ ht = _mesa_hash_table_create(NULL, _mesa_key_hash_string,
+ _mesa_key_string_equal);
- _mesa_hash_table_insert(ht, hash_str1, str1, NULL);
- _mesa_hash_table_insert(ht, hash_str2, str2, NULL);
+ _mesa_hash_table_insert(ht, str1, NULL);
+ _mesa_hash_table_insert(ht, str2, NULL);
_mesa_hash_table_destroy(ht, delete_callback);
struct hash_table *ht;
const char *str1 = "test1";
const char *str2 = "test2";
- uint32_t hash_str1 = _mesa_hash_string(str1);
- uint32_t hash_str2 = _mesa_hash_string(str2);
struct hash_entry *entry;
- ht = _mesa_hash_table_create(NULL, _mesa_key_string_equal);
+ ht = _mesa_hash_table_create(NULL, _mesa_key_hash_string,
+ _mesa_key_string_equal);
- _mesa_hash_table_insert(ht, hash_str1, str1, NULL);
- _mesa_hash_table_insert(ht, hash_str2, str2, NULL);
+ _mesa_hash_table_insert(ht, str1, NULL);
+ _mesa_hash_table_insert(ht, str2, NULL);
- entry = _mesa_hash_table_search(ht, hash_str1, str1);
+ entry = _mesa_hash_table_search(ht, str1);
assert(strcmp(entry->key, str1) == 0);
- entry = _mesa_hash_table_search(ht, hash_str2, str2);
+ entry = _mesa_hash_table_search(ht, str2);
assert(strcmp(entry->key, str2) == 0);
_mesa_hash_table_destroy(ht, NULL);
uint32_t keys[size];
uint32_t i;
- ht = _mesa_hash_table_create(NULL, uint32_t_key_equals);
+ ht = _mesa_hash_table_create(NULL, key_value, uint32_t_key_equals);
for (i = 0; i < size; i++) {
keys[i] = i;
- _mesa_hash_table_insert(ht, i, keys + i, NULL);
+ _mesa_hash_table_insert(ht, keys + i, NULL);
}
for (i = 0; i < size; i++) {
- entry = _mesa_hash_table_search(ht, i, keys + i);
+ entry = _mesa_hash_table_search(ht, keys + i);
assert(entry);
assert(key_value(entry->key) == i);
}
uint32_t keys[size];
uint32_t i, random_value;
- ht = _mesa_hash_table_create(NULL, uint32_t_key_equals);
+ ht = _mesa_hash_table_create(NULL, key_value, uint32_t_key_equals);
for (i = 0; i < size; i++) {
keys[i] = i;
- _mesa_hash_table_insert(ht, i, keys + i, NULL);
+ _mesa_hash_table_insert(ht, keys + i, NULL);
}
/* Test the no-predicate case. */
{
struct hash_table *ht;
- ht = _mesa_hash_table_create(NULL, _mesa_key_string_equal);
+ ht = _mesa_hash_table_create(NULL, NULL, _mesa_key_string_equal);
_mesa_hash_table_remove(ht, NULL);
struct hash_table *ht;
char *str1 = strdup("test1");
char *str2 = strdup("test1");
- uint32_t hash_str1 = _mesa_hash_string(str1);
- uint32_t hash_str2 = _mesa_hash_string(str2);
struct hash_entry *entry;
assert(str1 != str2);
- ht = _mesa_hash_table_create(NULL, _mesa_key_string_equal);
+ ht = _mesa_hash_table_create(NULL, _mesa_key_hash_string,
+ _mesa_key_string_equal);
- _mesa_hash_table_insert(ht, hash_str1, str1, str1);
- _mesa_hash_table_insert(ht, hash_str2, str2, str2);
+ _mesa_hash_table_insert(ht, str1, str1);
+ _mesa_hash_table_insert(ht, str2, str2);
- entry = _mesa_hash_table_search(ht, hash_str1, str1);
+ entry = _mesa_hash_table_search(ht, str1);
assert(entry);
assert(entry->data == str2);
_mesa_hash_table_remove(ht, entry);
- entry = _mesa_hash_table_search(ht, hash_str1, str1);
+ entry = _mesa_hash_table_search(ht, str1);
assert(!entry);
_mesa_hash_table_destroy(ht, NULL);