mesa: Add hash_table_replace
authorIan Romanick <ian.d.romanick@intel.com>
Wed, 17 Aug 2011 18:51:15 +0000 (11:51 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Tue, 4 Oct 2011 19:33:28 +0000 (12:33 -0700)
hash_table_replace doesn't use get_node to avoid having to hash the key twice.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/program/hash_table.c
src/mesa/program/hash_table.h

index 2b09462c0f5cd4f0540f6c2d4a4be940217c799d..dc8563a330f72af2ffeb6bb5f1153268df4c8ec5 100644 (file)
@@ -149,6 +149,31 @@ hash_table_insert(struct hash_table *ht, void *data, const void *key)
     insert_at_head(& ht->buckets[bucket], & node->link);
 }
 
+void
+hash_table_replace(struct hash_table *ht, void *data, const void *key)
+{
+    const unsigned hash_value = (*ht->hash)(key);
+    const unsigned bucket = hash_value % ht->num_buckets;
+    struct node *node;
+    struct hash_node *hn;
+
+    foreach(node, & ht->buckets[bucket]) {
+       hn = (struct hash_node *) node;
+
+       if ((*ht->compare)(hn->key, key) == 0) {
+         hn->data = data;
+         return;
+       }
+    }
+
+    hn = calloc(1, sizeof(*hn));
+
+    hn->data = data;
+    hn->key = key;
+
+    insert_at_head(& ht->buckets[bucket], & hn->link);
+}
+
 void
 hash_table_remove(struct hash_table *ht, const void *key)
 {
index 746939c2273b7a1bf145fc5342d082268192cb3f..e7ab067a3bd66f7fddc201d390a10bedcb48c397 100644 (file)
@@ -93,10 +93,25 @@ extern void *hash_table_find(struct hash_table *ht, const void *key);
  * If \c key is already in the hash table, it will be added again.  Future
  * calls to \c hash_table_find and \c hash_table_remove will return or remove,
  * repsectively, the most recently added instance of \c key.
+ *
+ * \sa hash_table_replace
  */
 extern void hash_table_insert(struct hash_table *ht, void *data,
     const void *key);
 
+/**
+ * Add an element to a hash table with replacement
+ *
+ * \warning
+ * If \c key is already in the hash table, \c data will \b replace the most
+ * recently inserted \c data (see the warning in \c hash_table_insert) for
+ * that key.
+ *
+ * \sa hash_table_insert
+ */
+extern void hash_table_replace(struct hash_table *ht, void *data,
+    const void *key);
+
 /**
  * Remove a specific element from a hash table.
  */