added ucx_map_remove

Mon, 08 Oct 2012 12:29:27 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 08 Oct 2012 12:29:27 +0200
changeset 53
e533c170bfb8
parent 52
34f50d0bada4
child 54
f634f790661a

added ucx_map_remove

test/main.c file | annotate | diff | comparison | revisions
test/map_tests.c file | annotate | diff | comparison | revisions
test/map_tests.h file | annotate | diff | comparison | revisions
ucx/map.c file | annotate | diff | comparison | revisions
ucx/map.h file | annotate | diff | comparison | revisions
--- a/test/main.c	Fri Oct 05 16:59:14 2012 +0200
+++ b/test/main.c	Mon Oct 08 12:29:27 2012 +0200
@@ -145,6 +145,7 @@
         ucx_test_register(suite, test_ucx_key);
         ucx_test_register(suite, test_ucx_map_put);
         ucx_test_register(suite, test_ucx_map_get);
+        ucx_test_register(suite, test_ucx_map_remove);
         ucx_test_register(suite, test_ucx_map_iterator);
         ucx_test_register(suite, test_ucx_map_iterator_chain);
         ucx_test_register(suite, test_ucx_map_store_load);
--- a/test/map_tests.c	Fri Oct 05 16:59:14 2012 +0200
+++ b/test/map_tests.c	Mon Oct 08 12:29:27 2012 +0200
@@ -95,6 +95,47 @@
     UCX_TEST_ASSERT(td[3] == 11200, "failed key 3");
     UCX_TEST_ASSERT(td[4] == 80000, "failed key 4");
 
+    UCX_TEST_ASSERT(map->count == 5, "expected 5 remaining values");
+    UCX_TEST_ASSERT(ucx_map_cstr_get(map, "Key0") != NULL, "element removed");
+
+    UCX_TEST_END
+    ucx_map_free(map);
+}
+
+UCX_TEST_IMPLEMENT(test_ucx_map_remove) {
+    UcxMap *map = ucx_map_new(4);
+
+    int td[5];
+    td[0] = 10; td[1] = 42; td[2] = 70; td[3] = 11200; td[4] = 80000;
+
+    ucx_map_cstr_put(map, "Key2", &td[2]); /* 0 */
+    ucx_map_cstr_put(map, "Key0", &td[0]); /* 0 */
+    ucx_map_cstr_put(map, "Key1", &td[1]); /* 3 */
+    ucx_map_cstr_put(map, "KeY3", &td[3]); /* 2 */
+    ucx_map_cstr_put(map, "KEY4", &td[4]); /* 0 */
+    UCX_TEST_BEGIN
+
+    td[0] = *((int*)ucx_map_cstr_remove(map, "Key0"));
+    td[1] = *((int*)ucx_map_cstr_get(map, "Key1"));
+    td[2] = *((int*)ucx_map_cstr_remove(map, "Key2"));
+    td[3] = *((int*)ucx_map_cstr_get(map, "KeY3"));
+    td[4] = *((int*)ucx_map_cstr_get(map, "KEY4"));
+    UCX_TEST_ASSERT(td[0] == 10, "failed key 0");
+    UCX_TEST_ASSERT(td[1] == 42, "failed key 1");
+    UCX_TEST_ASSERT(td[2] == 70, "failed key 2");
+    UCX_TEST_ASSERT(td[3] == 11200, "failed key 3");
+    UCX_TEST_ASSERT(td[4] == 80000, "failed key 4");
+
+    UCX_TEST_ASSERT(map->count == 3, "expected 3 remaining values");
+    UCX_TEST_ASSERT(ucx_map_cstr_get(map, "Key0")==NULL, "element not removed");
+    UCX_TEST_ASSERT(ucx_map_cstr_get(map, "Key1")!=NULL, "element removed");
+    UCX_TEST_ASSERT(ucx_map_cstr_get(map, "Key2")==NULL, "element not removed");
+    UCX_TEST_ASSERT(ucx_map_cstr_get(map, "KeY3")!=NULL, "element removed");
+    UCX_TEST_ASSERT(ucx_map_cstr_get(map, "KEY4")!=NULL, "element removed");
+
+    UCX_TEST_ASSERT(ucx_map_cstr_remove(map, "Key2") == NULL,
+            "subsequent remove call shall return NULL");
+
     UCX_TEST_END
     ucx_map_free(map);
 }
