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>

Eric Wong committed Oct 6, 2019 at 23:30 UTC 8a973d0bb398d6d83d6c048acecc750d01bd7234
6 files changed +32 -11
hashmap.c
+5 -3
@@ -219,8 +219,9 @@ void hashmap_add(struct hashmap *map, struct hashmap_entry *entry)
219 }
220 }
221
222 -void *hashmap_remove(struct hashmap *map, const struct hashmap_entry *key,
223 - const void *keydata)
222 +struct hashmap_entry *hashmap_remove(struct hashmap *map,
223 + const struct hashmap_entry *key,
224 + const void *keydata)
225 {
226 struct hashmap_entry *old;
227 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,
243 return old;
244 }
245
245 -void *hashmap_put(struct hashmap *map, struct hashmap_entry *entry)
246 +struct hashmap_entry *hashmap_put(struct hashmap *map,
247 + struct hashmap_entry *entry)
248 {
249 struct hashmap_entry *old = hashmap_remove(map, entry, NULL);
250 hashmap_add(map, entry);
hashmap.h
+12 -3
@@ -349,7 +349,11 @@ void hashmap_add(struct hashmap *map, struct hashmap_entry *entry);
349 * `entry` is the entry to add or replace.
350 * Returns the replaced entry, or NULL if not found (i.e. the entry was added).
351 */
352 -void *hashmap_put(struct hashmap *map, struct hashmap_entry *entry);
352 +struct hashmap_entry *hashmap_put(struct hashmap *map,
353 + struct hashmap_entry *entry);
354 +
355 +#define hashmap_put_entry(map, keyvar, type, member) \
356 + container_of_or_null(hashmap_put(map, &(keyvar)->member), type, member)
357
358 /*
359 * 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);
362 *
363 * Argument explanation is the same as in `hashmap_get`.
364 */
361 -void *hashmap_remove(struct hashmap *map, const struct hashmap_entry *key,
362 - const void *keydata);
365 +struct hashmap_entry *hashmap_remove(struct hashmap *map,
366 + const struct hashmap_entry *key,
367 + const void *keydata);
368 +
369 +#define hashmap_remove_entry(map, keyvar, keydata, type, member) \
370 + container_of_or_null(hashmap_remove(map, &(keyvar)->member, keydata), \
371 + type, member)
372
373 /*
374 * Returns the `bucket` an entry is stored in.
range-diff.c
+3 -1
@@ -229,7 +229,9 @@ static void find_exact_matches(struct string_list *a, struct string_list *b)
229 util->patch = b->items[i].string;
230 util->diff = util->patch + util->diff_offset;
231 hashmap_entry_init(&util->e, strhash(util->diff));
232 - other = hashmap_remove(&map, &util->e, NULL);
232 + other = hashmap_remove_entry(&map, util, NULL,
233 + struct patch_util,
234 + e /* member name */);
235 if (other) {
236 if (other->matching >= 0)
237 BUG("already assigned!");
remote.c
+2 -1
@@ -162,7 +162,8 @@ static struct remote *make_remote(const char *name, int len)
162 remotes[remotes_nr++] = ret;
163
164 hashmap_entry_init(&ret->ent, lookup_entry.hash);
165 - replaced = hashmap_put(&remotes_hash, &ret->ent);
165 + replaced = hashmap_put_entry(&remotes_hash, ret, struct remote,
166 + ent /* member name */);
167 assert(replaced == NULL); /* no previous entry overwritten */
168 return ret;
169 }
submodule-config.c
+3 -1
@@ -141,7 +141,9 @@ static void cache_remove_path(struct submodule_cache *cache,
141 struct submodule_entry *removed;
142 hashmap_entry_init(&e.ent, hash);
143 e.config = submodule;
144 - removed = hashmap_remove(&cache->for_path, &e.ent, NULL);
144 + removed = hashmap_remove_entry(&cache->for_path, &e, NULL,
145 + struct submodule_entry,
146 + ent /* member name */);
147 free(removed);
148 }
149
t/helper/test-hashmap.c
+7 -2
@@ -189,7 +189,9 @@ int cmd__hashmap(int argc, const char **argv)
189 entry = alloc_test_entry(hash, p1, p2);
190
191 /* add / replace entry */
192 - entry = hashmap_put(&map, &entry->ent);
192 + entry = hashmap_put_entry(&map, entry,
193 + struct test_entry,
194 + ent /* member name */);
195
196 /* print and free replaced entry, if any */
197 puts(entry ? get_value(entry) : "NULL");
@@ -212,10 +214,13 @@ int cmd__hashmap(int argc, const char **argv)
214
215 /* setup static key */
216 struct hashmap_entry key;
217 + struct hashmap_entry *rm;
218 hashmap_entry_init(&key, hash);
219
220 /* remove entry from hashmap */
218 - entry = hashmap_remove(&map, &key, p1);
221 + rm = hashmap_remove(&map, &key, p1);
222 + entry = rm ? container_of(rm, struct test_entry, ent)
223 + : NULL;
224
225 /* print result and free entry*/
226 puts(entry ? get_value(entry) : "NULL");