Skip to content

Commit

Permalink
Add 'instant_rehashing' type flag (non-incremental)
Browse files Browse the repository at this point in the history
Signed-off-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
  • Loading branch information
zuiderkwast committed Sep 9, 2024
1 parent a4d3e07 commit de69e05
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 10 deletions.
7 changes: 7 additions & 0 deletions src/hashtab.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,9 @@ static inline void rehashStepOnWriteIfNeeded(hashtab *t) {
static int resize(hashtab *t, size_t min_capacity, int *malloc_failed) {
if (malloc_failed) *malloc_failed = 0;

/* Adjust mininum size. We don't resize to zero currently. */
if (min_capacity == 0) min_capacity = 1;

/* Size of new table. */
signed char exp = nextBucketExp(min_capacity);
size_t num_buckets = numBuckets(exp);
Expand Down Expand Up @@ -549,6 +552,10 @@ static int resize(hashtab *t, size_t min_capacity, int *malloc_failed) {
/* If the old table was empty, the rehashing is completed immediately. */
if (t->tables[0] == NULL || t->used[0] == 0) {
rehashingCompleted(t);
} else if (t->type->instant_rehashing) {
while (hashtabIsRehashing(t)) {
rehashStep(t);
}
}
return 1;
}
Expand Down
11 changes: 2 additions & 9 deletions src/hashtab.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ typedef struct {
/* Allow a hashtab to carry extra caller-defined metadata. The extra memory
* is initialized to 0. */
size_t (*getMetadataSize)(void);
/* Flag to disable incremental rehashing */
unsigned instant_rehashing : 1;
/* Allow the caller to store some data here in the type. It's useful for the
* rehashingStarted and rehashingCompleted callbacks. */
void *userdata;
Expand Down Expand Up @@ -128,15 +130,6 @@ typedef struct hashtabStats {
unsigned long *clvector;
} hashtabStats;

/* TODO:
*
* - Type flag to disable incremental rehashing.
*
* Not needed: defrag functions (solved by emit_ref in scan) */


/* --- Inline functions --- */

/* --- Prototypes --- */

/* Hash function (global seed) */
Expand Down
3 changes: 2 additions & 1 deletion src/unit/test_files.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ int test_cursor(int argc, char **argv, int flags);
int test_set_hash_function_seed(int argc, char **argv, int flags);
int test_add_find_delete(int argc, char **argv, int flags);
int test_add_find_delete_avoid_resize(int argc, char **argv, int flags);
int test_instant_rehashing(int argc, char **argv, int flags);
int test_probing_chain_length(int argc, char **argv, int flags);
int test_two_phase_insert_and_pop(int argc, char **argv, int flags);
int test_scan(int argc, char **argv, int flags);
Expand Down Expand Up @@ -152,7 +153,7 @@ unitTest __test_crc64_c[] = {{"test_crc64", test_crc64}, {NULL, NULL}};
unitTest __test_crc64combine_c[] = {{"test_crc64combine", test_crc64combine}, {NULL, NULL}};
unitTest __test_dict_c[] = {{"test_dictCreate", test_dictCreate}, {"test_dictAdd16Keys", test_dictAdd16Keys}, {"test_dictDisableResize", test_dictDisableResize}, {"test_dictAddOneKeyTriggerResize", test_dictAddOneKeyTriggerResize}, {"test_dictDeleteKeys", test_dictDeleteKeys}, {"test_dictDeleteOneKeyTriggerResize", test_dictDeleteOneKeyTriggerResize}, {"test_dictEmptyDirAdd128Keys", test_dictEmptyDirAdd128Keys}, {"test_dictDisableResizeReduceTo3", test_dictDisableResizeReduceTo3}, {"test_dictDeleteOneKeyTriggerResizeAgain", test_dictDeleteOneKeyTriggerResizeAgain}, {"test_dictBenchmark", test_dictBenchmark}, {NULL, NULL}};
unitTest __test_endianconv_c[] = {{"test_endianconv", test_endianconv}, {NULL, NULL}};
unitTest __test_hashtab_c[] = {{"test_cursor", test_cursor}, {"test_set_hash_function_seed", test_set_hash_function_seed}, {"test_add_find_delete", test_add_find_delete}, {"test_add_find_delete_avoid_resize", test_add_find_delete_avoid_resize}, {"test_probing_chain_length", test_probing_chain_length}, {"test_two_phase_insert_and_pop", test_two_phase_insert_and_pop}, {"test_scan", test_scan}, {"test_iterator", test_iterator}, {"test_safe_iterator", test_safe_iterator}, {"test_random_element", test_random_element}, {NULL, NULL}};
unitTest __test_hashtab_c[] = {{"test_cursor", test_cursor}, {"test_set_hash_function_seed", test_set_hash_function_seed}, {"test_add_find_delete", test_add_find_delete}, {"test_add_find_delete_avoid_resize", test_add_find_delete_avoid_resize}, {"test_instant_rehashing", test_instant_rehashing}, {"test_probing_chain_length", test_probing_chain_length}, {"test_two_phase_insert_and_pop", test_two_phase_insert_and_pop}, {"test_scan", test_scan}, {"test_iterator", test_iterator}, {"test_safe_iterator", test_safe_iterator}, {"test_random_element", test_random_element}, {NULL, NULL}};
unitTest __test_intset_c[] = {{"test_intsetValueEncodings", test_intsetValueEncodings}, {"test_intsetBasicAdding", test_intsetBasicAdding}, {"test_intsetLargeNumberRandomAdd", test_intsetLargeNumberRandomAdd}, {"test_intsetUpgradeFromint16Toint32", test_intsetUpgradeFromint16Toint32}, {"test_intsetUpgradeFromint16Toint64", test_intsetUpgradeFromint16Toint64}, {"test_intsetUpgradeFromint32Toint64", test_intsetUpgradeFromint32Toint64}, {"test_intsetStressLookups", test_intsetStressLookups}, {"test_intsetStressAddDelete", test_intsetStressAddDelete}, {NULL, NULL}};
unitTest __test_kvstore_c[] = {{"test_kvstoreAdd16Keys", test_kvstoreAdd16Keys}, {"test_kvstoreIteratorRemoveAllKeysNoDeleteEmptyDict", test_kvstoreIteratorRemoveAllKeysNoDeleteEmptyDict}, {"test_kvstoreIteratorRemoveAllKeysDeleteEmptyDict", test_kvstoreIteratorRemoveAllKeysDeleteEmptyDict}, {"test_kvstoreDictIteratorRemoveAllKeysNoDeleteEmptyDict", test_kvstoreDictIteratorRemoveAllKeysNoDeleteEmptyDict}, {"test_kvstoreDictIteratorRemoveAllKeysDeleteEmptyDict", test_kvstoreDictIteratorRemoveAllKeysDeleteEmptyDict}, {NULL, NULL}};
unitTest __test_listpack_c[] = {{"test_listpackCreateIntList", test_listpackCreateIntList}, {"test_listpackCreateList", test_listpackCreateList}, {"test_listpackLpPrepend", test_listpackLpPrepend}, {"test_listpackLpPrependInteger", test_listpackLpPrependInteger}, {"test_listpackGetELementAtIndex", test_listpackGetELementAtIndex}, {"test_listpackPop", test_listpackPop}, {"test_listpackGetELementAtIndex2", test_listpackGetELementAtIndex2}, {"test_listpackIterate0toEnd", test_listpackIterate0toEnd}, {"test_listpackIterate1toEnd", test_listpackIterate1toEnd}, {"test_listpackIterate2toEnd", test_listpackIterate2toEnd}, {"test_listpackIterateBackToFront", test_listpackIterateBackToFront}, {"test_listpackIterateBackToFrontWithDelete", test_listpackIterateBackToFrontWithDelete}, {"test_listpackDeleteWhenNumIsMinusOne", test_listpackDeleteWhenNumIsMinusOne}, {"test_listpackDeleteWithNegativeIndex", test_listpackDeleteWithNegativeIndex}, {"test_listpackDeleteInclusiveRange0_0", test_listpackDeleteInclusiveRange0_0}, {"test_listpackDeleteInclusiveRange0_1", test_listpackDeleteInclusiveRange0_1}, {"test_listpackDeleteInclusiveRange1_2", test_listpackDeleteInclusiveRange1_2}, {"test_listpackDeleteWitStartIndexOutOfRange", test_listpackDeleteWitStartIndexOutOfRange}, {"test_listpackDeleteWitNumOverflow", test_listpackDeleteWitNumOverflow}, {"test_listpackBatchDelete", test_listpackBatchDelete}, {"test_listpackDeleteFooWhileIterating", test_listpackDeleteFooWhileIterating}, {"test_listpackReplaceWithSameSize", test_listpackReplaceWithSameSize}, {"test_listpackReplaceWithDifferentSize", test_listpackReplaceWithDifferentSize}, {"test_listpackRegressionGt255Bytes", test_listpackRegressionGt255Bytes}, {"test_listpackCreateLongListAndCheckIndices", test_listpackCreateLongListAndCheckIndices}, {"test_listpackCompareStrsWithLpEntries", test_listpackCompareStrsWithLpEntries}, {"test_listpackLpMergeEmptyLps", test_listpackLpMergeEmptyLps}, {"test_listpackLpMergeLp1Larger", test_listpackLpMergeLp1Larger}, {"test_listpackLpMergeLp2Larger", test_listpackLpMergeLp2Larger}, {"test_listpackLpNextRandom", test_listpackLpNextRandom}, {"test_listpackLpNextRandomCC", test_listpackLpNextRandomCC}, {"test_listpackRandomPairWithOneElement", test_listpackRandomPairWithOneElement}, {"test_listpackRandomPairWithManyElements", test_listpackRandomPairWithManyElements}, {"test_listpackRandomPairsWithOneElement", test_listpackRandomPairsWithOneElement}, {"test_listpackRandomPairsWithManyElements", test_listpackRandomPairsWithManyElements}, {"test_listpackRandomPairsUniqueWithOneElement", test_listpackRandomPairsUniqueWithOneElement}, {"test_listpackRandomPairsUniqueWithManyElements", test_listpackRandomPairsUniqueWithManyElements}, {"test_listpackPushVariousEncodings", test_listpackPushVariousEncodings}, {"test_listpackLpFind", test_listpackLpFind}, {"test_listpackLpValidateIntegrity", test_listpackLpValidateIntegrity}, {"test_listpackNumberOfElementsExceedsLP_HDR_NUMELE_UNKNOWN", test_listpackNumberOfElementsExceedsLP_HDR_NUMELE_UNKNOWN}, {"test_listpackStressWithRandom", test_listpackStressWithRandom}, {"test_listpackSTressWithVariableSize", test_listpackSTressWithVariableSize}, {"test_listpackBenchmarkInit", test_listpackBenchmarkInit}, {"test_listpackBenchmarkLpAppend", test_listpackBenchmarkLpAppend}, {"test_listpackBenchmarkLpFindString", test_listpackBenchmarkLpFindString}, {"test_listpackBenchmarkLpFindNumber", test_listpackBenchmarkLpFindNumber}, {"test_listpackBenchmarkLpSeek", test_listpackBenchmarkLpSeek}, {"test_listpackBenchmarkLpValidateIntegrity", test_listpackBenchmarkLpValidateIntegrity}, {"test_listpackBenchmarkLpCompareWithString", test_listpackBenchmarkLpCompareWithString}, {"test_listpackBenchmarkLpCompareWithNumber", test_listpackBenchmarkLpCompareWithNumber}, {"test_listpackBenchmarkFree", test_listpackBenchmarkFree}, {NULL, NULL}};
Expand Down
29 changes: 29 additions & 0 deletions src/unit/test_hashtab.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,35 @@ int test_add_find_delete_avoid_resize(int argc, char **argv, int flags) {
return 0;
}

int test_instant_rehashing(int argc, char **argv, int flags) {
UNUSED(argc);
UNUSED(argv);
UNUSED(flags);

long count = 200;

/* A set of longs, i.e. pointer-sized values. */
hashtabType type = {.instant_rehashing = 1};
hashtab *t = hashtabCreate(&type);
long j;

/* Populate and check that rehashing is never ongoing. */
for (j = 0; j < count; j++) {
assert(hashtabAdd(t, (void *)j));
assert(!hashtabIsRehashing(t));
}

/* Delete and check that rehashing is never ongoing. */
for (j = 0; j < count; j++) {
assert(hashtabDelete(t, (void *)j));
assert(!hashtabIsRehashing(t));
}

hashtabRelease(t);
return 0;
}


int test_probing_chain_length(int argc, char **argv, int flags) {
UNUSED(argc);
UNUSED(argv);
Expand Down

0 comments on commit de69e05

Please sign in to comment.