--- a/test/map_tests.h	Fri Oct 05 16:59:14 2012 +0200
+++ b/test/map_tests.h	Mon Oct 08 12:29:27 2012 +0200
@@ -16,6 +16,7 @@
 UCX_TEST_DECLARE(test_ucx_key)
 UCX_TEST_DECLARE(test_ucx_map_put)
 UCX_TEST_DECLARE(test_ucx_map_get)
+UCX_TEST_DECLARE(test_ucx_map_remove)
 UCX_TEST_DECLARE(test_ucx_map_iterator)
 UCX_TEST_DECLARE(test_ucx_map_iterator_chain)
 UCX_TEST_DECLARE(test_ucx_map_store_load)
--- a/ucx/map.c	Fri Oct 05 16:59:14 2012 +0200
+++ b/ucx/map.c	Mon Oct 08 12:29:27 2012 +0200
@@ -106,10 +106,10 @@
             return -1;
         }
         e->key.data = NULL;
-        if (prev == NULL) {
+        if (prev) {
+            prev->next = e;
+        } else {
             map->map[slot] = e;
-        } else {
-            prev->next = e;
         }
         e->next = elm;
         elm = e;
@@ -130,25 +130,47 @@
     return 0;
 }
 
-void* ucx_map_get(UcxMap *map, UcxKey key) {
+void* ucx_map_get_and_remove(UcxMap *map, UcxKey key, _Bool remove) {
     if(key.hash == 0) {
         key.hash = ucx_hash((char*)key.data, key.len);
     }
     
-    UcxMapElement *elm = map->map[key.hash%map->size];
-    while (elm != NULL && elm->key.hash <= key.hash) {
+    size_t slot = key.hash%map->size;
+    UcxMapElement *elm = map->map[slot];
+    UcxMapElement *pelm = NULL;
+    while (elm && elm->key.hash <= key.hash) {
         if(elm->key.hash == key.hash) {
             int n = (key.len > elm->key.len) ? elm->key.len : key.len;
             if (memcmp(elm->key.data, key.data, n) == 0) {
-                return elm->data;
+                void *data = elm->data;
+                if (remove) {
+                    if (pelm) {
+                        pelm->next = elm->next;
+                    } else {
+                        map->map[slot] = elm->next;
+                    }
+                    free(elm);
+                    map->count--;
+                }
+
+                return data;
             }
         }
-        elm = elm->next;
+        pelm = elm;
+        elm = pelm->next;
     }
 
     return NULL;
 }
 
+void *ucx_map_get(UcxMap *map, UcxKey key) {
+    return ucx_map_get_and_remove(map, key, 0);
+}
+
+void *ucx_map_remove(UcxMap *map, UcxKey key) {
+    return ucx_map_get_and_remove(map, key, 1);
+}
+
 UcxKey ucx_key(void *data, size_t len) {
     UcxKey key;
     key.data = data;
--- a/ucx/map.h	Fri Oct 05 16:59:14 2012 +0200
+++ b/ucx/map.h	Mon Oct 08 12:29:27 2012 +0200
@@ -64,11 +64,14 @@
 
 int ucx_map_put(UcxMap *map, UcxKey key, void *data);
 void* ucx_map_get(UcxMap *map, UcxKey key);
+void* ucx_map_remove(UcxMap *map, UcxKey key);
 
 #define ucx_map_sstr_put(m, s, d) ucx_map_put(m, ucx_key(s.ptr, s.length), d)
 #define ucx_map_cstr_put(m, s, d) ucx_map_put(m, ucx_key(s, 1+strlen(s)), d)
 #define ucx_map_sstr_get(m, s) ucx_map_get(m, ucx_key(s.ptr, s.length))
 #define ucx_map_cstr_get(m, s) ucx_map_get(m, ucx_key(s, 1+strlen(s)))
+#define ucx_map_sstr_remove(m, s) ucx_map_remove(m, ucx_key(s.ptr, s.length))
+#define ucx_map_cstr_remove(m, s) ucx_map_remove(m, ucx_key(s, 1+strlen(s)))
 
 UcxKey ucx_key(void *data, size_t len);
 

mercurial