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
     1.1 --- a/test/main.c	Fri Oct 05 13:23:25 2012 +0200
     1.2 +++ b/test/main.c	Fri Oct 05 14:06:40 2012 +0200
     1.3 @@ -150,6 +150,7 @@
     1.4          ucx_test_register(suite, test_ucx_map_store_load);
     1.5          ucx_test_register(suite, test_ucx_map_store_load_with_mempool);
     1.6          ucx_test_register(suite, test_ucx_map_clone);
     1.7 +        ucx_test_register(suite, test_ucx_map_rehash);
     1.8          
     1.9          /* sstring Tests */
    1.10          ucx_test_register(suite, test_sstr);
     2.1 --- a/test/map_tests.c	Fri Oct 05 13:23:25 2012 +0200
     2.2 +++ b/test/map_tests.c	Fri Oct 05 14:06:40 2012 +0200
     2.3 @@ -285,3 +285,38 @@
     2.4      ucx_map_free(map);
     2.5      ucx_map_free(clone);
     2.6  }
     2.7 +
     2.8 +UCX_TEST_IMPLEMENT(test_ucx_map_rehash) {
     2.9 +    UcxMap *map = ucx_map_new(4);
    2.10 +
    2.11 +    char keys[10][5];
    2.12 +    char values[10][7];
    2.13 +    for (int i = 0 ; i < 10 ; i++) {
    2.14 +        strcpy(keys[i], "key");
    2.15 +        keys[i][3] = 48+i; keys[i][4] = 0;
    2.16 +        strcpy(values[i], "value");
    2.17 +        values[i][5] = 48+i; values[i][6] = 0;
    2.18 +
    2.19 +        ucx_map_cstr_put(map, keys[i], values[i]);
    2.20 +    }
    2.21 +
    2.22 +    map = ucx_map_rehash(map);
    2.23 +
    2.24 +    UCX_TEST_BEGIN
    2.25 +    UCX_TEST_ASSERT(map->size == 25, "new capacity shall be 2.5 * count");
    2.26 +    UCX_TEST_ASSERT(map->count == 10, "new map element count incorrect");
    2.27 +    for (int i = 0 ; i < 10 ; i++) {
    2.28 +        char *value = ucx_map_cstr_get(map, keys[i]);
    2.29 +        UCX_TEST_ASSERT(value != NULL, "new map is missing old keys");
    2.30 +        UCX_TEST_ASSERT(strncmp(value, values[i], 6) == 0,
    2.31 +                "new map contains incorrect values");
    2.32 +    }
    2.33 +    UcxMap *samemap = ucx_map_rehash(map);
    2.34 +    UCX_TEST_ASSERT(samemap == map,
    2.35 +            "subsequent rehashing call shall do nothing");
    2.36 +    UCX_TEST_ASSERT(samemap->size == 25,
    2.37 +            "subsequent rehashing call shall not change size");
    2.38 +    UCX_TEST_END
    2.39 +
    2.40 +    ucx_map_free(map);
    2.41 +}
     3.1 --- a/test/map_tests.h	Fri Oct 05 13:23:25 2012 +0200
     3.2 +++ b/test/map_tests.h	Fri Oct 05 14:06:40 2012 +0200
     3.3 @@ -21,6 +21,7 @@
     3.4  UCX_TEST_DECLARE(test_ucx_map_store_load)
     3.5  UCX_TEST_DECLARE(test_ucx_map_store_load_with_mempool)
     3.6  UCX_TEST_DECLARE(test_ucx_map_clone)
     3.7 +UCX_TEST_DECLARE(test_ucx_map_rehash)
     3.8  
     3.9  
    3.10  #ifdef	__cplusplus
     4.1 --- a/ucx/map.c	Fri Oct 05 13:23:25 2012 +0200
     4.2 +++ b/ucx/map.c	Fri Oct 05 14:06:40 2012 +0200
     4.3 @@ -45,7 +45,7 @@
     4.4  }
     4.5  
     4.6  UcxMap *ucx_map_clone(UcxMap *map, copy_func fnc, void *data) {
     4.7 -    size_t bs = (map->count * 5) >> 2;
     4.8 +    size_t bs = (map->count * 5) >> 1;
     4.9      UcxMap *newmap = ucx_map_new(bs > map->size ? bs : map->size);
    4.10      UcxMapIterator i = ucx_map_iterator(map);
    4.11      void *value;
    4.12 @@ -55,6 +55,17 @@
    4.13      return newmap;
    4.14  }
    4.15  
    4.16 +UcxMap *ucx_map_rehash(UcxMap *map) {
    4.17 +    size_t load = (map->size * 3) >> 2;
    4.18 +    if (map->count > load) {
    4.19 +        UcxMap *newmap = ucx_map_clone(map, NULL, NULL);
    4.20 +        ucx_map_free(map);
    4.21 +        return newmap;
    4.22 +    } else {
    4.23 +        return map;
    4.24 +    }
    4.25 +}
    4.26 +
    4.27  int ucx_map_put(UcxMap *map, UcxKey key, void *data) {
    4.28      if(key.hash == 0) {
    4.29          key.hash = ucx_hash((char*)key.data, key.len);
     5.1 --- a/ucx/map.h	Fri Oct 05 13:23:25 2012 +0200
     5.2 +++ b/ucx/map.h	Fri Oct 05 14:06:40 2012 +0200
     5.3 @@ -57,7 +57,9 @@
     5.4  
     5.5  UcxMap *ucx_map_new(size_t size);
     5.6  void ucx_map_free(UcxMap *map);
     5.7 +/* you cannot clone maps with more than 390 mio entries */
     5.8  UcxMap *ucx_map_clone(UcxMap *map, copy_func fnc, void *data);
     5.9 +UcxMap *ucx_map_rehash(UcxMap *map);
    5.10  
    5.11  int ucx_map_put(UcxMap *map, UcxKey key, void *data);
    5.12  void* ucx_map_get(UcxMap *map, UcxKey key);

mercurial