gallium: Really free hash entries.
authorJosé Fonseca <jrfonseca@tungstengraphics.com>
Thu, 8 May 2008 06:19:07 +0000 (15:19 +0900)
committerJosé Fonseca <jrfonseca@tungstengraphics.com>
Thu, 8 May 2008 06:29:20 +0000 (15:29 +0900)
Hook up to the new cso_hash_erase function.

src/gallium/auxiliary/util/u_hash_table.c
src/gallium/auxiliary/util/u_hash_table.h

index f3f16a8d94f606f437f365927de4062a7addece8..dd5eca7fca357811d2fecf47a9f9d4ce5673df9e 100644 (file)
@@ -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);
    
index 1583bd7548c32b3be9d8680f5adc75a0da5fdc32..feee881582e1b891d456fcdc0be82d5bf917dbb0 100644 (file)
@@ -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),