summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/util/u_hash_table.c
diff options
context:
space:
mode:
authorJosé Fonseca <jrfonseca@tungstengraphics.com>2008-05-08 15:19:07 +0900
committerJosé Fonseca <jrfonseca@tungstengraphics.com>2008-05-08 15:29:20 +0900
commit665b327a47ce80d136e91cfafedbc165227ea168 (patch)
treedd9b2556e944859e728732448eabbff92c52c65b /src/gallium/auxiliary/util/u_hash_table.c
parent53996e562f8623ccb1defeaaa77efdff24477808 (diff)
gallium: Really free hash entries.
Hook up to the new cso_hash_erase function.
Diffstat (limited to 'src/gallium/auxiliary/util/u_hash_table.c')
-rw-r--r--src/gallium/auxiliary/util/u_hash_table.c77
1 files changed, 68 insertions, 9 deletions
diff --git a/src/gallium/auxiliary/util/u_hash_table.c b/src/gallium/auxiliary/util/u_hash_table.c
index f3f16a8d94..dd5eca7fca 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);