# HG changeset patch # User Mike Becker # Date 1349438800 -7200 # Node ID 1c78cd19fb6b75395118652ca901298f133523e0 # Parent ff194559eb41e2d1f84737a9f61b76cb849f9dc0 added rehashing to maps by using clone function diff -r ff194559eb41 -r 1c78cd19fb6b test/main.c --- 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); diff -r ff194559eb41 -r 1c78cd19fb6b test/map_tests.c --- 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); +} diff -r ff194559eb41 -r 1c78cd19fb6b test/map_tests.h --- 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 diff -r ff194559eb41 -r 1c78cd19fb6b ucx/map.c --- 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); diff -r ff194559eb41 -r 1c78cd19fb6b ucx/map.h --- 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);