diff options
author | dec05eba <dec05eba@protonmail.com> | 2021-12-20 10:26:12 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2021-12-21 20:22:33 +0100 |
commit | 44e987c8521a99519350a42292bcfcd28451dcbd (patch) | |
tree | 699015a5dd459e96e0b19f4836f7dcffc1e347de /src/hashmap.c | |
parent | 6bb40bf0c5cd8ee8fb87640fd04b2c595f84c1d3 (diff) |
Async load images
Diffstat (limited to 'src/hashmap.c')
-rw-r--r-- | src/hashmap.c | 47 |
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; + } + } +} |