Re: [Mesa-dev] [PATCH] mesa/util: add a hash table wrapper which support 64-bit keys
On 06/13/2017 06:07 PM, Nicolai Hähnle wrote: On 13.06.2017 14:01, Grazvydas Ignotas wrote: On Tue, Jun 13, 2017 at 10:58 AM, Samuel Pitoiset wrote: Needed for bindless handles which are represented using 64-bit unsigned integers. All hash table implementations should be uniformized later on. Signed-off-by: Samuel Pitoiset --- src/util/hash_table.c | 149 ++ src/util/hash_table.h | 25 + 2 files changed, 174 insertions(+) diff --git a/src/util/hash_table.c b/src/util/hash_table.c index 9e643af8b23..c2b9210218a 100644 --- a/src/util/hash_table.c +++ b/src/util/hash_table.c @@ -47,6 +47,7 @@ #include "hash_table.h" #include "ralloc.h" #include "macros.h" +#include "main/hash.h" static const uint32_t deleted_key_value; @@ -502,3 +503,151 @@ _mesa_key_pointer_equal(const void *a, const void *b) { return a == b; } + +/** + * Hash table wrapper which supports 64-bit keys. + * + * TODO: unify all hash table implementations. + */ +#if !defined(MESA_ARCH_X86_64) + +struct hash_key_u64 { + uint64_t value; +}; + +static uint32_t +key_u64_hash(const void *key) +{ + return _mesa_hash_data(key, sizeof(struct hash_key_u64)); +} + +static bool +key_u64_equals(const void *a, const void *b) +{ + struct hash_key_u64 *aa = (struct hash_key_u64 *)a; const struct hash_key_u64, and then you can drop the cast. + struct hash_key_u64 *bb = (struct hash_key_u64 *)b; + + return aa->value == bb->value; +} + +#endif + +struct hash_table_u64 * +_mesa_hash_table_u64_create(void *mem_ctx) +{ + struct hash_table_u64 *ht; + + ht = CALLOC_STRUCT(hash_table_u64); + if (!ht) + return NULL; + +#if !defined(MESA_ARCH_X86_64) I can't seem to find anything defining MESA_ARCH_X86_64 anywhere. That's stuck in one of Samuel's other pending patches :) Yeah. :) There is also nothing x86-64 specific here, what about doing if (sizeof(void *) == 8) { and letting the compiler optimizer to drop the other case? I like that suggestion, actually, it makes sure both paths will always build without compiler error. +1 for that suggestion, and MESA_ARCH_X86_64 is no longer needed with that. Thanks. With or without your suggestions, the patch is Reviewed-by: Nicolai Hähnle + ht->table = _mesa_hash_table_create(mem_ctx, key_u64_hash, key_u64_equals); +#else + ht->table = _mesa_hash_table_create(mem_ctx, _mesa_hash_pointer, + _mesa_key_pointer_equal); +#endif Gražvydas ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH] mesa/util: add a hash table wrapper which support 64-bit keys
On 13.06.2017 14:01, Grazvydas Ignotas wrote: On Tue, Jun 13, 2017 at 10:58 AM, Samuel Pitoiset wrote: Needed for bindless handles which are represented using 64-bit unsigned integers. All hash table implementations should be uniformized later on. Signed-off-by: Samuel Pitoiset --- src/util/hash_table.c | 149 ++ src/util/hash_table.h | 25 + 2 files changed, 174 insertions(+) diff --git a/src/util/hash_table.c b/src/util/hash_table.c index 9e643af8b23..c2b9210218a 100644 --- a/src/util/hash_table.c +++ b/src/util/hash_table.c @@ -47,6 +47,7 @@ #include "hash_table.h" #include "ralloc.h" #include "macros.h" +#include "main/hash.h" static const uint32_t deleted_key_value; @@ -502,3 +503,151 @@ _mesa_key_pointer_equal(const void *a, const void *b) { return a == b; } + +/** + * Hash table wrapper which supports 64-bit keys. + * + * TODO: unify all hash table implementations. + */ +#if !defined(MESA_ARCH_X86_64) + +struct hash_key_u64 { + uint64_t value; +}; + +static uint32_t +key_u64_hash(const void *key) +{ + return _mesa_hash_data(key, sizeof(struct hash_key_u64)); +} + +static bool +key_u64_equals(const void *a, const void *b) +{ + struct hash_key_u64 *aa = (struct hash_key_u64 *)a; const struct hash_key_u64, and then you can drop the cast. + struct hash_key_u64 *bb = (struct hash_key_u64 *)b; + + return aa->value == bb->value; +} + +#endif + +struct hash_table_u64 * +_mesa_hash_table_u64_create(void *mem_ctx) +{ + struct hash_table_u64 *ht; + + ht = CALLOC_STRUCT(hash_table_u64); + if (!ht) + return NULL; + +#if !defined(MESA_ARCH_X86_64) I can't seem to find anything defining MESA_ARCH_X86_64 anywhere. That's stuck in one of Samuel's other pending patches :) There is also nothing x86-64 specific here, what about doing if (sizeof(void *) == 8) { and letting the compiler optimizer to drop the other case? I like that suggestion, actually, it makes sure both paths will always build without compiler error. With or without your suggestions, the patch is Reviewed-by: Nicolai Hähnle + ht->table = _mesa_hash_table_create(mem_ctx, key_u64_hash, key_u64_equals); +#else + ht->table = _mesa_hash_table_create(mem_ctx, _mesa_hash_pointer, + _mesa_key_pointer_equal); +#endif Gražvydas ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev -- Lerne, wie die Welt wirklich ist, Aber vergiss niemals, wie sie sein sollte. ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH] mesa/util: add a hash table wrapper which support 64-bit keys
On Tue, Jun 13, 2017 at 10:58 AM, Samuel Pitoiset wrote: > Needed for bindless handles which are represented using > 64-bit unsigned integers. All hash table implementations should > be uniformized later on. > > Signed-off-by: Samuel Pitoiset > --- > src/util/hash_table.c | 149 > ++ > src/util/hash_table.h | 25 + > 2 files changed, 174 insertions(+) > > diff --git a/src/util/hash_table.c b/src/util/hash_table.c > index 9e643af8b23..c2b9210218a 100644 > --- a/src/util/hash_table.c > +++ b/src/util/hash_table.c > @@ -47,6 +47,7 @@ > #include "hash_table.h" > #include "ralloc.h" > #include "macros.h" > +#include "main/hash.h" > > static const uint32_t deleted_key_value; > > @@ -502,3 +503,151 @@ _mesa_key_pointer_equal(const void *a, const void *b) > { > return a == b; > } > + > +/** > + * Hash table wrapper which supports 64-bit keys. > + * > + * TODO: unify all hash table implementations. > + */ > +#if !defined(MESA_ARCH_X86_64) > + > +struct hash_key_u64 { > + uint64_t value; > +}; > + > +static uint32_t > +key_u64_hash(const void *key) > +{ > + return _mesa_hash_data(key, sizeof(struct hash_key_u64)); > +} > + > +static bool > +key_u64_equals(const void *a, const void *b) > +{ > + struct hash_key_u64 *aa = (struct hash_key_u64 *)a; const struct hash_key_u64, and then you can drop the cast. > + struct hash_key_u64 *bb = (struct hash_key_u64 *)b; > + > + return aa->value == bb->value; > +} > + > +#endif > + > +struct hash_table_u64 * > +_mesa_hash_table_u64_create(void *mem_ctx) > +{ > + struct hash_table_u64 *ht; > + > + ht = CALLOC_STRUCT(hash_table_u64); > + if (!ht) > + return NULL; > + > +#if !defined(MESA_ARCH_X86_64) I can't seem to find anything defining MESA_ARCH_X86_64 anywhere. There is also nothing x86-64 specific here, what about doing if (sizeof(void *) == 8) { and letting the compiler optimizer to drop the other case? > + ht->table = _mesa_hash_table_create(mem_ctx, key_u64_hash, > key_u64_equals); > +#else > + ht->table = _mesa_hash_table_create(mem_ctx, _mesa_hash_pointer, > + _mesa_key_pointer_equal); > +#endif Gražvydas ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH] mesa/util: add a hash table wrapper which support 64-bit keys
Needed for bindless handles which are represented using 64-bit unsigned integers. All hash table implementations should be uniformized later on. Signed-off-by: Samuel Pitoiset --- src/util/hash_table.c | 149 ++ src/util/hash_table.h | 25 + 2 files changed, 174 insertions(+) diff --git a/src/util/hash_table.c b/src/util/hash_table.c index 9e643af8b23..c2b9210218a 100644 --- a/src/util/hash_table.c +++ b/src/util/hash_table.c @@ -47,6 +47,7 @@ #include "hash_table.h" #include "ralloc.h" #include "macros.h" +#include "main/hash.h" static const uint32_t deleted_key_value; @@ -502,3 +503,151 @@ _mesa_key_pointer_equal(const void *a, const void *b) { return a == b; } + +/** + * Hash table wrapper which supports 64-bit keys. + * + * TODO: unify all hash table implementations. + */ +#if !defined(MESA_ARCH_X86_64) + +struct hash_key_u64 { + uint64_t value; +}; + +static uint32_t +key_u64_hash(const void *key) +{ + return _mesa_hash_data(key, sizeof(struct hash_key_u64)); +} + +static bool +key_u64_equals(const void *a, const void *b) +{ + struct hash_key_u64 *aa = (struct hash_key_u64 *)a; + struct hash_key_u64 *bb = (struct hash_key_u64 *)b; + + return aa->value == bb->value; +} + +#endif + +struct hash_table_u64 * +_mesa_hash_table_u64_create(void *mem_ctx) +{ + struct hash_table_u64 *ht; + + ht = CALLOC_STRUCT(hash_table_u64); + if (!ht) + return NULL; + +#if !defined(MESA_ARCH_X86_64) + ht->table = _mesa_hash_table_create(mem_ctx, key_u64_hash, key_u64_equals); +#else + ht->table = _mesa_hash_table_create(mem_ctx, _mesa_hash_pointer, + _mesa_key_pointer_equal); +#endif + + if (ht->table) + _mesa_hash_table_set_deleted_key(ht->table, uint_key(DELETED_KEY_VALUE)); + + return ht; +} + +void +_mesa_hash_table_u64_destroy(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; + + /* 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; + + delete_function(&deleted_entry); + } + ht->deleted_key_data = NULL; + } + + _mesa_hash_table_destroy(ht->table, delete_function); + free(ht); +} + +void +_mesa_hash_table_u64_insert(struct hash_table_u64 *ht, uint64_t key, +void *data) +{ + if (key == DELETED_KEY_VALUE) { + ht->deleted_key_data = data; + return; + } + +#if !defined(MESA_ARCH_X86_64) + struct hash_key_u64 *_key = CALLOC_STRUCT(hash_key_u64); + + if (!_key) + return; + _key->value = key; + + _mesa_hash_table_insert(ht->table, _key, data); +#else + _mesa_hash_table_insert(ht->table, (void *)key, data); +#endif +} + +static struct hash_entry * +hash_table_u64_search(struct hash_table_u64 *ht, uint64_t key) +{ +#if !defined(MESA_ARCH_X86_64) + struct hash_key_u64 _key = { .value = key }; + return _mesa_hash_table_search(ht->table, &_key); +#else + return _mesa_hash_table_search(ht->table, (void *)key); +#endif +} + +void * +_mesa_hash_table_u64_search(struct hash_table_u64 *ht, uint64_t key) +{ + struct hash_entry *entry; + + if (key == DELETED_KEY_VALUE) + return ht->deleted_key_data; + + entry = hash_table_u64_search(ht, key); + if (!entry) + return NULL; + + return entry->data; +} + +void +_mesa_hash_table_u64_remove(struct hash_table_u64 *ht, uint64_t key) +{ + struct hash_entry *entry; + + if (key == DELETED_KEY_VALUE) { + ht->deleted_key_data = NULL; + return; + } + + entry = hash_table_u64_search(ht, key); + if (!entry) + return; + +#if !defined(MESA_ARCH_X86_64) + struct hash_key *_key = (struct hash_key *)entry->key; + + _mesa_hash_table_remove(ht->table, entry); + free(_key); +#else + _mesa_hash_table_remove(ht->table, entry); +#endif +} diff --git a/src/util/hash_table.h b/src/util/hash_table.h index c7f577665dc..cf939130fcf 100644 --- a/src/util/hash_table.h +++ b/src/util/hash_table.h @@ -153,6 +153,31 @@ hash_table_call_foreach(struct hash_table *ht, callback(entry->key, entry->data, closure); } +/** + * Hash table wrapper which supports 64-bit keys. + */ +struct hash_table_u64 { + struct hash_table *table; + void *deleted_key_data; +}; + +struct hash_table_u64 * +_mesa_hash_table_u64_create(void *mem_ctx); + +void +_mesa_hash_table_u64_destroy(struct hash_table_u64 *ht, + void (*delete_function)(struct hash_entry *entry)); + +void +_mesa_hash_table_u64_insert(struct hash_table_u64 *ht, uint64_t key, +void *data); + +void * +_mesa_hash_tab