Added hashmap_clear function

hashmap_clear quickly clears the map.
When the update_cap is provided, the map's capacity will be
updated to match the currently number of allocated buckets.
This is an optimization to ensure that this operation does
not perform any allocations.

closes #1
pull/13/head v0.3.0
tidwall 4 years ago
parent 3db84f0b0a
commit 9dd095ec1b

@ -129,6 +129,29 @@ struct hashmap *hashmap_new(size_t elsize, size_t cap,
return map; return map;
} }
// hashmap_clear quickly clears the map.
// When the update_cap is provided, the map's capacity will be updated to match
// the currently number of allocated buckets. This is an optimization to ensure
// that this operation does not perform any allocations.
void hashmap_clear(struct hashmap *map, bool update_cap) {
map->count = 0;
if (update_cap) {
map->cap = map->nbuckets;
} else if (map->nbuckets != map->cap) {
void *new_buckets = hmmalloc(map->bucketsz*map->cap);
if (new_buckets) {
hmfree(map->buckets);
map->buckets = new_buckets;
}
map->nbuckets = map->cap;
}
memset(map->buckets, 0, map->bucketsz*map->nbuckets);
map->mask = map->nbuckets-1;
map->growat = map->nbuckets*0.75;
map->shrinkat = map->nbuckets*0.10;
}
static bool resize(struct hashmap *map, size_t new_cap) { static bool resize(struct hashmap *map, size_t new_cap) {
struct hashmap *map2 = hashmap_new(map->elsize, new_cap, map->seed1, struct hashmap *map2 = hashmap_new(map->elsize, new_cap, map->seed1,
map->seed1, map->hash, map->compare, map->seed1, map->hash, map->compare,
@ -666,6 +689,36 @@ static void all() {
assert(v && *v == vals[j]); assert(v && *v == vals[j]);
} }
} }
for (int i = 0; i < N; i++) {
while (true) {
assert(!hashmap_set(map, &vals[i]));
if (!hashmap_oom(map)) {
break;
}
}
}
assert(map->count != 0);
size_t prev_cap = map->cap;
hashmap_clear(map, true);
assert(prev_cap < map->cap);
assert(map->count == 0);
for (int i = 0; i < N; i++) {
while (true) {
assert(!hashmap_set(map, &vals[i]));
if (!hashmap_oom(map)) {
break;
}
}
}
prev_cap = map->cap;
hashmap_clear(map, false);
assert(prev_cap == map->cap);
hashmap_free(map); hashmap_free(map);
xfree(vals); xfree(vals);

@ -19,6 +19,7 @@ struct hashmap *hashmap_new(size_t elsize, size_t cap,
void *udata), void *udata),
void *udata); void *udata);
void hashmap_free(struct hashmap *map); void hashmap_free(struct hashmap *map);
void hashmap_clear(struct hashmap *map, bool update_cap);
size_t hashmap_count(struct hashmap *map); size_t hashmap_count(struct hashmap *map);
bool hashmap_oom(struct hashmap *map); bool hashmap_oom(struct hashmap *map);
void *hashmap_get(struct hashmap *map, void *item); void *hashmap_get(struct hashmap *map, void *item);

Loading…
Cancel
Save