diff --git a/HISTORY b/HISTORY index 20ebb69..5be34f3 100644 --- a/HISTORY +++ b/HISTORY @@ -1,5 +1,5 @@ -Version 1.44 2020-05-07 +Version 1.44 2020-05-21 * add test file src/tests/test_pthread_lock.c * add uniq_skiplist.[hc] * add function split_string_ex @@ -29,6 +29,7 @@ Version 1.44 2020-05-07 * connection_pool support validate connection on error * fast_task_queue.[hc]: free_queue support init_callback * ini_file_reader.c: use mutex lock when access dynamic content array + * uniq_skiplist add function uniq_skiplist_replace_ex Version 1.43 2019-12-25 * replace function call system to getExecResult, diff --git a/src/uniq_skiplist.c b/src/uniq_skiplist.c index 27383de..807437c 100644 --- a/src/uniq_skiplist.c +++ b/src/uniq_skiplist.c @@ -447,7 +447,8 @@ static UniqSkiplistNode *uniq_skiplist_get_first_larger( return (UniqSkiplistNode *)previous->links[0]; } -int uniq_skiplist_delete(UniqSkiplist *sl, void *data) +int uniq_skiplist_delete_ex(UniqSkiplist *sl, void *data, + const bool need_free) { int i; int level_index; @@ -480,7 +481,7 @@ int uniq_skiplist_delete(UniqSkiplist *sl, void *data) } } - if (sl->factory->free_func != NULL) { + if (need_free && sl->factory->free_func != NULL) { sl->factory->free_func(deleted->data, sl->factory->delay_free_seconds); } @@ -490,6 +491,32 @@ int uniq_skiplist_delete(UniqSkiplist *sl, void *data) return 0; } +int uniq_skiplist_replace_ex(UniqSkiplist *sl, void *data, + const bool need_free_old) +{ + int level_index; + UniqSkiplistNode *previous; + volatile UniqSkiplistNode *current; + + previous = uniq_skiplist_get_equal_previous(sl, data, &level_index); + if (previous == NULL) { + return ENOENT; + } + + current = previous->links[level_index]; + if (need_free_old && sl->factory->free_func != NULL) { + void *deleted_data; + + deleted_data = current->data; + current->data = data; + sl->factory->free_func(deleted_data, sl->factory->delay_free_seconds); + } else { + current->data = data; + } + + return 0; +} + void *uniq_skiplist_find(UniqSkiplist *sl, void *data) { int level_index; diff --git a/src/uniq_skiplist.h b/src/uniq_skiplist.h index 35980d9..57d4ce1 100644 --- a/src/uniq_skiplist.h +++ b/src/uniq_skiplist.h @@ -70,6 +70,13 @@ extern "C" { compare_func, free_func, 64 * 1024, \ SKIPLIST_DEFAULT_MIN_ALLOC_ELEMENTS_ONCE, 0) +#define uniq_skiplist_delete(sl, data) \ + uniq_skiplist_delete_ex(sl, data, true) + +#define uniq_skiplist_replace(sl, data) \ + uniq_skiplist_replace_ex(sl, data, true) + + int uniq_skiplist_init_ex2(UniqSkiplistFactory *factory, const int max_level_count, skiplist_compare_func compare_func, uniq_skiplist_free_func free_func, const int alloc_skiplist_once, @@ -84,7 +91,10 @@ UniqSkiplist *uniq_skiplist_new(UniqSkiplistFactory *factory, void uniq_skiplist_free(UniqSkiplist *sl); int uniq_skiplist_insert(UniqSkiplist *sl, void *data); -int uniq_skiplist_delete(UniqSkiplist *sl, void *data); +int uniq_skiplist_delete_ex(UniqSkiplist *sl, void *data, + const bool need_free); +int uniq_skiplist_replace_ex(UniqSkiplist *sl, void *data, + const bool need_free_old); void *uniq_skiplist_find(UniqSkiplist *sl, void *data); int uniq_skiplist_find_all(UniqSkiplist *sl, void *data, UniqSkiplistIterator *iterator);