diff --git a/src/UDPC_Defines.h b/src/UDPC_Defines.h index 98dbe25..77088e7 100644 --- a/src/UDPC_Defines.h +++ b/src/UDPC_Defines.h @@ -49,18 +49,4 @@ static const char *UDPC_ERR_THREADFAIL_STR = "Failed to create thread"; #define UDPC_PACKET_MAX_SIZE 8192 -// 5 8 2 7 3 6 1 -// 3 2 5 1 8 7 6 -#define UDPC_HASH32(x) ( \ - ( \ - ((x & 0xF8000000) >> 5) \ - ((x & 0x07F80000) >> 6) \ - ((x & 0x00060000) << 10) \ - ((x & 0x0001FC00) >> 4) \ - ((x & 0x00000380) << 22) \ - ((x & 0x0000007E) >> 1) \ - ((x & 0x00000001) << 21) \ - ) ^ 0x96969696 \ -) - #endif diff --git a/src/UDPC_HashMap.c b/src/UDPC_HashMap.c index 19dc757..b191c5c 100644 --- a/src/UDPC_HashMap.c +++ b/src/UDPC_HashMap.c @@ -1,6 +1,7 @@ #include "UDPC_HashMap.h" #include +#include UDPC_HashMap* UDPC_HashMap_init(uint32_t capacity, uint32_t unitSize) { @@ -12,7 +13,7 @@ UDPC_HashMap* UDPC_HashMap_init(uint32_t capacity, uint32_t unitSize) int fail = 0; m->size = 0; - m->capacity = (capacity > 9 ? capacity : 10); + m->capacity = (capacity > 10 ? capacity : 10); m->unitSize = unitSize; m->buckets = malloc(sizeof(UDPC_Deque) * m->capacity); if(!m->buckets) @@ -59,11 +60,84 @@ void UDPC_HashMap_destroy(UDPC_HashMap *hashMap) { for(int x = 0; x < hashMap->capacity; ++x) { - while((hashMap->buckets + x)->size > 0) - { - UDPC_Deque_pop_back(hashMap->buckets + x, sizeof(uint32_t) + hashMap->unitSize); - } + free((hashMap->buckets + x)->buf); } free(hashMap->buckets); free(hashMap); } + +void* UDPC_HashMap_insert(UDPC_HashMap *hm, uint32_t key, void *data) +{ + uint32_t hash = UDPC_HASH32(key) % hm->capacity; + + char *temp = malloc(sizeof(uint32_t) + hm->unitSize); + memcpy(temp, &key, sizeof(uint32_t)); + memcpy(temp + sizeof(uint32_t), data, hm->unitSize); + + if(UDPC_Deque_push_back(hm->buckets + hash, temp, sizeof(uint32_t) + hm->unitSize) == 0) + { + free(temp); + return NULL; + } + + free(temp); + ++hm->size; + temp = UDPC_Deque_get_back_ptr(hm->buckets + hash, sizeof(uint32_t) + hm->unitSize); + return temp + sizeof(uint32_t); +} + +int UDPC_HashMap_remove(UDPC_HashMap *hm, uint32_t key) +{ + if(hm->size == 0) + { + return 0; + } + + uint32_t hash = UDPC_HASH32(key) % hm->capacity; + + for(int x = 0; x * (sizeof(uint32_t) + hm->unitSize) < (hm->buckets + hash)->size; ++x) + { + if(memcmp( + UDPC_Deque_index_ptr(hm->buckets + hash, sizeof(uint32_t) + hm->unitSize, x), + &key, + sizeof(uint32_t)) == 0) + { + int result = UDPC_Deque_remove(hm->buckets + hash, sizeof(uint32_t) + hm->unitSize, x); + if(result != 0) + { + --hm->size; + return 1; + } + else + { + return 0; + } + } + } + + return 0; +} + +void* UDPC_HashMap_get(UDPC_HashMap *hm, uint32_t key) +{ + if(hm->size == 0) + { + return NULL; + } + + uint32_t hash = UDPC_HASH32(key) % hm->capacity; + + for(int x = 0; x * (sizeof(uint32_t) + hm->unitSize) < (hm->buckets + hash)->size; ++x) + { + char *ptr = UDPC_Deque_index_ptr(hm->buckets + hash, sizeof(uint32_t) + hm->unitSize, x); + if(memcmp( + ptr, + &key, + sizeof(uint32_t)) == 0) + { + return ptr + sizeof(uint32_t); + } + } + + return NULL; +} diff --git a/src/UDPC_HashMap.h b/src/UDPC_HashMap.h index 2685441..46eebb3 100644 --- a/src/UDPC_HashMap.h +++ b/src/UDPC_HashMap.h @@ -1,6 +1,20 @@ #ifndef UDPC_HASHMAP_H #define UDPC_HASHMAP_H +// 5 8 2 7 3 6 1 +// 3 2 5 1 8 7 6 +#define UDPC_HASH32(x) ( \ + ( \ + ((x & 0xF8000000) >> 5) | \ + ((x & 0x07F80000) >> 6) | \ + ((x & 0x00060000) << 10) | \ + ((x & 0x0001FC00) >> 4) | \ + ((x & 0x00000380) << 22) | \ + ((x & 0x0000007E) >> 1) | \ + ((x & 0x00000001) << 21) \ + ) ^ 0x96969696 \ +) + #include "UDPC_Deque.h" typedef struct { @@ -10,8 +24,27 @@ typedef struct { UDPC_Deque *buckets; } UDPC_HashMap; +/*! + * \brief Creates a HashMap structure + * Note that UDPC_HashMap_destroy must be called on the returned ptr to free + * resources to avoid a memory leak. + * \return non-null if creating the HashMap was successful + */ UDPC_HashMap* UDPC_HashMap_init(uint32_t capacity, uint32_t unitSize); +/*! + * \brief Releases resources used by a HashMap structure + */ void UDPC_HashMap_destroy(UDPC_HashMap *hashMap); +/*! + * \brief Inserts a copy of data pointed to by given pointer + * \return Internally managed pointer to inserted data + */ +void* UDPC_HashMap_insert(UDPC_HashMap *hm, uint32_t key, void *data); + +int UDPC_HashMap_remove(UDPC_HashMap *hm, uint32_t key); + +void* UDPC_HashMap_get(UDPC_HashMap *hm, uint32_t key); + #endif