Impl. way to set custom hasher for hash_map
All checks were successful
Run Unit Tests / build-and-run-unit-tests (push) Successful in 8s
All checks were successful
Run Unit Tests / build-and-run-unit-tests (push) Successful in 8s
This commit is contained in:
parent
4a69d281de
commit
70415c6caf
2 changed files with 23 additions and 8 deletions
|
@ -74,8 +74,7 @@ int simple_archiver_hash_map_internal_pick_in_list(void *data, void *ud) {
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t simple_archiver_hash_map_internal_key_to_hash(const void *key,
|
uint64_t simple_archiver_hash_default_fn(const void *key, size_t key_size) {
|
||||||
size_t key_size) {
|
|
||||||
uint64_t seed = 0;
|
uint64_t seed = 0;
|
||||||
uint64_t temp = 0;
|
uint64_t temp = 0;
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
|
@ -106,6 +105,7 @@ int simple_archiver_hash_map_internal_rehash(SDArchiverHashMap *hash_map) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
SDArchiverHashMap new_hash_map;
|
SDArchiverHashMap new_hash_map;
|
||||||
|
new_hash_map.hash_fn = hash_map->hash_fn;
|
||||||
new_hash_map.buckets_size = hash_map->buckets_size * 2;
|
new_hash_map.buckets_size = hash_map->buckets_size * 2;
|
||||||
// Pointers have the same size (at least on the same machine), so
|
// Pointers have the same size (at least on the same machine), so
|
||||||
// sizeof(void*) should be ok.
|
// sizeof(void*) should be ok.
|
||||||
|
@ -146,7 +146,14 @@ int simple_archiver_hash_map_internal_rehash(SDArchiverHashMap *hash_map) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SDArchiverHashMap *simple_archiver_hash_map_init(void) {
|
SDArchiverHashMap *simple_archiver_hash_map_init(void) {
|
||||||
|
return simple_archiver_hash_map_init_custom_hasher(
|
||||||
|
simple_archiver_hash_default_fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDArchiverHashMap *simple_archiver_hash_map_init_custom_hasher(
|
||||||
|
uint64_t (*hash_fn)(const void *, size_t)) {
|
||||||
SDArchiverHashMap *hash_map = malloc(sizeof(SDArchiverHashMap));
|
SDArchiverHashMap *hash_map = malloc(sizeof(SDArchiverHashMap));
|
||||||
|
hash_map->hash_fn = hash_fn;
|
||||||
hash_map->buckets_size = SC_SA_DS_HASH_MAP_START_BUCKET_SIZE;
|
hash_map->buckets_size = SC_SA_DS_HASH_MAP_START_BUCKET_SIZE;
|
||||||
// Pointers have the same size (at least on the same machine), so
|
// Pointers have the same size (at least on the same machine), so
|
||||||
// sizeof(void*) should be ok.
|
// sizeof(void*) should be ok.
|
||||||
|
@ -193,8 +200,7 @@ int simple_archiver_hash_map_insert(SDArchiverHashMap *hash_map, void *value,
|
||||||
data->value_cleanup_fn = value_cleanup_fn;
|
data->value_cleanup_fn = value_cleanup_fn;
|
||||||
data->key_cleanup_fn = key_cleanup_fn;
|
data->key_cleanup_fn = key_cleanup_fn;
|
||||||
|
|
||||||
uint64_t hash = simple_archiver_hash_map_internal_key_to_hash(key, key_size) %
|
uint64_t hash = hash_map->hash_fn(key, key_size) % hash_map->buckets_size;
|
||||||
hash_map->buckets_size;
|
|
||||||
int result = simple_archiver_list_add_front(
|
int result = simple_archiver_list_add_front(
|
||||||
hash_map->buckets[hash], data,
|
hash_map->buckets[hash], data,
|
||||||
simple_archiver_hash_map_internal_cleanup_data);
|
simple_archiver_hash_map_internal_cleanup_data);
|
||||||
|
@ -225,8 +231,7 @@ int simple_archiver_hash_map_insert(SDArchiverHashMap *hash_map, void *value,
|
||||||
|
|
||||||
void *simple_archiver_hash_map_get(const SDArchiverHashMap *hash_map,
|
void *simple_archiver_hash_map_get(const SDArchiverHashMap *hash_map,
|
||||||
const void *key, size_t key_size) {
|
const void *key, size_t key_size) {
|
||||||
uint64_t hash = simple_archiver_hash_map_internal_key_to_hash(key, key_size) %
|
uint64_t hash = hash_map->hash_fn(key, key_size) % hash_map->buckets_size;
|
||||||
hash_map->buckets_size;
|
|
||||||
|
|
||||||
SDArchiverLLNode *node = hash_map->buckets[hash]->head;
|
SDArchiverLLNode *node = hash_map->buckets[hash]->head;
|
||||||
while (node) {
|
while (node) {
|
||||||
|
@ -244,8 +249,7 @@ void *simple_archiver_hash_map_get(const SDArchiverHashMap *hash_map,
|
||||||
|
|
||||||
int simple_archiver_hash_map_remove(SDArchiverHashMap *hash_map, void *key,
|
int simple_archiver_hash_map_remove(SDArchiverHashMap *hash_map, void *key,
|
||||||
size_t key_size) {
|
size_t key_size) {
|
||||||
uint64_t hash = simple_archiver_hash_map_internal_key_to_hash(key, key_size) %
|
uint64_t hash = hash_map->hash_fn(key, key_size) % hash_map->buckets_size;
|
||||||
hash_map->buckets_size;
|
|
||||||
|
|
||||||
SDArchiverHashMapKeyData key_data;
|
SDArchiverHashMapKeyData key_data;
|
||||||
key_data.key = key;
|
key_data.key = key;
|
||||||
|
|
|
@ -32,10 +32,21 @@ typedef struct SDArchiverHashMap {
|
||||||
SDArchiverLinkedList **buckets;
|
SDArchiverLinkedList **buckets;
|
||||||
size_t buckets_size;
|
size_t buckets_size;
|
||||||
size_t count;
|
size_t count;
|
||||||
|
uint64_t (*hash_fn)(const void *, size_t);
|
||||||
} SDArchiverHashMap;
|
} SDArchiverHashMap;
|
||||||
|
|
||||||
|
uint64_t simple_archiver_hash_default_fn(const void *key, size_t key_size);
|
||||||
|
|
||||||
SDArchiverHashMap *simple_archiver_hash_map_init(void);
|
SDArchiverHashMap *simple_archiver_hash_map_init(void);
|
||||||
|
|
||||||
|
/// Creates a hash map that will use the custom hash function instead of the
|
||||||
|
/// default. Note that the hash function must return a 64-bit unsigned integer
|
||||||
|
/// as specified by the function's api. The first parameter of hash_fn is a
|
||||||
|
/// pointer to the key to be hashed, and the second parameter is the size of
|
||||||
|
/// the key in bytes.
|
||||||
|
SDArchiverHashMap *simple_archiver_hash_map_init_custom_hasher(
|
||||||
|
uint64_t (*hash_fn)(const void *, size_t));
|
||||||
|
|
||||||
/// It is recommended to use the double-pointer version of hash-map free as
|
/// It is recommended to use the double-pointer version of hash-map free as
|
||||||
/// that will ensure the variable holding the pointer will end up pointing to
|
/// that will ensure the variable holding the pointer will end up pointing to
|
||||||
/// NULL after free.
|
/// NULL after free.
|
||||||
|
|
Loading…
Reference in a new issue