Fri, 05 Oct 2012 16:59:14 +0200
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);