added ucx_map_copy and fixed ucx_map_rehash

Fri, 05 Oct 2012 16:59:14 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 05 Oct 2012 16:59:14 +0200
changeset 52
34f50d0bada4
parent 51
1c78cd19fb6b
child 53
e533c170bfb8

added ucx_map_copy and fixed ucx_map_rehash

test/map_tests.c file | annotate | diff | comparison | revisions
ucx/allocator.c file | annotate | diff | comparison | revisions
ucx/allocator.h file | annotate | diff | comparison | revisions
ucx/map.c file | annotate | diff | comparison | revisions
ucx/map.h file | annotate | diff | comparison | revisions
--- a/test/map_tests.c	Fri Oct 05 14:06:40 2012 +0200
+++ b/test/map_tests.c	Fri Oct 05 16:59:14 2012 +0200
@@ -300,7 +300,7 @@
         ucx_map_cstr_put(map, keys[i], values[i]);
     }
 
-    map = ucx_map_rehash(map);
+    ucx_map_rehash(map);
 
     UCX_TEST_BEGIN
     UCX_TEST_ASSERT(map->size == 25, "new capacity shall be 2.5 * count");
@@ -311,10 +311,8 @@
         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,
+    ucx_map_rehash(map);
+    UCX_TEST_ASSERT(map->size == 25,
             "subsequent rehashing call shall not change size");
     UCX_TEST_END
 
--- a/ucx/allocator.c	Fri Oct 05 14:06:40 2012 +0200
+++ b/ucx/allocator.c	Fri Oct 05 16:59:14 2012 +0200
@@ -1,12 +1,14 @@
-#include "allocator.h"
-#include <stdlib.h>
-
-void *ucx_default_malloc(void *ignore, size_t n) {
-    return malloc(n);
-}
-void *ucx_default_calloc(void *ignore, size_t n, size_t size) {
-    return calloc(n, size);
-}
-void *ucx_default_realloc(void *ignore, void *data, size_t n) {
-    return realloc(data, n);
-}
+#include <stdlib.h>
+#include "allocator.h"
+
+void *ucx_default_malloc(void *ignore, size_t n) {
+    return malloc(n);
+}
+
+void *ucx_default_calloc(void *ignore, size_t n, size_t size) {
+    return calloc(n, size);
+}
+
+void *ucx_default_realloc(void *ignore, void *data, size_t n) {
+    return realloc(data, n);
+}
--- a/ucx/allocator.h	Fri Oct 05 14:06:40 2012 +0200
+++ b/ucx/allocator.h	Fri Oct 05 16:59:14 2012 +0200
@@ -1,32 +1,31 @@
-#ifndef ALLOCATOR_H
-#define ALLOCATOR_H
-
-#include <stddef.h>
-
-#ifdef  __cplusplus
-extern "C" {
-#endif
-
-typedef void*(*ucx_allocator_malloc)(void *pool, size_t n);
-typedef void*(*ucx_allocator_calloc)(void *pool, size_t n, size_t size);
-typedef void*(*ucx_allocator_realloc)(void *pool, void *data, size_t n);
-
-typedef struct {
-    void *pool;
-    ucx_allocator_malloc malloc;
-    ucx_allocator_calloc calloc;
-    ucx_allocator_realloc realloc;
-} UcxAllocator;
-
-void *ucx_default_malloc(void *ignore, size_t n);
-void *ucx_default_calloc(void *ignore, size_t n, size_t size);
-void *ucx_default_realloc(void *ignore, void *data, size_t n);
-
-#define UCX_ALLOCATOR_DEFAULT {NULL, \
-    ucx_default_malloc, ucx_default_calloc, ucx_default_realloc}
-
-#ifdef  __cplusplus
-}
-#endif
-
-#endif /* ALLOCATOR_H */
+#ifndef ALLOCATOR_H
+#define	ALLOCATOR_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef void*(*ucx_allocator_malloc)(void *pool, size_t n);
+typedef void*(*ucx_allocator_calloc)(void *pool, size_t n, size_t size);
+typedef void*(*ucx_allocator_realloc)(void *pool, void *data, size_t n);
+
+typedef struct {
+    void *pool;
+    ucx_allocator_malloc malloc;
+    ucx_allocator_calloc calloc;
+    ucx_allocator_realloc realloc;
+} UcxAllocator;
+
+void *ucx_default_malloc(void *ignore, size_t n);
+void *ucx_default_calloc(void *ignore, size_t n, size_t size);
+void *ucx_default_realloc(void *ignore, void *data, size_t n);
+
+#define UCX_ALLOCATOR_DEFAULT {NULL, \
+        ucx_default_malloc, ucx_default_calloc, ucx_default_realloc}
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* ALLOCATOR_H */
+
--- a/ucx/map.c	Fri Oct 05 14:06:40 2012 +0200
+++ b/ucx/map.c	Fri Oct 05 16:59:14 2012 +0200
@@ -44,26 +44,46 @@
     free(map);
 }
 
+int ucx_map_copy(UcxMap *from, UcxMap *to, copy_func fnc, void *data) {
+    UcxMapIterator i = ucx_map_iterator(from);
+    void *value;
+    UCX_MAP_FOREACH(value, i) {
+        int ret = ucx_map_put(to, i.cur->key, fnc ? fnc(value, data) : value);
+        if(ret != 0) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
 UcxMap *ucx_map_clone(UcxMap *map, copy_func fnc, void *data) {
     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;
-    UCX_MAP_FOREACH(value, i) {
-        ucx_map_put(newmap, i.cur->key, fnc ? fnc(value, data) : value);
+    if(newmap == NULL) {
+        return NULL;
     }
+    ucx_map_copy(map, newmap, fnc, data);
     return newmap;
 }
 
-UcxMap *ucx_map_rehash(UcxMap *map) {
+int 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;
+        UcxMap oldmap;
+        oldmap.map = map->map;
+        oldmap.size = map->size;
+        oldmap.count = map->count;
+        
+        map->size = (map->count * 5) >> 1;
+        map->map = (UcxMapElement**)calloc(map->size, sizeof(UcxMapElement*));
+        if(map->map == NULL) {
+            *map = oldmap;
+            return 1;
+        }
+        map->count = 0;
+        ucx_map_copy(&oldmap, map, NULL, NULL);
     }
+    return 0;
 }
 
 int ucx_map_put(UcxMap *map, UcxKey key, void *data) {
--- a/ucx/map.h	Fri Oct 05 14:06:40 2012 +0200
+++ b/ucx/map.h	Fri Oct 05 16:59:14 2012 +0200
@@ -58,8 +58,9 @@
 UcxMap *ucx_map_new(size_t size);
 void ucx_map_free(UcxMap *map);
 /* you cannot clone maps with more than 390 mio entries */
+int ucx_map_copy(UcxMap *from, UcxMap *to, copy_func fnc, void *data);
 UcxMap *ucx_map_clone(UcxMap *map, copy_func fnc, void *data);
-UcxMap *ucx_map_rehash(UcxMap *map);
+int ucx_map_rehash(UcxMap *map);
 
 int ucx_map_put(UcxMap *map, UcxKey key, void *data);
 void* ucx_map_get(UcxMap *map, UcxKey key);

mercurial