mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-06 08:50:09 +01:00
util/hash_table: add u64 foreach macro
needs some nontrivial wrapping but can mostly fallback to the regular impl. Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Reviewed-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27762>
This commit is contained in:
parent
cc1501628f
commit
d964f57a48
3 changed files with 69 additions and 0 deletions
|
|
@ -57,6 +57,7 @@ ForEachMacros:
|
|||
|
||||
- hash_table_foreach
|
||||
- hash_table_foreach_remove
|
||||
- hash_table_u64_foreach
|
||||
|
||||
- rb_tree_foreach
|
||||
- rb_tree_foreach_rev
|
||||
|
|
|
|||
|
|
@ -960,3 +960,49 @@ _mesa_hash_table_u64_remove(struct hash_table_u64 *ht, uint64_t key)
|
|||
FREE(_key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Iterates in order ("freed key", "deleted key", regular entries...)
|
||||
*/
|
||||
struct hash_entry_u64
|
||||
_mesa_hash_table_u64_next_entry(struct hash_table_u64 *ht,
|
||||
struct hash_entry_u64 *ent)
|
||||
{
|
||||
/* First entry: freed key */
|
||||
if (!ent && ht->freed_key_data) {
|
||||
return (struct hash_entry_u64){
|
||||
.key = FREED_KEY_VALUE,
|
||||
.data = ht->freed_key_data,
|
||||
};
|
||||
}
|
||||
|
||||
/* Second entry: deleted key */
|
||||
if ((!ent || ent->key == FREED_KEY_VALUE) && ht->deleted_key_data) {
|
||||
return (struct hash_entry_u64){
|
||||
.key = DELETED_KEY_VALUE,
|
||||
.data = ht->deleted_key_data,
|
||||
};
|
||||
}
|
||||
|
||||
/* All other entries: regular */
|
||||
struct hash_entry *next =
|
||||
_mesa_hash_table_next_entry(ht->table, ent ? ent->_entry : NULL);
|
||||
|
||||
if (!next)
|
||||
return (struct hash_entry_u64){.data = NULL};
|
||||
|
||||
uint64_t key;
|
||||
if (sizeof(void *) == 8) {
|
||||
key = (uintptr_t)next->key;
|
||||
} else {
|
||||
const struct hash_key_u64 *_key = next->key;
|
||||
key = _key->value;
|
||||
}
|
||||
|
||||
return (struct hash_entry_u64){
|
||||
.key = key,
|
||||
.data = next->data,
|
||||
._entry = next,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,6 +171,12 @@ struct hash_table_u64 {
|
|||
void *deleted_key_data;
|
||||
};
|
||||
|
||||
struct hash_entry_u64 {
|
||||
uint64_t key;
|
||||
void *data;
|
||||
struct hash_entry *_entry;
|
||||
};
|
||||
|
||||
struct hash_table_u64 *
|
||||
_mesa_hash_table_u64_create(void *mem_ctx);
|
||||
|
||||
|
|
@ -190,6 +196,22 @@ _mesa_hash_table_u64_remove(struct hash_table_u64 *ht, uint64_t key);
|
|||
void
|
||||
_mesa_hash_table_u64_clear(struct hash_table_u64 *ht);
|
||||
|
||||
struct hash_entry_u64
|
||||
_mesa_hash_table_u64_next_entry(struct hash_table_u64 *ht,
|
||||
struct hash_entry_u64 *ent);
|
||||
|
||||
/**
|
||||
* This foreach function is safe against deletion (which just replaces
|
||||
* an entry's data with the deleted marker), but not against insertion
|
||||
* (which may rehash the table, making entry a dangling pointer).
|
||||
*/
|
||||
#define hash_table_u64_foreach(ht, entry) \
|
||||
for (struct hash_entry_u64 entry = \
|
||||
_mesa_hash_table_u64_next_entry(ht, NULL); \
|
||||
entry.data != NULL; \
|
||||
entry = _mesa_hash_table_u64_next_entry(ht, &entry))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern C */
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue