summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--add-interactive.c2
-rw-r--r--attr.c26
-rw-r--r--blame.c2
-rw-r--r--bloom.c5
-rw-r--r--builtin/difftool.c9
-rw-r--r--builtin/fetch.c6
-rw-r--r--builtin/shortlog.c61
-rw-r--r--config.c2
-rw-r--r--diff.c4
-rw-r--r--diffcore-rename.c2
-rw-r--r--dir.c8
-rw-r--r--hashmap.c74
-rw-r--r--hashmap.h91
-rw-r--r--merge-recursive.c6
-rw-r--r--name-hash.c4
-rw-r--r--object.c2
-rw-r--r--oidmap.c2
-rw-r--r--patch-ids.c2
-rw-r--r--range-diff.c6
-rw-r--r--ref-filter.c2
-rw-r--r--revision.c11
-rw-r--r--sequencer.c4
-rw-r--r--strmap.c178
-rw-r--r--strmap.h268
-rw-r--r--submodule-config.c4
-rw-r--r--t/helper/test-hashmap.c9
27 files changed, 621 insertions, 170 deletions
diff --git a/Makefile b/Makefile
index dd1cf41e00..d3a531d3c6 100644
--- a/Makefile
+++ b/Makefile
@@ -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)
diff --git a/attr.c b/attr.c
index a826b2ef1f..4ef85d668b 100644
--- a/attr.c
+++ b/attr.c
@@ -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;
diff --git a/blame.c b/blame.c
index 9156ebeafd..a5044fcfaa 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..b176f28f53 100644
--- a/bloom.c
+++ b/bloom.c
@@ -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) {
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 ace4a1d387..643f4f3f6d 100644
--- a/diff.c
+++ b/diff.c
@@ -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;
}
diff --git a/dir.c b/dir.c
index ebea5f1f91..d637461da5 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 09813e1a46..5009471800 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);
}
@@ -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);
diff --git a/hashmap.h b/hashmap.h
index b011b394fe..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;
* }
* }
@@ -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);
}
diff --git a/object.c b/object.c
index 05544bc92b..68f80b0b3d 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..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,