Merge branch 'ew/hashmap'

Code clean-up of the hashmap API, both users and implementation.

* ew/hashmap:
  hashmap_entry: remove first member requirement from docs
  hashmap: remove type arg from hashmap_{get,put,remove}_entry
  OFFSETOF_VAR macro to simplify hashmap iterators
  hashmap: introduce hashmap_free_entries
  hashmap: hashmap_{put,remove} return hashmap_entry *
  hashmap: use *_entry APIs for iteration
  hashmap_cmp_fn takes hashmap_entry params
  hashmap_get{,_from_hash} return "struct hashmap_entry *"
  hashmap: use *_entry APIs to wrap container_of
  hashmap_get_next returns "struct hashmap_entry *"
  introduce container_of macro
  hashmap_put takes "struct hashmap_entry *"
  hashmap_remove takes "const struct hashmap_entry *"
  hashmap_get takes "const struct hashmap_entry *"
  hashmap_add takes "struct hashmap_entry *"
  hashmap_get_next takes "const struct hashmap_entry *"
  hashmap_entry_init takes "struct hashmap_entry *"
  packfile: use hashmap_entry in delta_base_cache_entry
  coccicheck: detect hashmap_entry.hash assignment
  diff: use hashmap_entry_init on moved_entry.ent
This commit is contained in:
Junio C Hamano
2019-10-15 13:48:01 +09:00
31 changed files with 667 additions and 381 deletions

View File

@ -108,30 +108,34 @@ struct path_and_oids_entry {
};
static int path_and_oids_cmp(const void *hashmap_cmp_fn_data,
const struct path_and_oids_entry *e1,
const struct path_and_oids_entry *e2,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
const void *keydata)
{
const struct path_and_oids_entry *e1, *e2;
e1 = container_of(eptr, const struct path_and_oids_entry, ent);
e2 = container_of(entry_or_key, const struct path_and_oids_entry, ent);
return strcmp(e1->path, e2->path);
}
static void paths_and_oids_init(struct hashmap *map)
{
hashmap_init(map, (hashmap_cmp_fn) path_and_oids_cmp, NULL, 0);
hashmap_init(map, path_and_oids_cmp, NULL, 0);
}
static void paths_and_oids_clear(struct hashmap *map)
{
struct hashmap_iter iter;
struct path_and_oids_entry *entry;
hashmap_iter_init(map, &iter);
while ((entry = (struct path_and_oids_entry *)hashmap_iter_next(&iter))) {
hashmap_for_each_entry(map, &iter, entry, ent /* member name */) {
oidset_clear(&entry->trees);
free(entry->path);
}
hashmap_free(map, 1);
hashmap_free_entries(map, struct path_and_oids_entry, ent);
}
static void paths_and_oids_insert(struct hashmap *map,
@ -142,18 +146,19 @@ static void paths_and_oids_insert(struct hashmap *map,
struct path_and_oids_entry key;
struct path_and_oids_entry *entry;
hashmap_entry_init(&key, hash);
hashmap_entry_init(&key.ent, hash);
/* use a shallow copy for the lookup */
key.path = (char *)path;
oidset_init(&key.trees, 0);
if (!(entry = (struct path_and_oids_entry *)hashmap_get(map, &key, NULL))) {
entry = hashmap_get_entry(map, &key, ent, NULL);
if (!entry) {
entry = xcalloc(1, sizeof(struct path_and_oids_entry));
hashmap_entry_init(entry, hash);
hashmap_entry_init(&entry->ent, hash);
entry->path = xstrdup(key.path);
oidset_init(&entry->trees, 16);
hashmap_put(map, entry);
hashmap_put(map, &entry->ent);
}
oidset_insert(&entry->trees, oid);
@ -236,8 +241,7 @@ void mark_trees_uninteresting_sparse(struct repository *r,
add_children_by_path(r, tree, &map);
}
hashmap_iter_init(&map, &map_iter);
while ((entry = hashmap_iter_next(&map_iter)))
hashmap_for_each_entry(&map, &map_iter, entry, ent /* member name */)
mark_trees_uninteresting_sparse(r, &entry->trees);
paths_and_oids_clear(&map);