Skip to content

Commit

Permalink
Update test to make it suitable for basic benchmarking and handle ran…
Browse files Browse the repository at this point in the history
…d collisions
  • Loading branch information
kg committed Apr 2, 2024
1 parent 9601de4 commit 358c8c8
Showing 1 changed file with 96 additions and 89 deletions.
185 changes: 96 additions & 89 deletions src/native/containers/dn-simdhash-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ typedef struct {

static inline uint8_t
key_comparer (instance_data_t data, size_t lhs, size_t rhs) {
return ((data.f == 4.20f) || (lhs == rhs));
return ((data.f == 4.20f) || (lhs == rhs));
}

#define DN_SIMDHASH_T dn_simdhash_size_t_size_t
Expand Down Expand Up @@ -67,7 +67,7 @@ void foreach_callback (size_t key, size_t value, void * user_data) {
}

int main () {
const int c = 10240;
const int c = 320000;
dn_simdhash_size_t_size_t_t *test = dn_simdhash_size_t_size_t_new(0, NULL);
dn_simdhash_instance_data(instance_data_t, test).f = 3.14f;
dn_simdhash_instance_data(instance_data_t, test).i = 42;
Expand All @@ -78,99 +78,106 @@ int main () {
srand(1);

for (int i = 0; i < c; i++) {
DN_SIMDHASH_KEY_T key = rand();
dn_vector_push_back(keys, key);
DN_SIMDHASH_VALUE_T value = (i * 2) + 1;
dn_vector_push_back(values, value);

uint8_t ok = dn_simdhash_size_t_size_t_try_add(test, key, value);
tassert(ok, "Insert failed");
}

if (!tasserteq(dn_simdhash_count(test), c, "count did not match"))
return 1;

printf("Calling foreach:\n");
uint32_t foreach_count = 0;
dn_simdhash_size_t_size_t_foreach(test, foreach_callback, &foreach_count);
printf("Foreach iterated %u time(s)\n", foreach_count);
printf("Count: %u, Capacity: %u, Cascaded item count: %u\n", dn_simdhash_count(test), dn_simdhash_capacity(test), count_cascaded_buckets(test));

for (int i = 0; i < c; i++) {
DN_SIMDHASH_KEY_T key = *dn_vector_index_t(keys, DN_SIMDHASH_KEY_T, i);
DN_SIMDHASH_VALUE_T value, expected_value = *dn_vector_index_t(values, DN_SIMDHASH_VALUE_T, i);

uint8_t ok = dn_simdhash_size_t_size_t_try_get_value(test, key, &value);
if (tassert1(ok, key, "did not find key"))
tasserteq(value, expected_value, "value did not match");
}

// NOTE: Adding duplicates could grow the table if we're unlucky, since the add operation
// eagerly grows before doing a table scan if we're at the grow threshold.
for (int i = 0; i < c; i++) {
DN_SIMDHASH_KEY_T key = *dn_vector_index_t(keys, DN_SIMDHASH_KEY_T, i);
DN_SIMDHASH_VALUE_T value = *dn_vector_index_t(values, DN_SIMDHASH_VALUE_T, i);
DN_SIMDHASH_KEY_T key;

retry: {
key = rand();
uint8_t ok = dn_simdhash_size_t_size_t_try_add(test, key, value);
tassert1(!ok, key, "added duplicate key successfully");
}

printf("After adding dupes: Count: %u, Capacity: %u, Cascaded item count: %u\n", dn_simdhash_count(test), dn_simdhash_capacity(test), count_cascaded_buckets(test));
uint32_t final_capacity = dn_simdhash_capacity(test);

for (int i = 0; i < c; i++) {
DN_SIMDHASH_KEY_T key = *dn_vector_index_t(keys, DN_SIMDHASH_KEY_T, i);
uint8_t ok = dn_simdhash_size_t_size_t_try_remove(test, key);
tassert1(ok, key, "could not remove key");

DN_SIMDHASH_VALUE_T value;
ok = dn_simdhash_size_t_size_t_try_get_value(test, key, &value);
tassert1(!ok, key, "found key after removal");
}

if (!tasserteq(dn_simdhash_count(test), 0, "was not empty"))
return 1;
if (!tasserteq(dn_simdhash_capacity(test), final_capacity, "capacity changed by emptying"))
return 1;

printf ("Calling foreach after emptying:\n");
foreach_count = 0;
dn_simdhash_size_t_size_t_foreach(test, foreach_callback, &foreach_count);
printf("Foreach iterated %u time(s)\n", foreach_count);
printf("Count: %u, Capacity: %u, Cascaded item count: %u\n", dn_simdhash_count(test), dn_simdhash_capacity(test), count_cascaded_buckets(test));

for (int i = 0; i < c; i++) {
DN_SIMDHASH_KEY_T key = *dn_vector_index_t(keys, DN_SIMDHASH_KEY_T, i);
DN_SIMDHASH_VALUE_T value;
uint8_t ok = dn_simdhash_size_t_size_t_try_get_value(test, key, &value);
tassert1(!ok, key, "found key after removal");
}

for (int i = 0; i < c; i++) {
DN_SIMDHASH_KEY_T key = *dn_vector_index_t(keys, DN_SIMDHASH_KEY_T, i);
DN_SIMDHASH_VALUE_T value = *dn_vector_index_t(values, DN_SIMDHASH_VALUE_T, i);

uint8_t ok = dn_simdhash_size_t_size_t_try_add(test, key, value);
tassert1(ok, key, "could not re-insert key after emptying");
}

if (!tasserteq(dn_simdhash_capacity(test), final_capacity, "expected capacity not to change after refilling"))
return 1;

for (int i = 0; i < c; i++) {
DN_SIMDHASH_KEY_T key = *dn_vector_index_t(keys, DN_SIMDHASH_KEY_T, i);
DN_SIMDHASH_VALUE_T value, expected_value = *dn_vector_index_t(values, DN_SIMDHASH_VALUE_T, i);
if (!ok)
goto retry;
}

uint8_t ok = dn_simdhash_size_t_size_t_try_get_value(test, key, &value);
if (tassert1(ok, key, "did not find key after refilling"))
tasserteq(value, expected_value, "value did not match after refilling");
dn_vector_push_back(keys, key);
dn_vector_push_back(values, value);
}

printf("Calling foreach after refilling:\n");
foreach_count = 0;
dn_simdhash_size_t_size_t_foreach(test, foreach_callback, &foreach_count);
printf("Foreach iterated %u time(s)\n", foreach_count);
printf("Count: %u, Capacity: %u, Cascaded item count: %u\n", dn_simdhash_count(test), dn_simdhash_capacity(test), count_cascaded_buckets(test));
for (int iter = 0; iter < 100; iter++) {
if (!tasserteq(dn_simdhash_count(test), c, "count did not match"))
return 1;

printf("Calling foreach:\n");
uint32_t foreach_count = 0;
dn_simdhash_size_t_size_t_foreach(test, foreach_callback, &foreach_count);
printf("Foreach iterated %u time(s)\n", foreach_count);
printf("Count: %u, Capacity: %u, Cascaded item count: %u\n", dn_simdhash_count(test), dn_simdhash_capacity(test), count_cascaded_buckets(test));

for (int i = 0; i < c; i++) {
DN_SIMDHASH_KEY_T key = *dn_vector_index_t(keys, DN_SIMDHASH_KEY_T, i);
DN_SIMDHASH_VALUE_T value, expected_value = *dn_vector_index_t(values, DN_SIMDHASH_VALUE_T, i);

uint8_t ok = dn_simdhash_size_t_size_t_try_get_value(test, key, &value);
if (tassert1(ok, key, "did not find key"))
tasserteq(value, expected_value, "value did not match");
}

// NOTE: Adding duplicates could grow the table if we're unlucky, since the add operation
// eagerly grows before doing a table scan if we're at the grow threshold.
for (int i = 0; i < c; i++) {
DN_SIMDHASH_KEY_T key = *dn_vector_index_t(keys, DN_SIMDHASH_KEY_T, i);
DN_SIMDHASH_VALUE_T value = *dn_vector_index_t(values, DN_SIMDHASH_VALUE_T, i);

uint8_t ok = dn_simdhash_size_t_size_t_try_add(test, key, value);
tassert1(!ok, key, "added duplicate key successfully");
}

printf("After adding dupes: Count: %u, Capacity: %u, Cascaded item count: %u\n", dn_simdhash_count(test), dn_simdhash_capacity(test), count_cascaded_buckets(test));
uint32_t final_capacity = dn_simdhash_capacity(test);

for (int i = 0; i < c; i++) {
DN_SIMDHASH_KEY_T key = *dn_vector_index_t(keys, DN_SIMDHASH_KEY_T, i);
uint8_t ok = dn_simdhash_size_t_size_t_try_remove(test, key);
tassert1(ok, key, "could not remove key");

DN_SIMDHASH_VALUE_T value;
ok = dn_simdhash_size_t_size_t_try_get_value(test, key, &value);
tassert1(!ok, key, "found key after removal");
}

if (!tasserteq(dn_simdhash_count(test), 0, "was not empty"))
return 1;
if (!tasserteq(dn_simdhash_capacity(test), final_capacity, "capacity changed by emptying"))
return 1;

printf ("Calling foreach after emptying:\n");
foreach_count = 0;
dn_simdhash_size_t_size_t_foreach(test, foreach_callback, &foreach_count);
printf("Foreach iterated %u time(s)\n", foreach_count);
printf("Count: %u, Capacity: %u, Cascaded item count: %u\n", dn_simdhash_count(test), dn_simdhash_capacity(test), count_cascaded_buckets(test));

for (int i = 0; i < c; i++) {
DN_SIMDHASH_KEY_T key = *dn_vector_index_t(keys, DN_SIMDHASH_KEY_T, i);
DN_SIMDHASH_VALUE_T value;
uint8_t ok = dn_simdhash_size_t_size_t_try_get_value(test, key, &value);
tassert1(!ok, key, "found key after removal");
}

for (int i = 0; i < c; i++) {
DN_SIMDHASH_KEY_T key = *dn_vector_index_t(keys, DN_SIMDHASH_KEY_T, i);
DN_SIMDHASH_VALUE_T value = *dn_vector_index_t(values, DN_SIMDHASH_VALUE_T, i);

uint8_t ok = dn_simdhash_size_t_size_t_try_add(test, key, value);
tassert1(ok, key, "could not re-insert key after emptying");
}

if (!tasserteq(dn_simdhash_capacity(test), final_capacity, "expected capacity not to change after refilling"))
return 1;

for (int i = 0; i < c; i++) {
DN_SIMDHASH_KEY_T key = *dn_vector_index_t(keys, DN_SIMDHASH_KEY_T, i);
DN_SIMDHASH_VALUE_T value, expected_value = *dn_vector_index_t(values, DN_SIMDHASH_VALUE_T, i);

uint8_t ok = dn_simdhash_size_t_size_t_try_get_value(test, key, &value);
if (tassert1(ok, key, "did not find key after refilling"))
tasserteq(value, expected_value, "value did not match after refilling");
}

printf("Calling foreach after refilling:\n");
foreach_count = 0;
dn_simdhash_size_t_size_t_foreach(test, foreach_callback, &foreach_count);
printf("Foreach iterated %u time(s)\n", foreach_count);
printf("Count: %u, Capacity: %u, Cascaded item count: %u\n", dn_simdhash_count(test), dn_simdhash_capacity(test), count_cascaded_buckets(test));
}

printf("done\n");

Expand Down

0 comments on commit 358c8c8

Please sign in to comment.