: 0;
}
-uint64_t simple_archiver_hash_map_internal_key_to_hash(const void *key,
- size_t key_size) {
+uint64_t simple_archiver_hash_default_fn(const void *key, size_t key_size) {
uint64_t seed = 0;
uint64_t temp = 0;
size_t count = 0;
return 1;
}
SDArchiverHashMap new_hash_map;
+ new_hash_map.hash_fn = hash_map->hash_fn;
new_hash_map.buckets_size = hash_map->buckets_size * 2;
// Pointers have the same size (at least on the same machine), so
// sizeof(void*) should be ok.
}
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));
+ hash_map->hash_fn = hash_fn;
hash_map->buckets_size = SC_SA_DS_HASH_MAP_START_BUCKET_SIZE;
// Pointers have the same size (at least on the same machine), so
// sizeof(void*) should be ok.
data->value_cleanup_fn = value_cleanup_fn;
data->key_cleanup_fn = key_cleanup_fn;
- uint64_t hash = simple_archiver_hash_map_internal_key_to_hash(key, key_size) %
- hash_map->buckets_size;
+ uint64_t hash = hash_map->hash_fn(key, key_size) % hash_map->buckets_size;
int result = simple_archiver_list_add_front(
hash_map->buckets[hash], data,
simple_archiver_hash_map_internal_cleanup_data);
void *simple_archiver_hash_map_get(const SDArchiverHashMap *hash_map,
const void *key, size_t key_size) {
- uint64_t hash = simple_archiver_hash_map_internal_key_to_hash(key, key_size) %
- hash_map->buckets_size;
+ uint64_t hash = hash_map->hash_fn(key, key_size) % hash_map->buckets_size;
SDArchiverLLNode *node = hash_map->buckets[hash]->head;
while (node) {
int simple_archiver_hash_map_remove(SDArchiverHashMap *hash_map, void *key,
size_t key_size) {
- uint64_t hash = simple_archiver_hash_map_internal_key_to_hash(key, key_size) %
- hash_map->buckets_size;
+ uint64_t hash = hash_map->hash_fn(key, key_size) % hash_map->buckets_size;
SDArchiverHashMapKeyData key_data;
key_data.key = key;
SDArchiverLinkedList **buckets;
size_t buckets_size;
size_t count;
+ uint64_t (*hash_fn)(const void *, size_t);
} SDArchiverHashMap;
+uint64_t simple_archiver_hash_default_fn(const void *key, size_t key_size);
+
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
/// that will ensure the variable holding the pointer will end up pointing to
/// NULL after free.