From 97a39a4a930ebec9162f90ebd0412aed47d413d0 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 2 Nov 2020 18:55:02 +0000 Subject: hashmap: adjust spacing to fix argument alignment No actual code changes; just whitespace adjustments. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- hashmap.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'hashmap.c') diff --git a/hashmap.c b/hashmap.c index 09813e1a46..e44d8a3e85 100644 --- a/hashmap.c +++ b/hashmap.c @@ -92,8 +92,9 @@ static void alloc_table(struct hashmap *map, unsigned int size) } static inline int entry_equals(const struct hashmap *map, - const struct hashmap_entry *e1, const struct hashmap_entry *e2, - const void *keydata) + const struct hashmap_entry *e1, + const struct hashmap_entry *e2, + const void *keydata) { return (e1 == e2) || (e1->hash == e2->hash && @@ -101,7 +102,7 @@ static inline int entry_equals(const struct hashmap *map, } static inline unsigned int bucket(const struct hashmap *map, - const struct hashmap_entry *key) + const struct hashmap_entry *key) { return key->hash & (map->tablesize - 1); } @@ -148,7 +149,7 @@ static int always_equal(const void *unused_cmp_data, } void hashmap_init(struct hashmap *map, hashmap_cmp_fn equals_function, - const void *cmpfn_data, size_t initial_size) + const void *cmpfn_data, size_t initial_size) { unsigned int size = HASHMAP_INITIAL_SIZE; @@ -199,7 +200,7 @@ struct hashmap_entry *hashmap_get(const struct hashmap *map, } struct hashmap_entry *hashmap_get_next(const struct hashmap *map, - const struct hashmap_entry *entry) + const struct hashmap_entry *entry) { struct hashmap_entry *e = entry->next; for (; e; e = e->next) @@ -225,8 +226,8 @@ void hashmap_add(struct hashmap *map, struct hashmap_entry *entry) } struct hashmap_entry *hashmap_remove(struct hashmap *map, - const struct hashmap_entry *key, - const void *keydata) + const struct hashmap_entry *key, + const void *keydata) { struct hashmap_entry *old; struct hashmap_entry **e = find_entry_ptr(map, key, keydata); @@ -249,7 +250,7 @@ struct hashmap_entry *hashmap_remove(struct hashmap *map, } struct hashmap_entry *hashmap_put(struct hashmap *map, - struct hashmap_entry *entry) + struct hashmap_entry *entry) { struct hashmap_entry *old = hashmap_remove(map, entry, NULL); hashmap_add(map, entry); -- cgit v1.3-6-g1900 From b7879b0ba6ee1306a42227f7fd7f4e5f50409184 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 2 Nov 2020 18:55:03 +0000 Subject: hashmap: allow re-use after hashmap_free() Previously, once map->table had been freed, any calls to hashmap_put(), hashmap_get(), or hashmap_remove() would cause a NULL pointer dereference (since hashmap_free_() also zeros the memory; without that zeroing, calling these functions would cause a use-after-free problem). Modify these functions to check for a NULL table and automatically allocate as needed. Also add a HASHMAP_INIT(fn, data) macro for initializing hashmaps on the stack without calling hashmap_init(). Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- hashmap.c | 16 ++++++++++++++-- hashmap.h | 3 +++ 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'hashmap.c') diff --git a/hashmap.c b/hashmap.c index e44d8a3e85..bb7c9979b8 100644 --- a/hashmap.c +++ b/hashmap.c @@ -114,6 +114,7 @@ int hashmap_bucket(const struct hashmap *map, unsigned int hash) static void rehash(struct hashmap *map, unsigned int newsize) { + /* map->table MUST NOT be NULL when this function is called */ unsigned int i, oldsize = map->tablesize; struct hashmap_entry **oldtable = map->table; @@ -134,6 +135,7 @@ static void rehash(struct hashmap *map, unsigned int newsize) static inline struct hashmap_entry **find_entry_ptr(const struct hashmap *map, const struct hashmap_entry *key, const void *keydata) { + /* map->table MUST NOT be NULL when this function is called */ struct hashmap_entry **e = &map->table[bucket(map, key)]; while (*e && !entry_equals(map, *e, key, keydata)) e = &(*e)->next; @@ -196,6 +198,8 @@ struct hashmap_entry *hashmap_get(const struct hashmap *map, const struct hashmap_entry *key, const void *keydata) { + if (!map->table) + return NULL; return *find_entry_ptr(map, key, keydata); } @@ -211,8 +215,12 @@ struct hashmap_entry *hashmap_get_next(const struct hashmap *map, void hashmap_add(struct hashmap *map, struct hashmap_entry *entry) { - unsigned int b = bucket(map, entry); + unsigned int b; + + if (!map->table) + alloc_table(map, HASHMAP_INITIAL_SIZE); + b = bucket(map, entry); /* add entry */ entry->next = map->table[b]; map->table[b] = entry; @@ -230,7 +238,11 @@ struct hashmap_entry *hashmap_remove(struct hashmap *map, const void *keydata) { struct hashmap_entry *old; - struct hashmap_entry **e = find_entry_ptr(map, key, keydata); + struct hashmap_entry **e; + + if (!map->table) + return NULL; + e = find_entry_ptr(map, key, keydata); if (!*e) return NULL; diff --git a/hashmap.h b/hashmap.h index 904f61d6e1..3b0f2bcade 100644 --- a/hashmap.h +++ b/hashmap.h @@ -210,6 +210,9 @@ struct hashmap { /* hashmap functions */ +#define HASHMAP_INIT(fn, data) { .cmpfn = fn, .cmpfn_data = data, \ + .do_count_items = 1 } + /* * Initializes a hashmap structure. * -- cgit v1.3-6-g1900 From 33f20d82177871225e17d9dd44169a52a36c9f1d Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 2 Nov 2020 18:55:04 +0000 Subject: hashmap: introduce a new hashmap_partial_clear() merge-ort is a heavy user of strmaps, which are built on hashmap.[ch]. clear_or_reinit_internal_opts() in merge-ort was taking about 12% of overall runtime in my testcase involving rebasing 35 patches of linux.git across a big rename. clear_or_reinit_internal_opts() was calling hashmap_free() followed by hashmap_init(), meaning that not only was it freeing all the memory associated with each of the strmaps just to immediately allocate a new array again, it was allocating a new array that was likely smaller than needed (thus resulting in later need to rehash things). The ending size of the map table on the previous commit was likely almost perfectly sized for the next commit we wanted to pick, and not dropping and reallocating the table immediately is a win. Add some new API to hashmap to clear a hashmap of entries without freeing map->table (and instead only zeroing it out like alloc_table() would do, along with zeroing the count of items in the table and the shrink_at field). Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- hashmap.c | 39 +++++++++++++++++++++++++++------------ hashmap.h | 13 ++++++++++++- 2 files changed, 39 insertions(+), 13 deletions(-) (limited to 'hashmap.c') diff --git a/hashmap.c b/hashmap.c index bb7c9979b8..922ed07954 100644 --- a/hashmap.c +++ b/hashmap.c @@ -174,22 +174,37 @@ void hashmap_init(struct hashmap *map, hashmap_cmp_fn equals_function, map->do_count_items = 1; } +static void free_individual_entries(struct hashmap *map, ssize_t entry_offset) +{ + struct hashmap_iter iter; + struct hashmap_entry *e; + + hashmap_iter_init(map, &iter); + while ((e = hashmap_iter_next(&iter))) + /* + * like container_of, but using caller-calculated + * offset (caller being hashmap_free_entries) + */ + free((char *)e - entry_offset); +} + +void hashmap_partial_clear_(struct hashmap *map, ssize_t entry_offset) +{ + if (!map || !map->table) + return; + if (entry_offset >= 0) /* called by hashmap_clear_entries */ + free_individual_entries(map, entry_offset); + memset(map->table, 0, map->tablesize * sizeof(struct hashmap_entry *)); + map->shrink_at = 0; + map->private_size = 0; +} + void hashmap_free_(struct hashmap *map, ssize_t entry_offset) { if (!map || !map->table) return; - if (entry_offset >= 0) { /* called by hashmap_free_entries */ - struct hashmap_iter iter; - struct hashmap_entry *e; - - hashmap_iter_init(map, &iter); - while ((e = hashmap_iter_next(&iter))) - /* - * like container_of, but using caller-calculated - * offset (caller being hashmap_free_entries) - */ - free((char *)e - entry_offset); - } + if (entry_offset >= 0) /* called by hashmap_free_entries */ + free_individual_entries(map, entry_offset); free(map->table); memset(map, 0, sizeof(*map)); } diff --git a/hashmap.h b/hashmap.h index 3b0f2bcade..e9430d582a 100644 --- a/hashmap.h +++ b/hashmap.h @@ -235,7 +235,8 @@ void hashmap_init(struct hashmap *map, const void *equals_function_data, size_t initial_size); -/* internal function for freeing hashmap */ +/* internal functions for clearing or freeing hashmap */ +void hashmap_partial_clear_(struct hashmap *map, ssize_t offset); void hashmap_free_(struct hashmap *map, ssize_t offset); /* @@ -268,6 +269,16 @@ void hashmap_free_(struct hashmap *map, ssize_t offset); */ #define hashmap_free(map) hashmap_free_(map, -1) +/* + * Basically the same as calling hashmap_free() followed by hashmap_init(), + * but doesn't incur the overhead of deallocating and reallocating + * map->table; it leaves map->table allocated and the same size but zeroes + * it out so it's ready for use again as an empty map. As with + * hashmap_free(), you may need to free the entries yourself before calling + * this function. + */ +#define hashmap_partial_clear(map) hashmap_partial_clear_(map, -1) + /* * Frees @map and all entries. @type is the struct type of the entry * where @member is the hashmap_entry struct used to associate with @map. -- cgit v1.3-6-g1900 From 6da1a258142ac2422c8c57c54b92eaed3c86226e Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Mon, 2 Nov 2020 18:55:05 +0000 Subject: hashmap: provide deallocation function names hashmap_free(), hashmap_free_entries(), and hashmap_free_() have existed for a while, but aren't necessarily the clearest names, especially with hashmap_partial_clear() being added to the mix and lazy-initialization now being supported. Peff suggested we adopt the following names[1]: - hashmap_clear() - remove all entries and de-allocate any hashmap-specific data, but be ready for reuse - hashmap_clear_and_free() - ditto, but free the entries themselves - hashmap_partial_clear() - remove all entries but don't deallocate table - hashmap_partial_clear_and_free() - ditto, but free the entries This patch provides the new names and converts all existing callers over to the new naming scheme. [1] https://lore.kernel.org/git/20201030125059.GA3277724@coredump.intra.peff.net/ Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- add-interactive.c | 2 +- blame.c | 2 +- bloom.c | 2 +- builtin/fetch.c | 6 +++--- builtin/shortlog.c | 2 +- config.c | 2 +- diff.c | 4 ++-- diffcore-rename.c | 2 +- dir.c | 8 ++++---- hashmap.c | 6 +++--- hashmap.h | 44 +++++++++++++++++++++++++++----------------- merge-recursive.c | 6 +++--- name-hash.c | 4 ++-- object.c | 2 +- oidmap.c | 2 +- patch-ids.c | 2 +- range-diff.c | 2 +- ref-filter.c | 2 +- revision.c | 2 +- sequencer.c | 4 ++-- submodule-config.c | 4 ++-- t/helper/test-hashmap.c | 6 +++--- 22 files changed, 63 insertions(+), 53 deletions(-) (limited to 'hashmap.c') diff --git a/add-interactive.c b/add-interactive.c index 555c4abf32..a14c0feaa2 100644 --- a/add-interactive.c +++ b/add-interactive.c @@ -557,7 +557,7 @@ static int get_modified_files(struct repository *r, if (ps) clear_pathspec(&rev.prune_data); } - hashmap_free_entries(&s.file_map, struct pathname_entry, ent); + hashmap_clear_and_free(&s.file_map, struct pathname_entry, ent); if (unmerged_count) *unmerged_count = s.unmerged_count; if (binary_count) diff --git a/blame.c b/blame.c index 686845b2b4..229beb6452 100644 --- a/blame.c +++ b/blame.c @@ -435,7 +435,7 @@ static void get_fingerprint(struct fingerprint *result, static void free_fingerprint(struct fingerprint *f) { - hashmap_free(&f->map); + hashmap_clear(&f->map); free(f->entries); } diff --git a/bloom.c b/bloom.c index 68c73200a5..719c313a1c 100644 --- a/bloom.c +++ b/bloom.c @@ -287,7 +287,7 @@ struct bloom_filter *get_or_compute_bloom_filter(struct repository *r, } cleanup: - hashmap_free_entries(&pathmap, struct pathmap_hash_entry, entry); + hashmap_clear_and_free(&pathmap, struct pathmap_hash_entry, entry); } else { for (i = 0; i < diff_queued_diff.nr; i++) diff_free_filepair(diff_queued_diff.queue[i]); diff --git a/builtin/fetch.c b/builtin/fetch.c index f9c3c49f14..ecf8537605 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -393,7 +393,7 @@ static void find_non_local_tags(const struct ref *refs, item = refname_hash_add(&remote_refs, ref->name, &ref->old_oid); string_list_insert(&remote_refs_list, ref->name); } - hashmap_free_entries(&existing_refs, struct refname_hash_entry, ent); + hashmap_clear_and_free(&existing_refs, struct refname_hash_entry, ent); /* * We may have a final lightweight tag that needs to be @@ -428,7 +428,7 @@ static void find_non_local_tags(const struct ref *refs, **tail = rm; *tail = &rm->next; } - hashmap_free_entries(&remote_refs, struct refname_hash_entry, ent); + hashmap_clear_and_free(&remote_refs, struct refname_hash_entry, ent); string_list_clear(&remote_refs_list, 0); oidset_clear(&fetch_oids); } @@ -573,7 +573,7 @@ static struct ref *get_ref_map(struct remote *remote, } } if (existing_refs_populated) - hashmap_free_entries(&existing_refs, struct refname_hash_entry, ent); + hashmap_clear_and_free(&existing_refs, struct refname_hash_entry, ent); return ref_map; } diff --git a/builtin/shortlog.c b/builtin/shortlog.c index 0a5c4968f6..83f0a739b4 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -220,7 +220,7 @@ static void strset_clear(struct strset *ss) { if (!ss->map.table) return; - hashmap_free_entries(&ss->map, struct strset_item, ent); + hashmap_clear_and_free(&ss->map, struct strset_item, ent); } static void insert_records_from_trailers(struct shortlog *log, diff --git a/config.c b/config.c index 2bdff4457b..8f324ed3a6 100644 --- a/config.c +++ b/config.c @@ -1963,7 +1963,7 @@ void git_configset_clear(struct config_set *cs) free(entry->key); string_list_clear(&entry->value_list, 1); } - hashmap_free_entries(&cs->config_hash, struct config_set_element, ent); + hashmap_clear_and_free(&cs->config_hash, struct config_set_element, ent); cs->hash_initialized = 0; free(cs->list.items); cs->list.nr = 0; diff --git a/diff.c b/diff.c index 2bb2f8f57e..8e0e59f5cf 100644 --- a/diff.c +++ b/diff.c @@ -6289,9 +6289,9 @@ static void diff_flush_patch_all_file_pairs(struct diff_options *o) if (o->color_moved == COLOR_MOVED_ZEBRA_DIM) dim_moved_lines(o); - hashmap_free_entries(&add_lines, struct moved_entry, + hashmap_clear_and_free(&add_lines, struct moved_entry, ent); - hashmap_free_entries(&del_lines, struct moved_entry, + hashmap_clear_and_free(&del_lines, struct moved_entry, ent); } diff --git a/diffcore-rename.c b/diffcore-rename.c index 99e63e90f8..d367a6d244 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -407,7 +407,7 @@ static int find_exact_renames(struct diff_options *options) renames += find_identical_files(&file_table, i, options); /* Free the hash data structure and entries */ - hashmap_free_entries(&file_table, struct file_similarity, entry); + hashmap_clear_and_free(&file_table, struct file_similarity, entry); return renames; } diff --git a/dir.c b/dir.c index 78387110e6..161dce121e 100644 --- a/dir.c +++ b/dir.c @@ -817,8 +817,8 @@ static void add_pattern_to_hashsets(struct pattern_list *pl, struct path_pattern clear_hashmaps: warning(_("disabling cone pattern matching")); - hashmap_free_entries(&pl->parent_hashmap, struct pattern_entry, ent); - hashmap_free_entries(&pl->recursive_hashmap, struct pattern_entry, ent); + hashmap_clear_and_free(&pl->parent_hashmap, struct pattern_entry, ent); + hashmap_clear_and_free(&pl->recursive_hashmap, struct pattern_entry, ent); pl->use_cone_patterns = 0; } @@ -921,8 +921,8 @@ void clear_pattern_list(struct pattern_list *pl) free(pl->patterns[i]); free(pl->patterns); free(pl->filebuf); - hashmap_free_entries(&pl->recursive_hashmap, struct pattern_entry, ent); - hashmap_free_entries(&pl->parent_hashmap, struct pattern_entry, ent); + hashmap_clear_and_free(&pl->recursive_hashmap, struct pattern_entry, ent); + hashmap_clear_and_free(&pl->parent_hashmap, struct pattern_entry, ent); memset(pl, 0, sizeof(*pl)); } diff --git a/hashmap.c b/hashmap.c index 922ed07954..5009471800 100644 --- a/hashmap.c +++ b/hashmap.c @@ -183,7 +183,7 @@ static void free_individual_entries(struct hashmap *map, ssize_t entry_offset) while ((e = hashmap_iter_next(&iter))) /* * like container_of, but using caller-calculated - * offset (caller being hashmap_free_entries) + * offset (caller being hashmap_clear_and_free) */ free((char *)e - entry_offset); } @@ -199,11 +199,11 @@ void hashmap_partial_clear_(struct hashmap *map, ssize_t entry_offset) map->private_size = 0; } -void hashmap_free_(struct hashmap *map, ssize_t entry_offset) +void hashmap_clear_(struct hashmap *map, ssize_t entry_offset) { if (!map || !map->table) return; - if (entry_offset >= 0) /* called by hashmap_free_entries */ + if (entry_offset >= 0) /* called by hashmap_clear_and_free */ free_individual_entries(map, entry_offset); free(map->table); memset(map, 0, sizeof(*map)); diff --git a/hashmap.h b/hashmap.h index e9430d582a..7251687d73 100644 --- a/hashmap.h +++ b/hashmap.h @@ -96,7 +96,7 @@ * } * * if (!strcmp("end", action)) { - * hashmap_free_entries(&map, struct long2string, ent); + * hashmap_clear_and_free(&map, struct long2string, ent); * break; * } * } @@ -237,7 +237,7 @@ void hashmap_init(struct hashmap *map, /* internal functions for clearing or freeing hashmap */ void hashmap_partial_clear_(struct hashmap *map, ssize_t offset); -void hashmap_free_(struct hashmap *map, ssize_t offset); +void hashmap_clear_(struct hashmap *map, ssize_t offset); /* * Frees a hashmap structure and allocated memory for the table, but does not @@ -253,40 +253,50 @@ void hashmap_free_(struct hashmap *map, ssize_t offset); * free(e->somefield); * free(e); * } - * hashmap_free(map); + * hashmap_clear(map); * * instead of * * hashmap_for_each_entry(map, hashmap_iter, e, hashmap_entry_name) { * free(e->somefield); * } - * hashmap_free_entries(map, struct my_entry_struct, hashmap_entry_name); + * hashmap_clear_and_free(map, struct my_entry_struct, hashmap_entry_name); * * to avoid the implicit extra loop over the entries. However, if there are * no special fields in your entry that need to be freed beyond the entry * itself, it is probably simpler to avoid the explicit loop and just call - * hashmap_free_entries(). + * hashmap_clear_and_free(). */ -#define hashmap_free(map) hashmap_free_(map, -1) +#define hashmap_clear(map) hashmap_clear_(map, -1) /* - * Basically the same as calling hashmap_free() followed by hashmap_init(), - * but doesn't incur the overhead of deallocating and reallocating - * map->table; it leaves map->table allocated and the same size but zeroes - * it out so it's ready for use again as an empty map. As with - * hashmap_free(), you may need to free the entries yourself before calling - * this function. + * Similar to hashmap_clear(), except that the table is no deallocated; it + * is merely zeroed out but left the same size as before. If the hashmap + * will be reused, this avoids the overhead of deallocating and + * reallocating map->table. As with hashmap_clear(), you may need to free + * the entries yourself before calling this function. */ #define hashmap_partial_clear(map) hashmap_partial_clear_(map, -1) /* - * Frees @map and all entries. @type is the struct type of the entry - * where @member is the hashmap_entry struct used to associate with @map. + * Similar to hashmap_clear() but also frees all entries. @type is the + * struct type of the entry where @member is the hashmap_entry struct used + * to associate with @map. * - * See usage note above hashmap_free(). + * See usage note above hashmap_clear(). */ -#define hashmap_free_entries(map, type, member) \ - hashmap_free_(map, offsetof(type, member)); +#define hashmap_clear_and_free(map, type, member) \ + hashmap_clear_(map, offsetof(type, member)) + +/* + * Similar to hashmap_partial_clear() but also frees all entries. @type is + * the struct type of the entry where @member is the hashmap_entry struct + * used to associate with @map. + * + * See usage note above hashmap_clear(). + */ +#define hashmap_partial_clear_and_free(map, type, member) \ + hashmap_partial_clear_(map, offsetof(type, member)) /* hashmap_entry functions */ diff --git a/merge-recursive.c b/merge-recursive.c index d0214335a7..f736a0f632 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -2651,7 +2651,7 @@ static struct string_list *get_renames(struct merge_options *opt, free(e->target_file); string_list_clear(&e->source_files, 0); } - hashmap_free_entries(&collisions, struct collision_entry, ent); + hashmap_clear_and_free(&collisions, struct collision_entry, ent); return renames; } @@ -2870,7 +2870,7 @@ static void initial_cleanup_rename(struct diff_queue_struct *pairs, strbuf_release(&e->new_dir); /* possible_new_dirs already cleared in get_directory_renames */ } - hashmap_free_entries(dir_renames, struct dir_rename_entry, ent); + hashmap_clear_and_free(dir_renames, struct dir_rename_entry, ent); free(dir_renames); free(pairs->queue); @@ -3497,7 +3497,7 @@ static int merge_trees_internal(struct merge_options *opt, string_list_clear(entries, 1); free(entries); - hashmap_free_entries(&opt->priv->current_file_dir_set, + hashmap_clear_and_free(&opt->priv->current_file_dir_set, struct path_hashmap_entry, e); if (clean < 0) { diff --git a/name-hash.c b/name-hash.c index fb526a3775..5d3c7b12c1 100644 --- a/name-hash.c +++ b/name-hash.c @@ -726,6 +726,6 @@ void free_name_hash(struct index_state *istate) return; istate->name_hash_initialized = 0; - hashmap_free(&istate->name_hash); - hashmap_free_entries(&istate->dir_hash, struct dir_entry, ent); + hashmap_clear(&istate->name_hash); + hashmap_clear_and_free(&istate->dir_hash, struct dir_entry, ent); } diff --git a/object.c b/object.c index 3257518656..b8406409d5 100644 --- a/object.c +++ b/object.c @@ -532,7 +532,7 @@ void raw_object_store_clear(struct raw_object_store *o) close_object_store(o); o->packed_git = NULL; - hashmap_free(&o->pack_map); + hashmap_clear(&o->pack_map); } void parsed_object_pool_clear(struct parsed_object_pool *o) diff --git a/oidmap.c b/oidmap.c index 423aa014a3..286a04a53c 100644 --- a/oidmap.c +++ b/oidmap.c @@ -27,7 +27,7 @@ void oidmap_free(struct oidmap *map, int free_entries) return; /* TODO: make oidmap itself not depend on struct layouts */ - hashmap_free_(&map->map, free_entries ? 0 : -1); + hashmap_clear_(&map->map, free_entries ? 0 : -1); } void *oidmap_get(const struct oidmap *map, const struct object_id *key) diff --git a/patch-ids.c b/patch-ids.c index 12aa6d494b..21973e4933 100644 --- a/patch-ids.c +++ b/patch-ids.c @@ -71,7 +71,7 @@ int init_patch_ids(struct repository *r, struct patch_ids *ids) int free_patch_ids(struct patch_ids *ids) { - hashmap_free_entries(&ids->patches, struct patch_id, ent); + hashmap_clear_and_free(&ids->patches, struct patch_id, ent); return 0; } diff --git a/range-diff.c b/range-diff.c index 24dc435e48..befeecae44 100644 --- a/range-diff.c +++ b/range-diff.c @@ -266,7 +266,7 @@ static void find_exact_matches(struct string_list *a, struct string_list *b) } } - hashmap_free(&map); + hashmap_clear(&map); } static void diffsize_consume(void *data, char *line, unsigned long len) diff --git a/ref-filter.c b/ref-filter.c index c62f6b4822..5e66b8cd76 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -2222,7 +2222,7 @@ void ref_array_clear(struct ref_array *array) used_atom_cnt = 0; if (ref_to_worktree_map.worktrees) { - hashmap_free_entries(&(ref_to_worktree_map.map), + hashmap_clear_and_free(&(ref_to_worktree_map.map), struct ref_to_worktree_entry, ent); free_worktrees(ref_to_worktree_map.worktrees); ref_to_worktree_map.worktrees = NULL; diff --git a/revision.c b/revision.c index aa62212040..f27649d45d 100644 --- a/revision.c +++ b/revision.c @@ -139,7 +139,7 @@ static void paths_and_oids_clear(struct hashmap *map) free(entry->path); } - hashmap_free_entries(map, struct path_and_oids_entry, ent); + hashmap_clear_and_free(map, struct path_and_oids_entry, ent); } static void paths_and_oids_insert(struct hashmap *map, diff --git a/sequencer.c b/sequencer.c index 00acb12496..23a09c3e7a 100644 --- a/sequencer.c +++ b/sequencer.c @@ -5058,7 +5058,7 @@ static int make_script_with_merges(struct pretty_print_context *pp, oidmap_free(&commit2todo, 1); oidmap_free(&state.commit2label, 1); - hashmap_free_entries(&state.labels, struct labels_entry, entry); + hashmap_clear_and_free(&state.labels, struct labels_entry, entry); strbuf_release(&state.buf); return 0; @@ -5577,7 +5577,7 @@ int todo_list_rearrange_squash(struct todo_list *todo_list) for (i = 0; i < todo_list->nr; i++) free(subjects[i]); free(subjects); - hashmap_free_entries(&subject2item, struct subject2item_entry, entry); + hashmap_clear_and_free(&subject2item, struct subject2item_entry, entry); clear_commit_todo_item(&commit_todo); diff --git a/submodule-config.c b/submodule-config.c index c569e22aa3..f502505566 100644 --- a/submodule-config.c +++ b/submodule-config.c @@ -103,8 +103,8 @@ static void submodule_cache_clear(struct submodule_cache *cache) ent /* member name */) free_one_config(entry); - hashmap_free_entries(&cache->for_path, struct submodule_entry, ent); - hashmap_free_entries(&cache->for_name, struct submodule_entry, ent); + hashmap_clear_and_free(&cache->for_path, struct submodule_entry, ent); + hashmap_clear_and_free(&cache->for_name, struct submodule_entry, ent); cache->initialized = 0; cache->gitmodules_read = 0; } diff --git a/t/helper/test-hashmap.c b/t/helper/test-hashmap.c index f38706216f..2475663b49 100644 --- a/t/helper/test-hashmap.c +++ b/t/helper/test-hashmap.c @@ -110,7 +110,7 @@ static void perf_hashmap(unsigned int method, unsigned int rounds) hashmap_add(&map, &entries[i]->ent); } - hashmap_free(&map); + hashmap_clear(&map); } } else { /* test map lookups */ @@ -130,7 +130,7 @@ static void perf_hashmap(unsigned int method, unsigned int rounds) } } - hashmap_free(&map); + hashmap_clear(&map); } } @@ -262,6 +262,6 @@ int cmd__hashmap(int argc, const char **argv) } strbuf_release(&line); - hashmap_free_entries(&map, struct test_entry, ent); + hashmap_clear_and_free(&map, struct test_entry, ent); return 0; } -- cgit v1.3-6-g1900