mirror of
https://github.com/git/git.git
synced 2026-03-04 14:37:35 +01:00
Replace oidmap's use of hashmap_clear_() and layout-dependent freeing with an explicit iteration and optional free callback. This removes reliance on struct layout assumptions while keeping the existing API intact. Add tests for oidmap_clear_with_free behavior. test_oidmap__clear_with_free_callback verifies that entries are freed when a callback is provided, while test_oidmap__clear_without_free_callback verifies that entries are not freed when no callback is given. These tests ensure the new clear implementation behaves correctly and preserves ownership semantics. Signed-off-by: Seyi Kuforiji <kuforiji98@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
80 lines
1.8 KiB
C
80 lines
1.8 KiB
C
#include "git-compat-util.h"
|
|
#include "hash.h"
|
|
#include "oidmap.h"
|
|
|
|
static int oidmap_neq(const void *hashmap_cmp_fn_data UNUSED,
|
|
const struct hashmap_entry *e1,
|
|
const struct hashmap_entry *e2,
|
|
const void *keydata)
|
|
{
|
|
const struct oidmap_entry *a, *b;
|
|
|
|
a = container_of(e1, const struct oidmap_entry, internal_entry);
|
|
b = container_of(e2, const struct oidmap_entry, internal_entry);
|
|
|
|
if (keydata)
|
|
return !oideq(&a->oid, (const struct object_id *) keydata);
|
|
return !oideq(&a->oid, &b->oid);
|
|
}
|
|
|
|
void oidmap_init(struct oidmap *map, size_t initial_size)
|
|
{
|
|
hashmap_init(&map->map, oidmap_neq, NULL, initial_size);
|
|
}
|
|
|
|
void oidmap_clear(struct oidmap *map, int free_entries)
|
|
{
|
|
oidmap_clear_with_free(map,
|
|
free_entries ? free : NULL);
|
|
}
|
|
|
|
void oidmap_clear_with_free(struct oidmap *map,
|
|
oidmap_free_fn free_fn)
|
|
{
|
|
struct hashmap_iter iter;
|
|
struct hashmap_entry *e;
|
|
|
|
if (!map || !map->map.cmpfn)
|
|
return;
|
|
|
|
hashmap_iter_init(&map->map, &iter);
|
|
while ((e = hashmap_iter_next(&iter))) {
|
|
struct oidmap_entry *entry =
|
|
container_of(e, struct oidmap_entry, internal_entry);
|
|
if (free_fn)
|
|
free_fn(entry);
|
|
}
|
|
|
|
hashmap_clear(&map->map);
|
|
}
|
|
|
|
void *oidmap_get(const struct oidmap *map, const struct object_id *key)
|
|
{
|
|
if (!map->map.cmpfn)
|
|
return NULL;
|
|
|
|
return hashmap_get_from_hash(&map->map, oidhash(key), key);
|
|
}
|
|
|
|
void *oidmap_remove(struct oidmap *map, const struct object_id *key)
|
|
{
|
|
struct hashmap_entry entry;
|
|
|
|
if (!map->map.cmpfn)
|
|
oidmap_init(map, 0);
|
|
|
|
hashmap_entry_init(&entry, oidhash(key));
|
|
return hashmap_remove(&map->map, &entry, key);
|
|
}
|
|
|
|
void *oidmap_put(struct oidmap *map, void *entry)
|
|
{
|
|
struct oidmap_entry *to_put = entry;
|
|
|
|
if (!map->map.cmpfn)
|
|
oidmap_init(map, 0);
|
|
|
|
hashmap_entry_init(&to_put->internal_entry, oidhash(&to_put->oid));
|
|
return hashmap_put(&map->map, &to_put->internal_entry);
|
|
}
|