diff --git a/src/hashtable.c b/src/hashtable.c index e226c8191..c36d8a8e6 100644 --- a/src/hashtable.c +++ b/src/hashtable.c @@ -179,11 +179,13 @@ void git_hashtable_free(git_hashtable *self) } -int git_hashtable_insert(git_hashtable *self, const void *key, void *value) +int git_hashtable_insert2(git_hashtable *self, const void *key, void *value, void **old_value) { int hash_id; git_hashtable_node *node; + *old_value = NULL; + for (hash_id = 0; hash_id < GIT_HASHTABLE_HASHES; ++hash_id) { node = node_with_hash(self, key, hash_id); @@ -195,6 +197,8 @@ int git_hashtable_insert(git_hashtable *self, const void *key, void *value) } if (key == node->key || self->key_equal(key, node->key) == 0) { + *old_value = node->value; + node->key = key; node->value = value; return GIT_SUCCESS; } @@ -241,3 +245,11 @@ int git_hashtable_remove(git_hashtable *self, const void *key) return GIT_ENOTFOUND; } +int git_hashtable_merge(git_hashtable *self, git_hashtable *other) +{ + if (resize_to(self, (self->size + other->size) * 2) < GIT_SUCCESS) + return GIT_ENOMEM; + + return insert_nodes(self, other->nodes, other->key_count); +} + diff --git a/src/hashtable.h b/src/hashtable.h index 74da580ef..c3475b6ed 100644 --- a/src/hashtable.h +++ b/src/hashtable.h @@ -34,11 +34,19 @@ typedef struct git_hashtable git_hashtable; git_hashtable *git_hashtable_alloc(size_t min_size, git_hash_ptr hash, git_hash_keyeq_ptr key_eq); -int git_hashtable_insert(git_hashtable *h, const void *key, void *value); void *git_hashtable_lookup(git_hashtable *h, const void *key); int git_hashtable_remove(git_hashtable *table, const void *key); void git_hashtable_free(git_hashtable *h); void git_hashtable_clear(git_hashtable *h); +int git_hashtable_merge(git_hashtable *self, git_hashtable *other); + +int git_hashtable_insert2(git_hashtable *h, const void *key, void *value, void **old_value); + +GIT_INLINE(int) git_hashtable_insert(git_hashtable *h, const void *key, void *value) +{ + void *_unused; + return git_hashtable_insert2(h, key, value, &_unused); +} #define git_hashtable_node_at(nodes, pos) ((git_hashtable_node *)(&nodes[pos])) @@ -57,5 +65,9 @@ void git_hashtable_clear(git_hashtable *h); }\ } +#define GIT_HASHTABLE_FOREACH_DELETE() {\ + _node->key = NULL; _node->value = NULL; _self->key_count--;\ +} + #endif