From 5247caa71a4f9134312d3232780361becc2e50be Mon Sep 17 00:00:00 2001 From: YuQing <384681@qq.com> Date: Tue, 9 May 2023 07:45:11 +0800 Subject: [PATCH] uniq_skiplist_clear impl. more optimization --- src/tests/test_uniq_skiplist.c | 6 +++- src/uniq_skiplist.c | 51 ++++++++++++++++++++++++---------- src/uniq_skiplist.h | 13 +-------- 3 files changed, 42 insertions(+), 28 deletions(-) diff --git a/src/tests/test_uniq_skiplist.c b/src/tests/test_uniq_skiplist.c index 09b0e6a..1931c12 100644 --- a/src/tests/test_uniq_skiplist.c +++ b/src/tests/test_uniq_skiplist.c @@ -312,13 +312,17 @@ int main(int argc, char *argv[]) test_delete(); printf("\n"); + test_clear(); + printf("\n"); + test_insert(); printf("\n"); test_clear(); printf("\n"); - printf("skiplist level_count: %d\n", sl->top_level_index + 1); + test_insert(); + printf("\n"); uniq_skiplist_free(sl); fast_mblock_manager_stat_print(false); diff --git a/src/uniq_skiplist.c b/src/uniq_skiplist.c index bf27f5b..da0257d 100644 --- a/src/uniq_skiplist.c +++ b/src/uniq_skiplist.c @@ -161,12 +161,24 @@ void uniq_skiplist_destroy(UniqSkiplistFactory *factory) factory->node_allocators = NULL; } +static inline void init_chain(UniqSkiplist *sl) +{ + int i; + + if (sl->factory->bidirection) { + LEVEL0_DOUBLE_CHAIN_TAIL(sl) = sl->top; + } + + for (i=0; i<=sl->top_level_index; i++) { + sl->top->links[i] = sl->factory->tail; + } +} + UniqSkiplist *uniq_skiplist_new(UniqSkiplistFactory *factory, const int level_count) { UniqSkiplist *sl; struct fast_mblock_man *top_mblock; - int i; if (level_count <= 0) { logError("file: "__FILE__", line: %d, " @@ -199,13 +211,7 @@ UniqSkiplist *uniq_skiplist_new(UniqSkiplistFactory *factory, } memset(sl->top, 0, top_mblock->info.element_size); sl->top->level_index = sl->top_level_index; - if (sl->factory->bidirection) { - LEVEL0_DOUBLE_CHAIN_TAIL(sl) = sl->top; - } - - for (i=0; itop->links[i] = sl->factory->tail; - } + init_chain(sl); return sl; } @@ -257,15 +263,11 @@ static int uniq_skiplist_grow(UniqSkiplist *sl) return 0; } -void uniq_skiplist_free(UniqSkiplist *sl) +static void do_clear(UniqSkiplist *sl) { volatile UniqSkiplistNode *node; volatile UniqSkiplistNode *deleted; - if (sl->top == NULL) { - return; - } - node = sl->top->links[0]; if (sl->factory->free_func != NULL) { while (node != sl->factory->tail) { @@ -286,11 +288,30 @@ void uniq_skiplist_free(UniqSkiplist *sl) } } + sl->element_count = 0; +} + +void uniq_skiplist_clear(UniqSkiplist *sl) +{ + if (!uniq_skiplist_empty(sl)) { + do_clear(sl); + init_chain(sl); + } +} + +void uniq_skiplist_free(UniqSkiplist *sl) +{ + if (sl->top == NULL) { + return; + } + + if (!uniq_skiplist_empty(sl)) { + do_clear(sl); + } + fast_mblock_free_object(sl->factory->node_allocators + sl->top_level_index, sl->top); - sl->top = NULL; - sl->element_count = 0; sl->top_level_index = 0; fast_mblock_free_object(&sl->factory->skiplist_allocator, sl); } diff --git a/src/uniq_skiplist.h b/src/uniq_skiplist.h index 5eabf15..282d9cf 100644 --- a/src/uniq_skiplist.h +++ b/src/uniq_skiplist.h @@ -253,18 +253,7 @@ static inline bool uniq_skiplist_empty(UniqSkiplist *sl) return sl->top->links[0] == sl->factory->tail; } -static inline void uniq_skiplist_clear(UniqSkiplist *sl) -{ - volatile UniqSkiplistNode *current; - volatile UniqSkiplistNode *deleted; - - current = sl->top->links[0]; - while (current != sl->factory->tail) { - deleted = current; - current = current->links[0]; - uniq_skiplist_delete(sl, deleted->data); - } -} +void uniq_skiplist_clear(UniqSkiplist *sl); #define LEVEL0_DOUBLE_CHAIN_NEXT_LINK(node) node->links[0] #define LEVEL0_DOUBLE_CHAIN_PREV_LINK(node) node->links[node->level_index + 1]