]> git.seodisparate.com - UDPConnection/commitdiff
Change HM to use overflow and individual buckets
authorStephen Seo <seo.disparate@gmail.com>
Thu, 7 Feb 2019 02:50:28 +0000 (11:50 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Thu, 7 Feb 2019 02:50:28 +0000 (11:50 +0900)
src/UDPC_HashMap.c
src/UDPC_HashMap.h

index b191c5c0b83dd540a886c518515938c216936a6b..4fe007b8f4a8445f4f4d0c9a2dfb53ea3fc8239d 100644 (file)
@@ -15,7 +15,8 @@ UDPC_HashMap* UDPC_HashMap_init(uint32_t capacity, uint32_t unitSize)
     m->size = 0;
     m->capacity = (capacity > 10 ? capacity : 10);
     m->unitSize = unitSize;
-    m->buckets = malloc(sizeof(UDPC_Deque) * m->capacity);
+
+    m->buckets = malloc(sizeof(UDPC_Deque*) * m->capacity);
     if(!m->buckets)
     {
         free(m);
@@ -26,14 +27,11 @@ UDPC_HashMap* UDPC_HashMap_init(uint32_t capacity, uint32_t unitSize)
     {
         if(fail != 0)
         {
-            (&m->buckets[x])->buf = NULL;
+            m->buckets[x] = NULL;
             continue;
         }
-
-        UDPC_Deque_clear(m->buckets + x);
-        (m->buckets + x)->alloc_size = 8 * (sizeof(uint32_t) + unitSize);
-        (m->buckets + x)->buf = malloc(8 * (sizeof(uint32_t) + unitSize));
-        if(!(m->buckets + x)->buf)
+        m->buckets[x] = UDPC_Deque_init(unitSize * UDPC_HASHMAP_BUCKET_SIZE);
+        if(!m->buckets[x])
         {
             fail = 1;
         }
@@ -43,9 +41,24 @@ UDPC_HashMap* UDPC_HashMap_init(uint32_t capacity, uint32_t unitSize)
     {
         for(int x = 0; x < m->capacity; ++x)
         {
-            if((m->buckets + x)->buf)
+            if(m->buckets[x])
+            {
+                UDPC_Deque_destroy(m->buckets[x]);
+            }
+        }
+        free(m->buckets);
+        free(m);
+        return NULL;
+    }
+
+    m->overflow = UDPC_Deque_init(unitSize * UDPC_HASHMAP_BUCKET_SIZE);
+    if(!m->overflow)
+    {
+        for(int x = 0; x < m->capacity; ++x)
+        {
+            if(m->buckets[x])
             {
-                free((m->buckets + x)->buf);
+                UDPC_Deque_destroy(m->buckets[x]);
             }
         }
         free(m->buckets);
@@ -60,7 +73,7 @@ void UDPC_HashMap_destroy(UDPC_HashMap *hashMap)
 {
     for(int x = 0; x < hashMap->capacity; ++x)
     {
-        free((hashMap->buckets + x)->buf);
+        UDPC_Deque_destroy(hashMap->buckets[x]);
     }
     free(hashMap->buckets);
     free(hashMap);
@@ -74,7 +87,15 @@ void* UDPC_HashMap_insert(UDPC_HashMap *hm, uint32_t key, void *data)
     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)
+    if(UDPC_Deque_get_available(hm->buckets[hash]) == 0)
+    {
+        if(UDPC_Deque_push_back(hm->overflow, temp, sizeof(uint32_t) + hm->unitSize) == 0)
+        {
+            free(temp);
+            return NULL;
+        }
+    }
+    else if(UDPC_Deque_push_back(hm->buckets[hash], temp, sizeof(uint32_t) + hm->unitSize) == 0)
     {
         free(temp);
         return NULL;
@@ -82,7 +103,7 @@ void* UDPC_HashMap_insert(UDPC_HashMap *hm, uint32_t key, void *data)
 
     free(temp);
     ++hm->size;
-    temp = UDPC_Deque_get_back_ptr(hm->buckets + hash, sizeof(uint32_t) + hm->unitSize);
+    temp = UDPC_Deque_get_back_ptr(hm->buckets[hash], sizeof(uint32_t) + hm->unitSize);
     return temp + sizeof(uint32_t);
 }
 
@@ -95,14 +116,34 @@ int UDPC_HashMap_remove(UDPC_HashMap *hm, uint32_t key)
 
     uint32_t hash = UDPC_HASH32(key) % hm->capacity;
 
-    for(int x = 0; x * (sizeof(uint32_t) + hm->unitSize) < (hm->buckets + hash)->size; ++x)
+    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;
+            }
+        }
+    }
+
+    for(int x = 0; x * (sizeof(uint32_t) + hm->unitSize) < hm->overflow->size; ++x)
     {
         if(memcmp(
-            UDPC_Deque_index_ptr(hm->buckets + hash, sizeof(uint32_t) + hm->unitSize, x),
+            UDPC_Deque_index_ptr(hm->overflow, 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);
+            int result = UDPC_Deque_remove(hm->overflow, sizeof(uint32_t) + hm->unitSize, x);
             if(result != 0)
             {
                 --hm->size;
@@ -127,9 +168,21 @@ void* UDPC_HashMap_get(UDPC_HashMap *hm, uint32_t key)
 
     uint32_t hash = UDPC_HASH32(key) % hm->capacity;
 
-    for(int x = 0; x * (sizeof(uint32_t) + hm->unitSize) < (hm->buckets + hash)->size; ++x)
+    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);
+        }
+    }
+
+    for(int x = 0; x * (sizeof(uint32_t) + hm->unitSize) < hm->overflow->size; ++x)
     {
-        char *ptr = UDPC_Deque_index_ptr(hm->buckets + hash, sizeof(uint32_t) + hm->unitSize, x);
+        char *ptr = UDPC_Deque_index_ptr(hm->overflow, sizeof(uint32_t) + hm->unitSize, x);
         if(memcmp(
             ptr,
             &key,
index 46eebb39223099b100c93335ee8e6d2cc7074536..5297e404502a59d0adc31f98c9247bf23f9a031f 100644 (file)
     ) ^ 0x96969696 \
 )
 
+#define UDPC_HASHMAP_BUCKET_SIZE 4
+
 #include "UDPC_Deque.h"
 
 typedef struct {
     uint32_t size;
     uint32_t capacity;
     uint32_t unitSize;
-    UDPC_Deque *buckets;
+    UDPC_Deque **buckets;
+    UDPC_Deque *overflow;
 } UDPC_HashMap;
 
 /*!