# HG changeset patch # User Mike Becker # Date 1349692167 -7200 # Node ID e533c170bfb8bb7ced378f08fb6f2a63966b3920 # Parent 34f50d0bada465ecaa5d49b981a243245d5d3ffc added ucx_map_remove diff -r 34f50d0bada4 -r e533c170bfb8 test/main.c --- a/test/main.c Fri Oct 05 16:59:14 2012 +0200 +++ b/test/main.c Mon Oct 08 12:29:27 2012 +0200 @@ -145,6 +145,7 @@ ucx_test_register(suite, test_ucx_key); ucx_test_register(suite, test_ucx_map_put); ucx_test_register(suite, test_ucx_map_get); + ucx_test_register(suite, test_ucx_map_remove); ucx_test_register(suite, test_ucx_map_iterator); ucx_test_register(suite, test_ucx_map_iterator_chain); ucx_test_register(suite, test_ucx_map_store_load); diff -r 34f50d0bada4 -r e533c170bfb8 test/map_tests.c --- a/test/map_tests.c Fri Oct 05 16:59:14 2012 +0200 +++ b/test/map_tests.c Mon Oct 08 12:29:27 2012 +0200 @@ -95,6 +95,47 @@ UCX_TEST_ASSERT(td[3] == 11200, "failed key 3"); UCX_TEST_ASSERT(td[4] == 80000, "failed key 4"); + UCX_TEST_ASSERT(map->count == 5, "expected 5 remaining values"); + UCX_TEST_ASSERT(ucx_map_cstr_get(map, "Key0") != NULL, "element removed"); + + UCX_TEST_END + ucx_map_free(map); +} + +UCX_TEST_IMPLEMENT(test_ucx_map_remove) { + UcxMap *map = ucx_map_new(4); + + int td[5]; + td[0] = 10; td[1] = 42; td[2] = 70; td[3] = 11200; td[4] = 80000; + + ucx_map_cstr_put(map, "Key2", &td[2]); /* 0 */ + ucx_map_cstr_put(map, "Key0", &td[0]); /* 0 */ + ucx_map_cstr_put(map, "Key1", &td[1]); /* 3 */ + ucx_map_cstr_put(map, "KeY3", &td[3]); /* 2 */ + ucx_map_cstr_put(map, "KEY4", &td[4]); /* 0 */ + UCX_TEST_BEGIN + + td[0] = *((int*)ucx_map_cstr_remove(map, "Key0")); + td[1] = *((int*)ucx_map_cstr_get(map, "Key1")); + td[2] = *((int*)ucx_map_cstr_remove(map, "Key2")); + td[3] = *((int*)ucx_map_cstr_get(map, "KeY3")); + td[4] = *((int*)ucx_map_cstr_get(map, "KEY4")); + UCX_TEST_ASSERT(td[0] == 10, "failed key 0"); + UCX_TEST_ASSERT(td[1] == 42, "failed key 1"); + UCX_TEST_ASSERT(td[2] == 70, "failed key 2"); + UCX_TEST_ASSERT(td[3] == 11200, "failed key 3"); + UCX_TEST_ASSERT(td[4] == 80000, "failed key 4"); + + UCX_TEST_ASSERT(map->count == 3, "expected 3 remaining values"); + UCX_TEST_ASSERT(ucx_map_cstr_get(map, "Key0")==NULL, "element not removed"); + UCX_TEST_ASSERT(ucx_map_cstr_get(map, "Key1")!=NULL, "element removed"); + UCX_TEST_ASSERT(ucx_map_cstr_get(map, "Key2")==NULL, "element not removed"); + UCX_TEST_ASSERT(ucx_map_cstr_get(map, "KeY3")!=NULL, "element removed"); + UCX_TEST_ASSERT(ucx_map_cstr_get(map, "KEY4")!=NULL, "element removed"); + + UCX_TEST_ASSERT(ucx_map_cstr_remove(map, "Key2") == NULL, + "subsequent remove call shall return NULL"); + UCX_TEST_END ucx_map_free(map); } diff -r 34f50d0bada4 -r e533c170bfb8 test/map_tests.h --- a/test/map_tests.h Fri Oct 05 16:59:14 2012 +0200 +++ b/test/map_tests.h Mon Oct 08 12:29:27 2012 +0200 @@ -16,6 +16,7 @@ UCX_TEST_DECLARE(test_ucx_key) UCX_TEST_DECLARE(test_ucx_map_put) UCX_TEST_DECLARE(test_ucx_map_get) +UCX_TEST_DECLARE(test_ucx_map_remove) UCX_TEST_DECLARE(test_ucx_map_iterator) UCX_TEST_DECLARE(test_ucx_map_iterator_chain) UCX_TEST_DECLARE(test_ucx_map_store_load) diff -r 34f50d0bada4 -r e533c170bfb8 ucx/map.c --- a/ucx/map.c Fri Oct 05 16:59:14 2012 +0200 +++ b/ucx/map.c Mon Oct 08 12:29:27 2012 +0200 @@ -106,10 +106,10 @@ return -1; } e->key.data = NULL; - if (prev == NULL) { + if (prev) { + prev->next = e; + } else { map->map[slot] = e; - } else { - prev->next = e; } e->next = elm; elm = e; @@ -130,25 +130,47 @@ return 0; } -void* ucx_map_get(UcxMap *map, UcxKey key) { +void* ucx_map_get_and_remove(UcxMap *map, UcxKey key, _Bool remove) { if(key.hash == 0) { key.hash = ucx_hash((char*)key.data, key.len); } - UcxMapElement *elm = map->map[key.hash%map->size]; - while (elm != NULL && elm->key.hash <= key.hash) { + size_t slot = key.hash%map->size; + UcxMapElement *elm = map->map[slot]; + UcxMapElement *pelm = NULL; + while (elm && elm->key.hash <= key.hash) { if(elm->key.hash == key.hash) { int n = (key.len > elm->key.len) ? elm->key.len : key.len; if (memcmp(elm->key.data, key.data, n) == 0) { - return elm->data; + void *data = elm->data; + if (remove) { + if (pelm) { + pelm->next = elm->next; + } else { + map->map[slot] = elm->next; + } + free(elm); + map->count--; + } + + return data; } } - elm = elm->next; + pelm = elm; + elm = pelm->next; } return NULL; } +void *ucx_map_get(UcxMap *map, UcxKey key) { + return ucx_map_get_and_remove(map, key, 0); +} + +void *ucx_map_remove(UcxMap *map, UcxKey key) { + return ucx_map_get_and_remove(map, key, 1); +} + UcxKey ucx_key(void *data, size_t len) { UcxKey key; key.data = data; diff -r 34f50d0bada4 -r e533c170bfb8 ucx/map.h --- a/ucx/map.h Fri Oct 05 16:59:14 2012 +0200 +++ b/ucx/map.h Mon Oct 08 12:29:27 2012 +0200 @@ -64,11 +64,14 @@ int ucx_map_put(UcxMap *map, UcxKey key, void *data); void* ucx_map_get(UcxMap *map, UcxKey key); +void* ucx_map_remove(UcxMap *map, UcxKey key); #define ucx_map_sstr_put(m, s, d) ucx_map_put(m, ucx_key(s.ptr, s.length), d) #define ucx_map_cstr_put(m, s, d) ucx_map_put(m, ucx_key(s, 1+strlen(s)), d) #define ucx_map_sstr_get(m, s) ucx_map_get(m, ucx_key(s.ptr, s.length)) #define ucx_map_cstr_get(m, s) ucx_map_get(m, ucx_key(s, 1+strlen(s))) +#define ucx_map_sstr_remove(m, s) ucx_map_remove(m, ucx_key(s.ptr, s.length)) +#define ucx_map_cstr_remove(m, s) ucx_map_remove(m, ucx_key(s, 1+strlen(s))) UcxKey ucx_key(void *data, size_t len);