diff options
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | add-interactive.c | 2 | ||||
-rw-r--r-- | attr.c | 26 | ||||
-rw-r--r-- | blame.c | 2 | ||||
-rw-r--r-- | bloom.c | 5 | ||||
-rw-r--r-- | builtin/difftool.c | 9 | ||||
-rw-r--r-- | builtin/fetch.c | 6 | ||||
-rw-r--r-- | builtin/shortlog.c | 61 | ||||
-rw-r--r-- | config.c | 2 | ||||
-rw-r--r-- | diff.c | 4 | ||||
-rw-r--r-- | diffcore-rename.c | 2 | ||||
-rw-r--r-- | dir.c | 8 | ||||
-rw-r--r-- | hashmap.c | 74 | ||||
-rw-r--r-- | hashmap.h | 91 | ||||
-rw-r--r-- | merge-recursive.c | 6 | ||||
-rw-r--r-- | name-hash.c | 4 | ||||
-rw-r--r-- | object.c | 2 | ||||
-rw-r--r-- | oidmap.c | 2 | ||||
-rw-r--r-- | patch-ids.c | 2 | ||||
-rw-r--r-- | range-diff.c | 6 | ||||
-rw-r--r-- | ref-filter.c | 2 | ||||
-rw-r--r-- | revision.c | 11 | ||||
-rw-r--r-- | sequencer.c | 4 | ||||
-rw-r--r-- | strmap.c | 178 | ||||
-rw-r--r-- | strmap.h | 268 | ||||
-rw-r--r-- | submodule-config.c | 4 | ||||
-rw-r--r-- | t/helper/test-hashmap.c | 9 |
27 files changed, 621 insertions, 170 deletions
@@ -1004,6 +1004,7 @@ LIB_OBJS += stable-qsort.o LIB_OBJS += strbuf.o LIB_OBJS += streaming.o LIB_OBJS += string-list.o +LIB_OBJS += strmap.o LIB_OBJS += strvec.o LIB_OBJS += sub-process.o LIB_OBJS += submodule-config.o 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) @@ -52,13 +52,6 @@ static inline void hashmap_unlock(struct attr_hashmap *map) pthread_mutex_unlock(&map->mutex); } -/* - * The global dictionary of all interned attributes. This - * is a singleton object which is shared between threads. - * Access to this dictionary must be surrounded with a mutex. - */ -static struct attr_hashmap g_attr_hashmap; - /* The container for objects stored in "struct attr_hashmap" */ struct attr_hash_entry { struct hashmap_entry ent; @@ -80,11 +73,14 @@ static int attr_hash_entry_cmp(const void *unused_cmp_data, return (a->keylen != b->keylen) || strncmp(a->key, b->key, a->keylen); } -/* Initialize an 'attr_hashmap' object */ -static void attr_hashmap_init(struct attr_hashmap *map) -{ - hashmap_init(&map->map, attr_hash_entry_cmp, NULL, 0); -} +/* + * The global dictionary of all interned attributes. This + * is a singleton object which is shared between threads. + * Access to this dictionary must be surrounded with a mutex. + */ +static struct attr_hashmap g_attr_hashmap = { + HASHMAP_INIT(attr_hash_entry_cmp, NULL) +}; /* * Retrieve the 'value' stored in a hashmap given the provided 'key'. @@ -96,9 +92,6 @@ static void *attr_hashmap_get(struct attr_hashmap *map, struct attr_hash_entry k; struct attr_hash_entry *e; - if (!map->map.tablesize) - attr_hashmap_init(map); - hashmap_entry_init(&k.ent, memhash(key, keylen)); k.key = key; k.keylen = keylen; @@ -114,9 +107,6 @@ static void attr_hashmap_add(struct attr_hashmap *map, { struct attr_hash_entry *e; - if (!map->map.tablesize) - attr_hashmap_init(map); - e = xmalloc(sizeof(struct attr_hash_entry)); hashmap_entry_init(&e->ent, memhash(key, keylen)); e->key = key; @@ -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); } @@ -229,10 +229,9 @@ struct bloom_filter *get_or_compute_bloom_filter(struct repository *r, diffcore_std(&diffopt); if (diff_queued_diff.nr <= settings->max_changed_paths) { - struct hashmap pathmap; + struct hashmap pathmap = HASHMAP_INIT(pathmap_cmp, NULL); struct pathmap_hash_entry *e; struct hashmap_iter iter; - hashmap_init(&pathmap, pathmap_cmp, NULL, 0); for (i = 0; i < diff_queued_diff.nr; i++) { const char *path = diff_queued_diff.queue[i]->two->path; @@ -287,7 +286,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/difftool.c b/builtin/difftool.c index 7ac432b881..6e18e623fd 100644 --- a/builtin/difftool.c +++ b/builtin/difftool.c @@ -342,7 +342,10 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, const char *workdir, *tmp; int ret = 0, i; FILE *fp; - struct hashmap working_tree_dups, submodules, symlinks2; + struct hashmap working_tree_dups = HASHMAP_INIT(working_tree_entry_cmp, + NULL); + struct hashmap submodules = HASHMAP_INIT(pair_cmp, NULL); + struct hashmap symlinks2 = HASHMAP_INIT(pair_cmp, NULL); struct hashmap_iter iter; struct pair_entry *entry; struct index_state wtindex; @@ -383,10 +386,6 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, rdir_len = rdir.len; wtdir_len = wtdir.len; - hashmap_init(&working_tree_dups, working_tree_entry_cmp, NULL, 0); - hashmap_init(&submodules, pair_cmp, NULL, 0); - hashmap_init(&symlinks2, pair_cmp, NULL, 0); - child.no_stdin = 1; child.git_cmd = 1; child.use_shell = 0; 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..c52e4ccd19 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -10,6 +10,7 @@ #include "shortlog.h" #include "parse-options.h" #include "trailer.h" +#include "strmap.h" static char const * const shortlog_usage[] = { N_("git shortlog [<options>] [<revision-range>] [[--] <path>...]"), @@ -169,60 +170,6 @@ static void read_from_stdin(struct shortlog *log) strbuf_release(&oneline); } -struct strset_item { - struct hashmap_entry ent; - char value[FLEX_ARRAY]; -}; - -struct strset { - struct hashmap map; -}; - -#define STRSET_INIT { { NULL } } - -static int strset_item_hashcmp(const void *hash_data, - const struct hashmap_entry *entry, - const struct hashmap_entry *entry_or_key, - const void *keydata) -{ - const struct strset_item *a, *b; - - a = container_of(entry, const struct strset_item, ent); - if (keydata) - return strcmp(a->value, keydata); - - b = container_of(entry_or_key, const struct strset_item, ent); - return strcmp(a->value, b->value); -} - -/* - * Adds "str" to the set if it was not already present; returns true if it was - * already there. - */ -static int strset_check_and_add(struct strset *ss, const char *str) -{ - unsigned int hash = strhash(str); - struct strset_item *item; - - if (!ss->map.table) - hashmap_init(&ss->map, strset_item_hashcmp, NULL, 0); - - if (hashmap_get_from_hash(&ss->map, hash, str)) - return 1; - - FLEX_ALLOC_STR(item, value, str); - hashmap_entry_init(&item->ent, hash); - hashmap_add(&ss->map, &item->ent); - return 0; -} - -static void strset_clear(struct strset *ss) -{ - if (!ss->map.table) - return; - hashmap_free_entries(&ss->map, struct strset_item, ent); -} - static void insert_records_from_trailers(struct shortlog *log, struct strset *dups, struct commit *commit, @@ -253,7 +200,7 @@ static void insert_records_from_trailers(struct shortlog *log, if (!parse_ident(log, &ident, value)) value = ident.buf; - if (strset_check_and_add(dups, value)) + if (!strset_add(dups, value)) continue; insert_one_record(log, value, oneline); } @@ -291,7 +238,7 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit) log->email ? "%aN <%aE>" : "%aN", &ident, &ctx); if (!HAS_MULTI_BITS(log->groups) || - !strset_check_and_add(&dups, ident.buf)) + strset_add(&dups, ident.buf)) insert_one_record(log, ident.buf, oneline_str); } if (log->groups & SHORTLOG_GROUP_COMMITTER) { @@ -300,7 +247,7 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit) log->email ? "%cN <%cE>" : "%cN", &ident, &ctx); if (!HAS_MULTI_BITS(log->groups) || - !strset_check_and_add(&dups, ident.buf)) + strset_add(&dups, ident.buf)) insert_one_record(log, ident.buf, oneline_str); } if (log->groups & SHORTLOG_GROUP_TRAILER) { @@ -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; @@ -6315,9 +6315,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; } @@ -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)); } @@ -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); } @@ -113,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; @@ -133,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; @@ -148,7 +151,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; @@ -171,22 +174,37 @@ void hashmap_init(struct hashmap *map, hashmap_cmp_fn equals_function, map->do_count_items = 1; } -void hashmap_free_(struct hashmap *map, ssize_t entry_offset) +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_clear_and_free) + */ + 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_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_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_clear_(struct hashmap *map, ssize_t entry_offset) +{ + if (!map || !map->table) + return; + if (entry_offset >= 0) /* called by hashmap_clear_and_free */ + free_individual_entries(map, entry_offset); free(map->table); memset(map, 0, sizeof(*map)); } @@ -195,11 +213,13 @@ 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); } 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) @@ -210,8 +230,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; @@ -225,11 +249,15 @@ 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); + struct hashmap_entry **e; + + if (!map->table) + return NULL; + e = find_entry_ptr(map, key, keydata); if (!*e) return NULL; @@ -249,7 +277,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); @@ -96,7 +96,7 @@ * } * * if (!strcmp("end", action)) { - * hashmap_free_entries(&map, struct long2string, ent); + * hashmap_clear_and_free(&map, struct long2string, ent); * break; * } * } @@ -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. * @@ -228,24 +231,72 @@ struct hashmap { * prevent expensive resizing. If 0, the table is dynamically resized. */ void hashmap_init(struct hashmap *map, - hashmap_cmp_fn equals_function, - const void *equals_function_data, - size_t initial_size); + hashmap_cmp_fn equals_function, + const void *equals_function_data, + size_t initial_size); -/* internal function for freeing hashmap */ -void hashmap_free_(struct hashmap *map, ssize_t offset); +/* internal functions for clearing or freeing hashmap */ +void hashmap_partial_clear_(struct hashmap *map, ssize_t offset); +void hashmap_clear_(struct hashmap *map, ssize_t offset); /* - * Frees a hashmap structure and allocated memory, leaves entries undisturbed + * Frees a hashmap structure and allocated memory for the table, but does not + * free the entries nor anything they point to. + * + * Usage note: + * + * Many callers will need to iterate over all entries and free the data each + * entry points to; in such a case, they can free the entry itself while at it. + * Thus, you might see: + * + * hashmap_for_each_entry(map, hashmap_iter, e, hashmap_entry_name) { + * free(e->somefield); + * free(e); + * } + * hashmap_clear(map); + * + * instead of + * + * hashmap_for_each_entry(map, hashmap_iter, e, hashmap_entry_name) { + * free(e->somefield); + * } + * 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_clear_and_free(). */ -#define hashmap_free(map) hashmap_free_(map, -1) +#define hashmap_clear(map) hashmap_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(), 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) + +/* + * 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_clear(). + */ +#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_free_entries(map, type, member) \ - hashmap_free_(map, offsetof(type, member)); +#define hashmap_partial_clear_and_free(map, type, member) \ + hashmap_partial_clear_(map, offsetof(type, member)) /* hashmap_entry functions */ @@ -261,7 +312,7 @@ void hashmap_free_(struct hashmap *map, ssize_t offset); * and if it is on stack, you can just let it go out of scope). */ static inline void hashmap_entry_init(struct hashmap_entry *e, - unsigned int hash) + unsigned int hash) { e->hash = hash; e->next = NULL; @@ -303,8 +354,8 @@ static inline unsigned int hashmap_get_size(struct hashmap *map) * to `hashmap_cmp_fn` to decide whether the entry matches the key. */ struct hashmap_entry *hashmap_get(const struct hashmap *map, - const struct hashmap_entry *key, - const void *keydata); + const struct hashmap_entry *key, + const void *keydata); /* * Returns the hashmap entry for the specified hash code and key data, @@ -337,7 +388,7 @@ static inline struct hashmap_entry *hashmap_get_from_hash( * call to `hashmap_get` or `hashmap_get_next`. */ struct hashmap_entry *hashmap_get_next(const struct hashmap *map, - const struct hashmap_entry *entry); + const struct hashmap_entry *entry); /* * Adds a hashmap entry. This allows to add duplicate entries (i.e. @@ -357,7 +408,7 @@ void hashmap_add(struct hashmap *map, struct hashmap_entry *entry); * Returns the replaced entry, or NULL if not found (i.e. the entry was added). */ struct hashmap_entry *hashmap_put(struct hashmap *map, - struct hashmap_entry *entry); + struct hashmap_entry *entry); /* * Adds or replaces a hashmap entry contained within @keyvar, @@ -379,8 +430,8 @@ struct hashmap_entry *hashmap_put(struct hashmap *map, * Argument explanation is the same as in `hashmap_get`. */ struct hashmap_entry *hashmap_remove(struct hashmap *map, - const struct hashmap_entry *key, - const void *keydata); + const struct hashmap_entry *key, + const void *keydata); /* * Removes a hashmap entry contained within @keyvar, @@ -422,7 +473,7 @@ struct hashmap_entry *hashmap_iter_next(struct hashmap_iter *iter); /* Initializes the iterator and returns the first entry, if any. */ static inline struct hashmap_entry *hashmap_iter_first(struct hashmap *map, - struct hashmap_iter *iter) + struct hashmap_iter *iter) { hashmap_iter_init(map, iter); return hashmap_iter_next(iter); 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); } @@ -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) @@ -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..b9950f10c8 100644 --- a/range-diff.c +++ b/range-diff.c @@ -232,11 +232,9 @@ static int patch_util_cmp(const void *dummy, const struct patch_util *a, static void find_exact_matches(struct string_list *a, struct string_list *b) { - struct hashmap map; + struct hashmap map = HASHMAP_INIT((hashmap_cmp_fn)patch_util_cmp, NULL); int i; - hashmap_init(&map, (hashmap_cmp_fn)patch_util_cmp, NULL, 0); - /* First, add the patches of a to a hash map */ for (i = 0; i < a->nr; i++) { struct patch_util *util = a->items[i].util; @@ -266,7 +264,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 6476686fea..aa260bfd09 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -2230,7 +2230,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..c6e169e3eb 100644 --- a/revision.c +++ b/revision.c @@ -124,11 +124,6 @@ static int path_and_oids_cmp(const void *hashmap_cmp_fn_data, return strcmp(e1->path, e2->path); } -static void paths_and_oids_init(struct hashmap *map) -{ - hashmap_init(map, path_and_oids_cmp, NULL, 0); -} - static void paths_and_oids_clear(struct hashmap *map) { struct hashmap_iter iter; @@ -139,7 +134,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, @@ -213,7 +208,7 @@ void mark_trees_uninteresting_sparse(struct repository *r, struct oidset *trees) { unsigned has_interesting = 0, has_uninteresting = 0; - struct hashmap map; + struct hashmap map = HASHMAP_INIT(path_and_oids_cmp, NULL); struct hashmap_iter map_iter; struct path_and_oids_entry *entry; struct object_id *oid; @@ -237,8 +232,6 @@ void mark_trees_uninteresting_sparse(struct repository *r, if (!has_uninteresting || !has_interesting) return; - paths_and_oids_init(&map); - oidset_iter_init(trees, &iter); while ((oid = oidset_iter_next(&iter))) { struct tree *tree = lookup_tree(r, oid); diff --git a/sequencer.c b/sequencer.c index 221e98721d..8909a46770 100644 --- a/sequencer.c +++ b/sequencer.c @@ -5085,7 +5085,7 @@ static int make_script_with_merges(struct pretty_print_context *pp, |