summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gallium/auxiliary/util/u_hash_table.c77
-rw-r--r--src/gallium/auxiliary/util/u_hash_table.h4
2 files changed, 72 insertions, 9 deletions
diff --git a/src/gallium/auxiliary/util/u_hash_table.c b/src/gallium/auxiliary/util/u_hash_table.c
index f3f16a8d94f..dd5eca7fca3 100644
--- a/src/gallium/auxiliary/util/u_hash_table.c
+++ b/src/gallium/auxiliary/util/u_hash_table.c
@@ -67,6 +67,13 @@ struct hash_table_item
};
+static INLINE struct hash_table_item *
+hash_table_item(struct cso_hash_iter iter)
+{
+ return (struct hash_table_item *)cso_hash_iter_data(iter);
+}
+
+
struct hash_table *
hash_table_create(unsigned (*hash)(void *key),
int (*compare)(void *key1, void *key2))
@@ -90,7 +97,27 @@ hash_table_create(unsigned (*hash)(void *key),
}
-static struct hash_table_item *
+static INLINE struct cso_hash_iter
+hash_table_find_iter(struct hash_table *ht,
+ void *key,
+ unsigned key_hash)
+{
+ struct cso_hash_iter iter;
+ struct hash_table_item *item;
+
+ iter = cso_hash_find(ht->cso, key_hash);
+ while (!cso_hash_iter_is_null(iter)) {
+ item = (struct hash_table_item *)cso_hash_iter_data(iter);
+ if (!ht->compare(item->key, key))
+ break;
+ iter = cso_hash_iter_next(iter);
+ }
+
+ return iter;
+}
+
+
+static INLINE struct hash_table_item *
hash_table_find_item(struct hash_table *ht,
void *key,
unsigned key_hash)
@@ -117,6 +144,7 @@ hash_table_set(struct hash_table *ht,
{
unsigned key_hash;
struct hash_table_item *item;
+ struct cso_hash_iter iter;
assert(ht);
@@ -136,9 +164,8 @@ hash_table_set(struct hash_table *ht,
item->key = key;
item->value = value;
- cso_hash_insert(ht->cso, key_hash, item);
- /* FIXME: there is no OOM propagation in cso_hash */
- if(0) {
+ iter = cso_hash_insert(ht->cso, key_hash, item);
+ if(cso_hash_iter_is_null(iter)) {
FREE(item);
return PIPE_ERROR_OUT_OF_MEMORY;
}
@@ -171,19 +198,39 @@ hash_table_remove(struct hash_table *ht,
void *key)
{
unsigned key_hash;
+ struct cso_hash_iter iter;
struct hash_table_item *item;
assert(ht);
key_hash = ht->hash(key);
- item = hash_table_find_item(ht, key, key_hash);
- if(!item)
+ iter = hash_table_find_iter(ht, key, key_hash);
+ if(cso_hash_iter_is_null(iter))
return;
- /* FIXME: cso_hash_take takes the first element of the collision list
- * indiscriminately, so we can not take the item down. */
- item->value = NULL;
+ item = hash_table_item(iter);
+ assert(item);
+ FREE(item);
+
+ cso_hash_erase(ht->cso, iter);
+}
+
+
+void
+hash_table_clear(struct hash_table *ht)
+{
+ struct cso_hash_iter iter;
+ struct hash_table_item *item;
+
+ assert(ht);
+
+ iter = cso_hash_first_node(ht->cso);
+ while (!cso_hash_iter_is_null(iter)) {
+ item = (struct hash_table_item *)cso_hash_take(ht->cso, cso_hash_iter_key(iter));
+ FREE(item);
+ iter = cso_hash_first_node(ht->cso);
+ }
}
@@ -196,6 +243,8 @@ hash_table_foreach(struct hash_table *ht,
struct hash_table_item *item;
enum pipe_error result;
+ assert(ht);
+
iter = cso_hash_first_node(ht->cso);
while (!cso_hash_iter_is_null(iter)) {
item = (struct hash_table_item *)cso_hash_iter_data(iter);
@@ -212,7 +261,17 @@ hash_table_foreach(struct hash_table *ht,
void
hash_table_destroy(struct hash_table *ht)
{
+ struct cso_hash_iter iter;
+ struct hash_table_item *item;
+
assert(ht);
+
+ iter = cso_hash_first_node(ht->cso);
+ while (!cso_hash_iter_is_null(iter)) {
+ item = (struct hash_table_item *)cso_hash_iter_data(iter);
+ FREE(item);
+ iter = cso_hash_iter_next(iter);
+ }
cso_hash_delete(ht->cso);
diff --git a/src/gallium/auxiliary/util/u_hash_table.h b/src/gallium/auxiliary/util/u_hash_table.h
index 1583bd7548c..feee881582e 100644
--- a/src/gallium/auxiliary/util/u_hash_table.h
+++ b/src/gallium/auxiliary/util/u_hash_table.h
@@ -75,6 +75,10 @@ hash_table_remove(struct hash_table *ht,
void *key);
+void
+hash_table_clear(struct hash_table *ht);
+
+
enum pipe_error
hash_table_foreach(struct hash_table *ht,
enum pipe_error (*callback)(void *key, void *value, void *data),