Skip to content
This repository has been archived by the owner on Mar 9, 2019. It is now read-only.

Commit

Permalink
fix size calculation for hash tables
Browse files Browse the repository at this point in the history
Addresses #44

The problem was that the compiler was producing int32_t sized results
when figuring out sizes and offsets.  Combine this with a large number
of elements (large enough to overflow 32-bits) and the table would be
allocated smaller than we needed.

This solves the problem in the fewest keystrokes by promoting the
size of a couple of fields to 64-bit, but has the side effect of
changing the size of the hashtable struct.
  • Loading branch information
wez committed Nov 27, 2013
1 parent 6f6c1a8 commit 2771014
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 8 deletions.
3 changes: 2 additions & 1 deletion include/phenom/hashtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,8 @@ struct ph_ht_elem {
};

struct ph_ht {
uint32_t nelems, table_size, elem_size, mask;
uint32_t nelems;
uint64_t table_size, elem_size, mask;
const struct ph_ht_key_def *kdef;
const struct ph_ht_val_def *vdef;
/* points to the table, an array of table_size elements */
Expand Down
24 changes: 17 additions & 7 deletions tests/hashtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,23 @@ static void load_data(ph_ht_t *ht, uint32_t howmany)

ph_ht_free_entries(ht);

if (howmany > 1000) {
// need to fix the format to allow for this many
ph_ht_grow(ht, howmany);

data = calloc(howmany, sizeof(*data));
ok(data, "allocated space");
if (!data) {
abort();
}

data = calloc(howmany, sizeof(*data));
for (i = 0; i < howmany; i++) {
data[i] = ph_string_make_printf(mt_misc, 16, "key:%04" PRIu32, i);

ph_ht_set(ht, &data[i], &data[i]);
data[i] = ph_string_make_printf(mt_misc, 16, "key:%08" PRIu32, i);
if (!data[i]) {
ok(0, "failed to create string for %" PRIu32, i);
}

if (ph_ht_set(ht, &data[i], &data[i]) != PH_OK) {
ok(0, "failed to insert item %d %.*s", i, data[i]->len, data[i]->buf);
}
}

is(ph_ht_size(ht), howmany);
Expand Down Expand Up @@ -57,7 +64,7 @@ int main(int argc, char **argv)
ph_unused_parameter(argv);

ph_library_init();
plan_tests(217);
plan_tests(221);

mt_misc = ph_memtype_register(&mt_def);

Expand Down Expand Up @@ -146,6 +153,9 @@ int main(int argc, char **argv)
load_data(&ht, 8);
load_data(&ht, 16);
load_data(&ht, 64);
// to test extreme size, uncomment this. It is too expensive to run
// as a unit test
// load_data(&ht, 100000000);

ph_ht_destroy(&ht);

Expand Down

0 comments on commit 2771014

Please sign in to comment.