aboutsummaryrefslogtreecommitdiff
path: root/src/hashmap.c
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-12-20 10:26:12 +0100
committerdec05eba <dec05eba@protonmail.com>2021-12-21 20:22:33 +0100
commit44e987c8521a99519350a42292bcfcd28451dcbd (patch)
tree699015a5dd459e96e0b19f4836f7dcffc1e347de /src/hashmap.c
parent6bb40bf0c5cd8ee8fb87640fd04b2c595f84c1d3 (diff)
Async load images
Diffstat (limited to 'src/hashmap.c')
-rw-r--r--src/hashmap.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/src/hashmap.c b/src/hashmap.c
index 1625101..4c31e46 100644
--- a/src/hashmap.c
+++ b/src/hashmap.c
@@ -13,7 +13,7 @@
#endif
#define HASH_TO_INDEX(hash) (hash & (CAP_NUM_ENTRIES(self->capacity)-1))
-#define HASHMAP_ENTRY_GET_KEY(entry) ((char*)entry + sizeof(mgui_hashmap_entry) + (entry->key_size))
+#define HASHMAP_ENTRY_GET_KEY(entry) ((char*)(entry) + sizeof(mgui_hashmap_entry))
/* |align| should be a multiple of 2 */
static size_t align_to(size_t value, size_t align) {
@@ -37,7 +37,7 @@ void mgui_hashmap_deinit(mgui_hashmap *self) {
mgui_hashmap_entry *entry = self->entries[i];
while(entry) {
mgui_hashmap_entry *next = entry->next;
- mgui_free(next);
+ mgui_free(entry);
entry = next;
}
}
@@ -129,8 +129,10 @@ bool mgui_hashmap_get(mgui_hashmap *self, const char *key, size_t key_size, void
bool mgui_hashmap_get_by_hash(mgui_hashmap *self, const char *key, size_t key_size, uint64_t hash, void **value_out) {
assert(hash == mgui_hashmap_hash(key, key_size));
- const size_t index = HASH_TO_INDEX(hash);
+ if(!self->entries)
+ return false;
+ const size_t index = HASH_TO_INDEX(hash);
mgui_hashmap_entry *entry = self->entries[index];
while(entry) {
if(hash == entry->hash && key_size == entry->key_size && memcmp(key, HASHMAP_ENTRY_GET_KEY(entry), key_size) == 0) {
@@ -153,3 +155,42 @@ uint64_t mgui_hashmap_hash(const char *data, size_t size) {
}
return hash;
}
+
+void mgui_hashmap_for_each(mgui_hashmap *self, bool(*callback)(void *value, void *userdata), void *userdata) {
+ if(!self->entries)
+ return;
+
+ for(size_t i = 0; i < CAP_NUM_ENTRIES(self->capacity); ++i) {
+ mgui_hashmap_entry *entry = self->entries[i];
+ while(entry) {
+ if(!callback(entry->value, userdata))
+ return;
+ entry = entry->next;
+ }
+ }
+}
+
+void mgui_hashmap_for_each_erase(mgui_hashmap *self, bool(*callback)(void *value, void *userdata), void *userdata) {
+ if(!self->entries)
+ return;
+
+ for(size_t i = 0; i < CAP_NUM_ENTRIES(self->capacity); ++i) {
+ mgui_hashmap_entry *entry = self->entries[i];
+ mgui_hashmap_entry *prev_entry = NULL;
+ while(entry) {
+ mgui_hashmap_entry *next = entry->next;
+ if(callback(entry->value, userdata)) {
+ /* Remove entry by replacing this entry with the next entry */
+ if(prev_entry)
+ prev_entry->next = next;
+ else
+ self->entries[i] = next;
+
+ mgui_free(entry);
+ } else {
+ prev_entry = entry;
+ }
+ entry = next;
+ }
+ }
+}