Added oom tests

pull/2/head
tidwall 4 years ago
parent 991b63b5c9
commit 268ea2d9e6

@ -287,6 +287,12 @@ void hashmap_free(struct hashmap *map) {
hmfree(map); hmfree(map);
} }
// hashmap_oom returns true if the last hashmap_set() call failed due to the
// system being out of memory.
bool hashmap_oom(struct hashmap *map) {
return map->oom;
}
// hashmap_scan iterates over all items in the hash map // hashmap_scan iterates over all items in the hash map
// Param `iter` can return false to stop iteration early. // Param `iter` can return false to stop iteration early.
// Returns false if the iteration has been stopped early. // Returns false if the iteration has been stopped early.
@ -476,9 +482,6 @@ uint64_t hashmap_murmur(const void *data, size_t len,
// $ cc -DHASHMAP_TEST hashmap.c && ./a.out # run tests // $ cc -DHASHMAP_TEST hashmap.c && ./a.out # run tests
// $ cc -DHASHMAP_TEST -O3 hashmap.c && BENCH=1 ./a.out # run benchmarks // $ cc -DHASHMAP_TEST -O3 hashmap.c && BENCH=1 ./a.out # run benchmarks
//============================================================================== //==============================================================================
// #ifndef HASHMAP_TEST
// #define HASHMAP_TEST
// #endif
#ifdef HASHMAP_TEST #ifdef HASHMAP_TEST
static size_t deepcount(struct hashmap *map) { static size_t deepcount(struct hashmap *map) {
@ -502,10 +505,15 @@ static size_t deepcount(struct hashmap *map) {
#include <stdio.h> #include <stdio.h>
#include "hashmap.h" #include "hashmap.h"
static bool rand_alloc_fail = false;
static int rand_alloc_fail_odds = 3; // 1 in 3 chance malloc will fail.
static uintptr_t total_allocs = 0; static uintptr_t total_allocs = 0;
static uintptr_t total_mem = 0; static uintptr_t total_mem = 0;
static void *xmalloc(size_t size) { static void *xmalloc(size_t size) {
if (rand_alloc_fail && rand()%rand_alloc_fail_odds == 0) {
return NULL;
}
void *mem = malloc(sizeof(uintptr_t)+size); void *mem = malloc(sizeof(uintptr_t)+size);
assert(mem); assert(mem);
*(uintptr_t*)mem = size; *(uintptr_t*)mem = size;
@ -553,17 +561,22 @@ static void all() {
printf("seed=%d, count=%d, item_size=%zu\n", seed, N, sizeof(int)); printf("seed=%d, count=%d, item_size=%zu\n", seed, N, sizeof(int));
srand(seed); srand(seed);
rand_alloc_fail = true;
// test sip and murmur hashes // test sip and murmur hashes
assert(hashmap_sip("hello", 5, 1, 2) == 2957200328589801622); assert(hashmap_sip("hello", 5, 1, 2) == 2957200328589801622);
assert(hashmap_murmur("hello", 5, 1, 2) == 1682575153221130884); assert(hashmap_murmur("hello", 5, 1, 2) == 1682575153221130884);
int *vals = xmalloc(N * sizeof(int)); int *vals;
while (!(vals = xmalloc(N * sizeof(int)))) {}
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
vals[i] = i; vals[i] = i;
} }
struct hashmap *map = hashmap_new(sizeof(int), 0, seed, seed, struct hashmap *map;
hash_int, compare_ints);
while (!(map = hashmap_new(sizeof(int), 0, seed, seed,
hash_int, compare_ints))) {}
shuffle(vals, N, sizeof(int)); shuffle(vals, N, sizeof(int));
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
// // printf("== %d ==\n", vals[i]); // // printf("== %d ==\n", vals[i]);
@ -573,13 +586,28 @@ static void all() {
int *v; int *v;
assert(!hashmap_get(map, &vals[i])); assert(!hashmap_get(map, &vals[i]));
assert(!hashmap_delete(map, &vals[i])); assert(!hashmap_delete(map, &vals[i]));
assert(!hashmap_set(map, &vals[i])); while (true) {
assert(!hashmap_set(map, &vals[i]));
if (!hashmap_oom(map)) {
break;
}
}
for (int j = 0; j < i; j++) { for (int j = 0; j < i; j++) {
v = hashmap_get(map, &vals[j]); v = hashmap_get(map, &vals[j]);
assert(v && *v == vals[j]); assert(v && *v == vals[j]);
} }
v = hashmap_set(map, &vals[i]); while (true) {
assert(v && *v == vals[i]); v = hashmap_set(map, &vals[i]);
if (!v) {
assert(hashmap_oom(map));
continue;
} else {
assert(!hashmap_oom(map));
assert(v && *v == vals[i]);
break;
}
}
v = hashmap_get(map, &vals[i]); v = hashmap_get(map, &vals[i]);
assert(v && *v == vals[i]); assert(v && *v == vals[i]);
v = hashmap_delete(map, &vals[i]); v = hashmap_delete(map, &vals[i]);
@ -592,7 +620,8 @@ static void all() {
assert(map->count == deepcount(map)); assert(map->count == deepcount(map));
} }
int *vals2 = xmalloc(N * sizeof(int)); int *vals2;
while (!(vals2 = xmalloc(N * sizeof(int)))) {}
memset(vals2, 0, N * sizeof(int)); memset(vals2, 0, N * sizeof(int));
assert(hashmap_scan(map, iter_ints, &vals2)); assert(hashmap_scan(map, iter_ints, &vals2));
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {

@ -18,6 +18,7 @@ struct hashmap *hashmap_new(size_t elsize, size_t cap,
int (*compare)(const void *a, const void *b)); int (*compare)(const void *a, const void *b));
void hashmap_free(struct hashmap *map); void hashmap_free(struct hashmap *map);
size_t hashmap_count(struct hashmap *map); size_t hashmap_count(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);
void *hashmap_set(struct hashmap *map, void *item); void *hashmap_set(struct hashmap *map, void *item);
void *hashmap_delete(struct hashmap *map, void *item); void *hashmap_delete(struct hashmap *map, void *item);

Loading…
Cancel
Save