#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
#include "UDPC_HashMap.h"
#include <stdlib.h>
+#include <string.h>
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)
{
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;
+}
#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 {
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