added rehashing to maps by using clone function

Fri, 05 Oct 2012 14:06:40 +0200

author
Mike Becker <universe@uap-core.de>
date
Fri, 05 Oct 2012 14:06:40 +0200
changeset 51
1c78cd19fb6b
parent 50
ff194559eb41
child 52
34f50d0bada4

added rehashing to maps by using clone function

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 13:23:25 2012 +0200
+++ b/test/main.c	Fri Oct 05 14:06:40 2012 +0200
@@ -150,6 +150,7 @@
         ucx_test_register(suite, test_ucx_map_store_load);
         ucx_test_register(suite, test_ucx_map_store_load_with_mempool);
         ucx_test_register(suite, test_ucx_map_clone);
+        ucx_test_register(suite, test_ucx_map_rehash);
         
         /* sstring Tests */
         ucx_test_register(suite, test_sstr);
--- a/test/map_tests.c	Fri Oct 05 13:23:25 2012 +0200
+++ b/test/map_tests.c	Fri Oct 05 14:06:40 2012 +0200
@@ -285,3 +285,38 @@
     ucx_map_free(map);
     ucx_map_free(clone);
 }
+
+UCX_TEST_IMPLEMENT(test_ucx_map_rehash) {
+    UcxMap *map = ucx_map_new(4);
+
+    char keys[10][5];
+    char values[10][7];
+    for (int i = 0 ; i < 10 ; i++) {
+        strcpy(keys[i], "key");
+        keys[i][3] = 48+i; keys[i][4] = 0;
+        strcpy(values[i], "value");
+        values[i][5] = 48+i; values[i][6] = 0;
+
+        ucx_map_cstr_put(map, keys[i], values[i]);
+    }
+
+    map = ucx_map_rehash(map);
+
+    UCX_TEST_BEGIN
+    UCX_TEST_ASSERT(map->size == 25, "new capacity shall be 2.5 * count");
+    UCX_TEST_ASSERT(map->count == 10, "new map element count incorrect");
+    for (int i = 0 ; i < 10 ; i++) {
+        char *value = ucx_map_cstr_get(map, keys[i]);
+        UCX_TEST_ASSERT(value != NULL, "new map is missing old keys");
+        UCX_TEST_ASSERT(strncmp(value, values[i], 6) == 0,
+                "new map contains incorrect values");
+    }
+    UcxMap *samemap = ucx_map_rehash(map);
+    UCX_TEST_ASSERT(samemap == map,
+            "subsequent rehashing call shall do nothing");
+    UCX_TEST_ASSERT(samemap->size == 25,
+            "subsequent rehashing call shall not change size");
+    UCX_TEST_END
+
+    ucx_map_free(map);
+}
--- a/test/map_tests.h	Fri Oct 05 13:23:25 2012 +0200
+++ b/test/map_tests.h	Fri Oct 05 14:06:40 2012 +0200
@@ -21,6 +21,7 @@
 UCX_TEST_DECLARE(test_ucx_map_store_load)
 UCX_TEST_DECLARE(test_ucx_map_store_load_with_mempool)
 UCX_TEST_DECLARE(test_ucx_map_clone)
+UCX_TEST_DECLARE(test_ucx_map_rehash)
 
 
 #ifdef	__cplusplus
--- a/ucx/map.c	Fri Oct 05 13:23:25 2012 +0200
+++ b/ucx/map.c	Fri Oct 05 14:06:40 2012 +0200
@@ -45,7 +45,7 @@
 }
 
 UcxMap *ucx_map_clone(UcxMap *map, copy_func fnc, void *data) {
-    size_t bs = (map->count * 5) >> 2;
+    size_t bs = (map->count * 5) >> 1;
     UcxMap *newmap = ucx_map_new(bs > map->size ? bs : map->size);
     UcxMapIterator i = ucx_map_iterator(map);
     void *value;
@@ -55,6 +55,17 @@
     return newmap;
 }
 
+UcxMap *ucx_map_rehash(UcxMap *map) {
+    size_t load = (map->size * 3) >> 2;
+    if (map->count > load) {
+        UcxMap *newmap = ucx_map_clone(map, NULL, NULL);
+        ucx_map_free(map);
+        return newmap;
+    } else {
+        return map;
+    }
+}
+
 int ucx_map_put(UcxMap *map, UcxKey key, void *data) {
     if(key.hash == 0) {
         key.hash = ucx_hash((char*)key.data, key.len);
--- a/ucx/map.h	Fri Oct 05 13:23:25 2012 +0200
+++ b/ucx/map.h	Fri Oct 05 14:06:40 2012 +0200
@@ -57,7 +57,9 @@
 
 UcxMap *ucx_map_new(size_t size);
 void ucx_map_free(UcxMap *map);
+/* you cannot clone maps with more than 390 mio entries */
 UcxMap *ucx_map_clone(UcxMap *map, copy_func fnc, void *data);
+UcxMap *ucx_map_rehash(UcxMap *map);
 
 int ucx_map_put(UcxMap *map, UcxKey key, void *data);
 void* ucx_map_get(UcxMap *map, UcxKey key);

mercurial