ENTRY(2147483648ul, 2362232233ul, 2362232231ul )
};
+static inline bool
+key_pointer_is_reserved(const struct hash_table *ht, const void *key)
+{
+ return key == NULL || key == ht->deleted_key;
+}
+
static int
entry_is_free(const struct hash_entry *entry)
{
static struct hash_entry *
hash_table_search(struct hash_table *ht, uint32_t hash, const void *key)
{
+ assert(!key_pointer_is_reserved(ht, key));
+
uint32_t size = ht->size;
uint32_t start_hash_address = util_fast_urem32(hash, size, ht->size_magic);
uint32_t double_hash = 1 + util_fast_urem32(hash, ht->rehash,
{
struct hash_entry *available_entry = NULL;
- assert(key != NULL);
+ assert(!key_pointer_is_reserved(ht, key));
if (ht->entries >= ht->max_entries) {
_mesa_hash_table_rehash(ht, ht->size_index + 1);
return aa->value == bb->value;
}
+#define FREED_KEY_VALUE 0
+
struct hash_table_u64 *
_mesa_hash_table_u64_create(void *mem_ctx)
{
+ STATIC_ASSERT(FREED_KEY_VALUE != DELETED_KEY_VALUE);
struct hash_table_u64 *ht;
ht = CALLOC_STRUCT(hash_table_u64);
}
void
-_mesa_hash_table_u64_destroy(struct hash_table_u64 *ht,
- void (*delete_function)(struct hash_entry *entry))
+_mesa_hash_table_u64_clear(struct hash_table_u64 *ht,
+ void (*delete_function)(struct hash_entry *entry))
{
if (!ht)
return;
if (ht->deleted_key_data) {
if (delete_function) {
struct hash_table *table = ht->table;
- struct hash_entry deleted_entry;
+ struct hash_entry entry;
/* Create a fake entry for the delete function. */
- deleted_entry.hash = table->key_hash_function(table->deleted_key);
- deleted_entry.key = table->deleted_key;
- deleted_entry.data = ht->deleted_key_data;
+ if (sizeof(void *) == 8) {
+ entry.hash = table->key_hash_function(table->deleted_key);
+ } else {
+ struct hash_key_u64 _key = { .value = (uintptr_t)table->deleted_key };
+ entry.hash = table->key_hash_function(&_key);
+ }
+ entry.key = table->deleted_key;
+ entry.data = ht->deleted_key_data;
- delete_function(&deleted_entry);
+ delete_function(&entry);
}
ht->deleted_key_data = NULL;
}
+ if (ht->freed_key_data) {
+ if (delete_function) {
+ struct hash_table *table = ht->table;
+ struct hash_entry entry;
+
+ /* Create a fake entry for the delete function. */
+ if (sizeof(void *) == 8) {
+ entry.hash = table->key_hash_function(uint_key(FREED_KEY_VALUE));
+ } else {
+ struct hash_key_u64 _key = { .value = (uintptr_t)FREED_KEY_VALUE };
+ entry.hash = table->key_hash_function(&_key);
+ }
+ entry.key = uint_key(FREED_KEY_VALUE);
+ entry.data = ht->freed_key_data;
+
+ delete_function(&entry);
+ }
+ ht->freed_key_data = NULL;
+ }
+
+ _mesa_hash_table_clear(ht->table, delete_function);
+}
+
+void
+_mesa_hash_table_u64_destroy(struct hash_table_u64 *ht,
+ void (*delete_function)(struct hash_entry *entry))
+{
+ if (!ht)
+ return;
+
+ _mesa_hash_table_u64_clear(ht, delete_function);
_mesa_hash_table_destroy(ht->table, delete_function);
free(ht);
}
_mesa_hash_table_u64_insert(struct hash_table_u64 *ht, uint64_t key,
void *data)
{
+ if (key == FREED_KEY_VALUE) {
+ ht->freed_key_data = data;
+ return;
+ }
+
if (key == DELETED_KEY_VALUE) {
ht->deleted_key_data = data;
return;
{
struct hash_entry *entry;
+ if (key == FREED_KEY_VALUE)
+ return ht->freed_key_data;
+
if (key == DELETED_KEY_VALUE)
return ht->deleted_key_data;
{
struct hash_entry *entry;
+ if (key == FREED_KEY_VALUE) {
+ ht->freed_key_data = NULL;
+ return;
+ }
+
if (key == DELETED_KEY_VALUE) {
ht->deleted_key_data = NULL;
return;