From acd834fde2e604173985be5d44cb2cf2b0cd5673 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 17 Aug 2011 11:51:15 -0700 Subject: mesa: Add hash_table_replace hash_table_replace doesn't use get_node to avoid having to hash the key twice. Signed-off-by: Ian Romanick Reviewed-by: Kenneth Graunke --- src/mesa/program/hash_table.c | 25 +++++++++++++++++++++++++ src/mesa/program/hash_table.h | 15 +++++++++++++++ 2 files changed, 40 insertions(+) (limited to 'src') diff --git a/src/mesa/program/hash_table.c b/src/mesa/program/hash_table.c index 2b09462c0f5..dc8563a330f 100644 --- a/src/mesa/program/hash_table.c +++ b/src/mesa/program/hash_table.c @@ -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) { diff --git a/src/mesa/program/hash_table.h b/src/mesa/program/hash_table.h index 746939c2273..e7ab067a3bd 100644 --- a/src/mesa/program/hash_table.h +++ b/src/mesa/program/hash_table.h @@ -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. */ -- cgit v1.2.3