summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Eric Wong <e@80x24.org>2019-10-06 23:30:39 +0000
committerLibravatar Junio C Hamano <gitster@pobox.com>2019-10-07 10:20:11 +0900
commit8a973d0bb398d6d83d6c048acecc750d01bd7234 (patch)
treec4987af10c66582df750927a060b13995dafd84a
parenthashmap: use *_entry APIs for iteration (diff)
downloadtgif-8a973d0bb398d6d83d6c048acecc750d01bd7234.tar.xz
hashmap: hashmap_{put,remove} return hashmap_entry *
And add *_entry variants to perform container_of as necessary to simplify most callers. Signed-off-by: Eric Wong <e@80x24.org> Reviewed-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--hashmap.c8
-rw-r--r--hashmap.h15
-rw-r--r--range-diff.c4
-rw-r--r--remote.c3
-rw-r--r--submodule-config.c4
-rw-r--r--t/helper/test-hashmap.c9
6 files changed, 32 insertions, 11 deletions
diff --git a/hashmap.c b/hashmap.c
index deb5fdf28c..1b60f97cf2 100644
--- a/hashmap.c
+++ b/hashmap.c
@@ -219,8 +219,9 @@ void hashmap_add(struct hashmap *map, struct hashmap_entry *entry)
}
}
-void *hashmap_remove(struct hashmap *map, const struct hashmap_entry *key,
- const void *keydata)
+struct hashmap_entry *hashmap_remove(struct hashmap *map,
+ const struct hashmap_entry *key,
+ const void *keydata)
{
struct hashmap_entry *old;
struct hashmap_entry **e = find_entry_ptr(map, key, keydata);
@@ -242,7 +243,8 @@ void *hashmap_remove(struct hashmap *map, const struct hashmap_entry *key,
return old;
}
-void *hashmap_put(struct hashmap *map, struct hashmap_entry *entry)
+struct hashmap_entry *hashmap_put(struct hashmap *map,
+ struct hashmap_entry *entry)
{
struct hashmap_entry *old = hashmap_remove(map, entry, NULL);
hashmap_add(map, entry);
diff --git a/hashmap.h b/hashmap.h
index 8d4b3907b4..bc3b10e097 100644
--- a/hashmap.h
+++ b/hashmap.h
@@ -349,7 +349,11 @@ void hashmap_add(struct hashmap *map, struct hashmap_entry *entry);
* `entry` is the entry to add or replace.
* Returns the replaced entry, or NULL if not found (i.e. the entry was added).
*/
-void *hashmap_put(struct hashmap *map, struct hashmap_entry *entry);
+struct hashmap_entry *hashmap_put(struct hashmap *map,
+ struct hashmap_entry *entry);
+
+#define hashmap_put_entry(map, keyvar, type, member) \
+ container_of_or_null(hashmap_put(map, &(keyvar)->member), type, member)
/*
* Removes a hashmap entry matching the specified key. If the hashmap contains
@@ -358,8 +362,13 @@ void *hashmap_put(struct hashmap *map, struct hashmap_entry *entry);
*
* Argument explanation is the same as in `hashmap_get`.
*/
-void *hashmap_remove(struct hashmap *map, const struct hashmap_entry *key,
- const void *keydata);
+struct hashmap_entry *hashmap_remove(struct hashmap *map,
+ const struct hashmap_entry *key,
+ const void *keydata);
+
+#define hashmap_remove_entry(map, keyvar, keydata, type, member) \
+ container_of_or_null(hashmap_remove(map, &(keyvar)->member, keydata), \
+ type, member)
/*
* Returns the `bucket` an entry is stored in.
diff --git a/range-diff.c b/range-diff.c
index c51cfd5556..e5e7820bfe 100644
--- a/range-diff.c
+++ b/range-diff.c
@@ -229,7 +229,9 @@ static void find_exact_matches(struct string_list *a, struct string_list *b)
util->patch = b->items[i].string;
util->diff = util->patch + util->diff_offset;
hashmap_entry_init(&util->e, strhash(util->diff));
- other = hashmap_remove(&map, &util->e, NULL);
+ other = hashmap_remove_entry(&map, util, NULL,
+ struct patch_util,
+ e /* member name */);
if (other) {
if (other->matching >= 0)
BUG("already assigned!");
diff --git a/remote.c b/remote.c
index fa9cadcfbd..5fcddcd88d 100644
--- a/remote.c
+++ b/remote.c
@@ -162,7 +162,8 @@ static struct remote *make_remote(const char *name, int len)
remotes[remotes_nr++] = ret;
hashmap_entry_init(&ret->ent, lookup_entry.hash);
- replaced = hashmap_put(&remotes_hash, &ret->ent);
+ replaced = hashmap_put_entry(&remotes_hash, ret, struct remote,
+ ent /* member name */);
assert(replaced == NULL); /* no previous entry overwritten */
return ret;
}
diff --git a/submodule-config.c b/submodule-config.c
index 5319933e1d..a289d195f6 100644
--- a/submodule-config.c
+++ b/submodule-config.c
@@ -141,7 +141,9 @@ static void cache_remove_path(struct submodule_cache *cache,
struct submodule_entry *removed;
hashmap_entry_init(&e.ent, hash);
e.config = submodule;
- removed = hashmap_remove(&cache->for_path, &e.ent, NULL);
+ removed = hashmap_remove_entry(&cache->for_path, &e, NULL,
+ struct submodule_entry,
+ ent /* member name */);
free(removed);
}
diff --git a/t/helper/test-hashmap.c b/t/helper/test-hashmap.c
index 4ec5e11556..07a93a2aec 100644
--- a/t/helper/test-hashmap.c
+++ b/t/helper/test-hashmap.c
@@ -189,7 +189,9 @@ int cmd__hashmap(int argc, const char **argv)
entry = alloc_test_entry(hash, p1, p2);
/* add / replace entry */
- entry = hashmap_put(&map, &entry->ent);
+ entry = hashmap_put_entry(&map, entry,
+ struct test_entry,
+ ent /* member name */);
/* print and free replaced entry, if any */
puts(entry ? get_value(entry) : "NULL");
@@ -212,10 +214,13 @@ int cmd__hashmap(int argc, const char **argv)
/* setup static key */
struct hashmap_entry key;
+ struct hashmap_entry *rm;
hashmap_entry_init(&key, hash);
/* remove entry from hashmap */
- entry = hashmap_remove(&map, &key, p1);
+ rm = hashmap_remove(&map, &key, p1);
+ entry = rm ? container_of(rm, struct test_entry, ent)
+ : NULL;
/* print result and free entry*/
puts(entry ? get_value(entry) : "NULL");