Ver Fonte

Basic (slow) hash map remove

Kajetan Johannes Hammerle há 11 meses atrás
pai
commit
f9141e4563
3 ficheiros alterados com 44 adições e 15 exclusões
  1. 3 0
      include/core/HashMap.h
  2. 22 0
      src/HashMap.c
  3. 19 15
      test/modules/HashMapTests.c

+ 3 - 0
include/core/HashMap.h

@@ -34,6 +34,9 @@ bool coreHashMapContainsPointer(const CoreHashMap* m, const void* key);
 #define coreHashMapContains(m, kType, key)                                     \
     coreHashMapContainsPointer(m, &(kType){key})
 void coreClearHashMap(CoreHashMap* m);
+bool coreHashMapRemovePointer(CoreHashMap* m, const void* key);
+#define coreHashMapRemove(m, kType, key)                                       \
+    coreHashMapRemovePointer(m, &(kType){key})
 size_t coreToStringHashMap(const CoreHashMap* m, char* buffer, size_t n,
                            CoreToString keyString, CoreToString valueString);
 void coreSwapHashMap(CoreHashMap* a, CoreHashMap* b);

+ 22 - 0
src/HashMap.c

@@ -149,6 +149,28 @@ void coreClearHashMap(CoreHashMap* m) {
     memset(getKey(m, m->capacity - 1), 1, m->keySize);
 }
 
+bool coreHashMapRemovePointer(CoreHashMap* m, const void* key) {
+    // ToDo: This is a very slow remove
+    CoreHashMap n =
+        CORE_HASH_MAP(m->keySize, m->valueSize, m->hasher, m->equal);
+    CoreHashMapIterator i = CORE_HASH_MAP_ITERATOR(m);
+    bool r = false;
+    while(true) {
+        CoreHashMapNode* node = coreHashMapNext(&i);
+        if(node == nullptr) {
+            break;
+        }
+        if(!m->equal(key, node->key, n.keySize)) {
+            coreHashMapPutPointer(&n, node->key, node->value);
+        } else {
+            r = true;
+        }
+    }
+    coreSwapHashMap(&n, m);
+    coreDestroyHashMap(&n);
+    return r;
+}
+
 size_t coreToStringHashMap(const CoreHashMap* m, char* buffer, size_t n,
                            CoreToString keyString, CoreToString valueString) {
     size_t w = 0;

+ 19 - 15
test/modules/HashMapTests.c

@@ -180,21 +180,25 @@ static void testAddCollisions() {
 }
 
 static void testRemove() {
-    //     IntMap map;
-    //     map.add(1, 3).add(2, 4).add(3, 5);
-    //
-    //     CORE_TEST_TRUE(map.remove(2));
-    //     CORE_TEST_FALSE(map.remove(7));
-    //
-    //     int* a = coreHashMapSearch(&map,int,1);
-    //     int* b = coreHashMapSearch(&map,int,2);
-    //     int* c = coreHashMapSearch(&map,int,3);
-    //
-    //     CORE_TEST_NULL(b);
-    //     if(CORE_TEST_NOT_NULL(a) && CORE_TEST_NOT_NULL(c)) {
-    //         CORE_TEST_EQUAL(3, *a);
-    //         CORE_TEST_EQUAL(5, *c);
-    //     }
+    CoreHashMap map = INT_MAP;
+    coreHashMapPut(&map, int, 1, int, 3);
+    coreHashMapPut(&map, int, 2, int, 4);
+    coreHashMapPut(&map, int, 3, int, 5);
+
+    CORE_TEST_TRUE(coreHashMapRemove(&map, size_t, 2));
+    CORE_TEST_FALSE(coreHashMapRemove(&map, size_t, 7));
+
+    int* a = coreHashMapSearch(&map, int, 1, int);
+    int* b = coreHashMapSearch(&map, int, 2, int);
+    int* c = coreHashMapSearch(&map, int, 3, int);
+
+    CORE_TEST_NULL(b);
+    if(CORE_TEST_NOT_NULL(a) && CORE_TEST_NOT_NULL(c)) {
+        CORE_TEST_INT(3, *a);
+        CORE_TEST_INT(5, *c);
+    }
+
+    coreDestroyHashMap(&map);
 }
 
 static void testHash() {