Add HashMapFunctionSet() to allow custom hash functions.

This commit is contained in:
Jordan Bancino 2022-10-11 09:27:34 -04:00
parent dc0a62efcf
commit 414b8d47be
4 changed files with 32 additions and 6 deletions

View file

@ -23,7 +23,7 @@ Phase 2: Building a foundation
[x] Implement an array
[x] Implement a logging facility
[x] Implement a hash map
[ ] Allow custom hash functions for each hash map
[x] Allow custom hash functions for each hash map
[x] Combine library code files
[x] Implement configuration file parsing using hash map
[x] Base64 encoding/decoding with padded/unpadded support
@ -55,6 +55,7 @@ Phase 2: Building a foundation
[x] Properly implement the command line options as stated in telodendria(8)
[ ] Remove "chroot" option, just chroot into the data dir, and make the log
file live there as well.
[ ] Allow logging to the syslog
Phase 3: Welcome to Matrix

View file

@ -1,4 +1,4 @@
.Dd $Mdocdate: October 10 2022 $
.Dd $Mdocdate: October 11 2022 $
.Dt HASHMAP 3
.Os Telodendria Project
.Sh NAME
@ -12,6 +12,8 @@
.Fn HashMapFree "HashMap *"
.Ft void
.Fn HashMapLoadSet "HashMap *" "float"
.Ft void
.Fn HashMapFunctionSet "HashMap *" "unsigned long (*) (const char *)"
.Ft void *
.Fn HashMapSet "HashMap *" "char *" "void *"
.Ft void *
@ -63,6 +65,14 @@ object is 0.75, which should be good enough for most purposes, but
if you need finer tuning, feel free to play with the max load with
this function. The changes take effect on the next insert.
.Pp
.Fn HashMapFunctionSet
allows the given hash map to use a custom hashing function. New hash
maps have a sane hashing function that should work okay for most use
cases, but if you have a better hash function, it can be specified with
this function. Do not change the hash function after keys have been
added; doing so results in undefined behavior. Only set the hash
function immediately after constructing a new hash map.
.Pp
.Fn HashMapSet
sets the given string key to the given value. Note neither the key nor the
value is copied into the hash map's own memory space; only pointers are

View file

@ -39,6 +39,8 @@ struct HashMap
size_t capacity;
HashMapBucket **entries;
unsigned long (*hashFunc) (const char *);
float maxLoad;
size_t iterator;
};
@ -60,7 +62,6 @@ HashMapHashKey(const char *key)
return hash;
}
static int
HashMapGrow(HashMap * map)
{
@ -136,6 +137,7 @@ HashMapCreate(void)
map->count = 0;
map->capacity = 16;
map->iterator = 0;
map->hashFunc = HashMapHashKey;
map->entries = calloc(map->capacity, sizeof(HashMapBucket *));
if (!map->entries)
@ -158,7 +160,7 @@ HashMapDelete(HashMap * map, const char *key)
return NULL;
}
hash = HashMapHashKey(key);
hash = map->hashFunc(key);
index = hash % map->capacity;
for (;;)
@ -212,7 +214,7 @@ HashMapGet(HashMap * map, const char *key)
return NULL;
}
hash = HashMapHashKey(key);
hash = map->hashFunc(key);
index = hash % map->capacity;
for (;;)
@ -280,6 +282,16 @@ HashMapMaxLoadSet(HashMap * map, float load)
map->maxLoad = load;
}
void
HashMapFunctionSet(HashMap * map, unsigned long (*hashFunc) (const char *))
{
if (!map || !hashFunc)
{
return;
}
map->hashFunc = hashFunc;
}
void *
HashMapSet(HashMap * map, char *key, void *value)
@ -297,7 +309,7 @@ HashMapSet(HashMap * map, char *key, void *value)
HashMapGrow(map);
}
hash = HashMapHashKey(key);
hash = map->hashFunc(key);
index = hash % map->capacity;
for (;;)

View file

@ -33,6 +33,9 @@ extern HashMap *
extern void
HashMapMaxLoadSet(HashMap *, float);
extern void
HashMapFunctionSet(HashMap *, unsigned long (*) (const char *));
extern void *
HashMapSet(HashMap *, char *, void *);