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
     1.1 --- a/test/map_tests.c	Fri Oct 05 14:06:40 2012 +0200
     1.2 +++ b/test/map_tests.c	Fri Oct 05 16:59:14 2012 +0200
     1.3 @@ -300,7 +300,7 @@
     1.4          ucx_map_cstr_put(map, keys[i], values[i]);
     1.5      }
     1.6  
     1.7 -    map = ucx_map_rehash(map);
     1.8 +    ucx_map_rehash(map);
     1.9  
    1.10      UCX_TEST_BEGIN
    1.11      UCX_TEST_ASSERT(map->size == 25, "new capacity shall be 2.5 * count");
    1.12 @@ -311,10 +311,8 @@
    1.13          UCX_TEST_ASSERT(strncmp(value, values[i], 6) == 0,
    1.14                  "new map contains incorrect values");
    1.15      }
    1.16 -    UcxMap *samemap = ucx_map_rehash(map);
    1.17 -    UCX_TEST_ASSERT(samemap == map,
    1.18 -            "subsequent rehashing call shall do nothing");
    1.19 -    UCX_TEST_ASSERT(samemap->size == 25,
    1.20 +    ucx_map_rehash(map);
    1.21 +    UCX_TEST_ASSERT(map->size == 25,
    1.22              "subsequent rehashing call shall not change size");
    1.23      UCX_TEST_END
    1.24  
     2.1 --- a/ucx/allocator.c	Fri Oct 05 14:06:40 2012 +0200
     2.2 +++ b/ucx/allocator.c	Fri Oct 05 16:59:14 2012 +0200
     2.3 @@ -1,12 +1,14 @@
     2.4 -#include "allocator.h"
     2.5 -#include <stdlib.h>
     2.6 -
     2.7 -void *ucx_default_malloc(void *ignore, size_t n) {
     2.8 -    return malloc(n);
     2.9 -}
    2.10 -void *ucx_default_calloc(void *ignore, size_t n, size_t size) {
    2.11 -    return calloc(n, size);
    2.12 -}
    2.13 -void *ucx_default_realloc(void *ignore, void *data, size_t n) {
    2.14 -    return realloc(data, n);
    2.15 -}
    2.16 +#include <stdlib.h>
    2.17 +#include "allocator.h"
    2.18 +
    2.19 +void *ucx_default_malloc(void *ignore, size_t n) {
    2.20 +    return malloc(n);
    2.21 +}
    2.22 +
    2.23 +void *ucx_default_calloc(void *ignore, size_t n, size_t size) {
    2.24 +    return calloc(n, size);
    2.25 +}
    2.26 +
    2.27 +void *ucx_default_realloc(void *ignore, void *data, size_t n) {
    2.28 +    return realloc(data, n);
    2.29 +}
     3.1 --- a/ucx/allocator.h	Fri Oct 05 14:06:40 2012 +0200
     3.2 +++ b/ucx/allocator.h	Fri Oct 05 16:59:14 2012 +0200
     3.3 @@ -1,32 +1,31 @@
     3.4 -#ifndef ALLOCATOR_H
     3.5 -#define ALLOCATOR_H
     3.6 -
     3.7 -#include <stddef.h>
     3.8 -
     3.9 -#ifdef  __cplusplus
    3.10 -extern "C" {
    3.11 -#endif
    3.12 -
    3.13 -typedef void*(*ucx_allocator_malloc)(void *pool, size_t n);
    3.14 -typedef void*(*ucx_allocator_calloc)(void *pool, size_t n, size_t size);
    3.15 -typedef void*(*ucx_allocator_realloc)(void *pool, void *data, size_t n);
    3.16 -
    3.17 -typedef struct {
    3.18 -    void *pool;
    3.19 -    ucx_allocator_malloc malloc;
    3.20 -    ucx_allocator_calloc calloc;
    3.21 -    ucx_allocator_realloc realloc;
    3.22 -} UcxAllocator;
    3.23 -
    3.24 -void *ucx_default_malloc(void *ignore, size_t n);
    3.25 -void *ucx_default_calloc(void *ignore, size_t n, size_t size);
    3.26 -void *ucx_default_realloc(void *ignore, void *data, size_t n);
    3.27 -
    3.28 -#define UCX_ALLOCATOR_DEFAULT {NULL, \
    3.29 -    ucx_default_malloc, ucx_default_calloc, ucx_default_realloc}
    3.30 -
    3.31 -#ifdef  __cplusplus
    3.32 -}
    3.33 -#endif
    3.34 -
    3.35 -#endif /* ALLOCATOR_H */
    3.36 +#ifndef ALLOCATOR_H
    3.37 +#define	ALLOCATOR_H
    3.38 +
    3.39 +#ifdef	__cplusplus
    3.40 +extern "C" {
    3.41 +#endif
    3.42 +
    3.43 +typedef void*(*ucx_allocator_malloc)(void *pool, size_t n);
    3.44 +typedef void*(*ucx_allocator_calloc)(void *pool, size_t n, size_t size);
    3.45 +typedef void*(*ucx_allocator_realloc)(void *pool, void *data, size_t n);
    3.46 +
    3.47 +typedef struct {
    3.48 +    void *pool;
    3.49 +    ucx_allocator_malloc malloc;
    3.50 +    ucx_allocator_calloc calloc;
    3.51 +    ucx_allocator_realloc realloc;
    3.52 +} UcxAllocator;
    3.53 +
    3.54 +void *ucx_default_malloc(void *ignore, size_t n);
    3.55 +void *ucx_default_calloc(void *ignore, size_t n, size_t size);
    3.56 +void *ucx_default_realloc(void *ignore, void *data, size_t n);
    3.57 +
    3.58 +#define UCX_ALLOCATOR_DEFAULT {NULL, \
    3.59 +        ucx_default_malloc, ucx_default_calloc, ucx_default_realloc}
    3.60 +
    3.61 +#ifdef	__cplusplus
    3.62 +}
    3.63 +#endif
    3.64 +
    3.65 +#endif	/* ALLOCATOR_H */
    3.66 +
     4.1 --- a/ucx/map.c	Fri Oct 05 14:06:40 2012 +0200
     4.2 +++ b/ucx/map.c	Fri Oct 05 16:59:14 2012 +0200
     4.3 @@ -44,26 +44,46 @@
     4.4      free(map);
     4.5  }
     4.6  
     4.7 +int ucx_map_copy(UcxMap *from, UcxMap *to, copy_func fnc, void *data) {
     4.8 +    UcxMapIterator i = ucx_map_iterator(from);
     4.9 +    void *value;
    4.10 +    UCX_MAP_FOREACH(value, i) {
    4.11 +        int ret = ucx_map_put(to, i.cur->key, fnc ? fnc(value, data) : value);
    4.12 +        if(ret != 0) {
    4.13 +            return 1;
    4.14 +        }
    4.15 +    }
    4.16 +    return 0;
    4.17 +}
    4.18 +
    4.19  UcxMap *ucx_map_clone(UcxMap *map, copy_func fnc, void *data) {
    4.20      size_t bs = (map->count * 5) >> 1;
    4.21      UcxMap *newmap = ucx_map_new(bs > map->size ? bs : map->size);
    4.22 -    UcxMapIterator i = ucx_map_iterator(map);
    4.23 -    void *value;
    4.24 -    UCX_MAP_FOREACH(value, i) {
    4.25 -        ucx_map_put(newmap, i.cur->key, fnc ? fnc(value, data) : value);
    4.26 +    if(newmap == NULL) {
    4.27 +        return NULL;
    4.28      }
    4.29 +    ucx_map_copy(map, newmap, fnc, data);
    4.30      return newmap;
    4.31  }
    4.32  
    4.33 -UcxMap *ucx_map_rehash(UcxMap *map) {
    4.34 +int ucx_map_rehash(UcxMap *map) {
    4.35      size_t load = (map->size * 3) >> 2;
    4.36      if (map->count > load) {
    4.37 -        UcxMap *newmap = ucx_map_clone(map, NULL, NULL);
    4.38 -        ucx_map_free(map);
    4.39 -        return newmap;
    4.40 -    } else {
    4.41 -        return map;
    4.42 +        UcxMap oldmap;
    4.43 +        oldmap.map = map->map;
    4.44 +        oldmap.size = map->size;
    4.45 +        oldmap.count = map->count;
    4.46 +        
    4.47 +        map->size = (map->count * 5) >> 1;
    4.48 +        map->map = (UcxMapElement**)calloc(map->size, sizeof(UcxMapElement*));
    4.49 +        if(map->map == NULL) {
    4.50 +            *map = oldmap;
    4.51 +            return 1;
    4.52 +        }
    4.53 +        map->count = 0;
    4.54 +        ucx_map_copy(&oldmap, map, NULL, NULL);
    4.55      }
    4.56 +    return 0;
    4.57  }
    4.58  
    4.59  int ucx_map_put(UcxMap *map, UcxKey key, void *data) {
     5.1 --- a/ucx/map.h	Fri Oct 05 14:06:40 2012 +0200
     5.2 +++ b/ucx/map.h	Fri Oct 05 16:59:14 2012 +0200
     5.3 @@ -58,8 +58,9 @@
     5.4  UcxMap *ucx_map_new(size_t size);
     5.5  void ucx_map_free(UcxMap *map);
     5.6  /* you cannot clone maps with more than 390 mio entries */
     5.7 +int ucx_map_copy(UcxMap *from, UcxMap *to, copy_func fnc, void *data);
     5.8  UcxMap *ucx_map_clone(UcxMap *map, copy_func fnc, void *data);
     5.9 -UcxMap *ucx_map_rehash(UcxMap *map);
    5.10 +int ucx_map_rehash(UcxMap *map);
    5.11  
    5.12  int ucx_map_put(UcxMap *map, UcxKey key, void *data);
    5.13  void* ucx_map_get(UcxMap *map, UcxKey key);

mercurial