From 5bae0d57cbfb745e455d8136253afbdb1a84366e Mon Sep 17 00:00:00 2001 From: yuqing Date: Tue, 29 Dec 2015 12:23:03 +0800 Subject: [PATCH] support multi skiplist --- HISTORY | 2 +- make.sh | 2 +- src/fast_mblock.c | 8 ++++++-- src/multi_skiplist.c | 24 +++++++++++------------- src/multi_skiplist.h | 13 +++++-------- src/tests/Makefile | 4 ++-- src/tests/test_skiplist.c | 3 ++- 7 files changed, 28 insertions(+), 28 deletions(-) diff --git a/HISTORY b/HISTORY index b74e877..9c7377f 100644 --- a/HISTORY +++ b/HISTORY @@ -1,5 +1,5 @@ -Version 1.24 2015-12-25 +Version 1.24 2015-12-29 * php extension compiled on PHP 7 * add skiplist which support stable sort * make.sh: use sed to replace perl diff --git a/make.sh b/make.sh index cbbf252..4f9afe6 100755 --- a/make.sh +++ b/make.sh @@ -56,7 +56,7 @@ CFLAGS='-Wall -D_FILE_OFFSET_BITS=64' if [ "$DEBUG_FLAG" = "1" ]; then CFLAGS="$CFLAGS -g -DDEBUG_FLAG" else - CFLAGS="$CFLAGS -O3" + CFLAGS="$CFLAGS -g -O3" fi LIBS='-lm' diff --git a/src/fast_mblock.c b/src/fast_mblock.c index 838ffc8..fbb5443 100644 --- a/src/fast_mblock.c +++ b/src/fast_mblock.c @@ -13,6 +13,7 @@ struct _fast_mblock_manager { bool initialized; + int count; struct fast_mblock_man head; pthread_mutex_t lock; }; @@ -20,7 +21,7 @@ struct _fast_mblock_manager #define INIT_HEAD(head) (head)->next = (head)->prev = head #define IS_EMPTY(head) ((head)->next == head) -static struct _fast_mblock_manager mblock_manager = {false}; +static struct _fast_mblock_manager mblock_manager = {false, 0}; int fast_mblock_manager_init() { @@ -78,13 +79,14 @@ static void add_to_mblock_list(struct fast_mblock_man *mblock) mblock->prev = current->prev; current->prev->next = mblock; current->prev = mblock; + mblock_manager.count++; pthread_mutex_unlock(&(mblock_manager.lock)); } static void delete_from_mblock_list(struct fast_mblock_man *mblock) { - if (!mblock_manager.initialized) + if (!mblock_manager.initialized || IS_EMPTY(mblock)) { return; } @@ -92,6 +94,7 @@ static void delete_from_mblock_list(struct fast_mblock_man *mblock) pthread_mutex_lock(&(mblock_manager.lock)); mblock->prev->next = mblock->next; mblock->next->prev = mblock->prev; + mblock_manager.count--; pthread_mutex_unlock(&(mblock_manager.lock)); INIT_HEAD(mblock); @@ -499,6 +502,7 @@ void fast_mblock_destroy(struct fast_mblock_man *mblock) if (IS_EMPTY(&mblock->trunks.head)) { + delete_from_mblock_list(mblock); return; } diff --git a/src/multi_skiplist.c b/src/multi_skiplist.c index 5201960..eaa47e6 100644 --- a/src/multi_skiplist.c +++ b/src/multi_skiplist.c @@ -150,7 +150,6 @@ DONE: return found; } - static inline int multi_skiplist_get_level_index(MultiSkiplist *sl) { int i; @@ -239,18 +238,10 @@ int multi_skiplist_do_delete(MultiSkiplist *sl, void *data, } deleted = previous->links[level_index]; - if (delete_all) { - dataCurrent = deleted->head; - while (dataCurrent != NULL) { - dataNode = dataCurrent; - dataCurrent = dataCurrent->next; - fast_mblock_free_object(&sl->data_mblock, dataNode); - } - } - else { - dataNode = deleted->head; - deleted->head = dataNode->next; - if (deleted->head != NULL) { + if (!delete_all) { + if (deleted->head->next != NULL) { + dataNode = deleted->head; + deleted->head = dataNode->next; fast_mblock_free_object(&sl->data_mblock, dataNode); return 0; } @@ -266,6 +257,13 @@ int multi_skiplist_do_delete(MultiSkiplist *sl, void *data, previous->links[i] = previous->links[i]->links[i]; } + dataCurrent = deleted->head; + while (dataCurrent != NULL) { + dataNode = dataCurrent; + dataCurrent = dataCurrent->next; + fast_mblock_free_object(&sl->data_mblock, dataNode); + } + fast_mblock_free_object(sl->mblocks + level_index, deleted); return 0; } diff --git a/src/multi_skiplist.h b/src/multi_skiplist.h index 0c7d6dd..f563123 100644 --- a/src/multi_skiplist.h +++ b/src/multi_skiplist.h @@ -73,13 +73,8 @@ void *multi_skiplist_find(MultiSkiplist *sl, void *data); static inline void multi_skiplist_iterator(MultiSkiplist *sl, MultiSkiplistIterator *iterator) { iterator->sl = sl; - iterator->current.node = sl->top->links[0]; - if (iterator->current.node != iterator->sl->tail) { - iterator->current.data = iterator->current.node->head; - } - else { - iterator->current.data = NULL; - } + iterator->current.node = sl->top; + iterator->current.data = NULL; } static inline void *multi_skiplist_next(MultiSkiplistIterator *iterator) @@ -87,7 +82,9 @@ static inline void *multi_skiplist_next(MultiSkiplistIterator *iterator) void *data; if (iterator->current.data == NULL) { - if (iterator->current.node == iterator->sl->tail) { + if (iterator->current.node == iterator->sl->tail || + iterator->current.node->links[0] == iterator->sl->tail) + { return NULL; } diff --git a/src/tests/Makefile b/src/tests/Makefile index 73c875c..0547c79 100644 --- a/src/tests/Makefile +++ b/src/tests/Makefile @@ -1,10 +1,10 @@ .SUFFIXES: .c .o -COMPILE = $(CC) -O2 -Wall -D_FILE_OFFSET_BITS=64 -g -DDEBUG_FLAG +COMPILE = $(CC) -g -O1 -Wall -D_FILE_OFFSET_BITS=64 -g -DDEBUG_FLAG INC_PATH = -I/usr/include/fastcommon LIB_PATH = -lfastcommon -ALL_PRGS = test_allocator test_skiplist +ALL_PRGS = test_allocator test_skiplist test_multi_skiplist all: $(ALL_PRGS) .c: diff --git a/src/tests/test_skiplist.c b/src/tests/test_skiplist.c index cae3694..aca468e 100644 --- a/src/tests/test_skiplist.c +++ b/src/tests/test_skiplist.c @@ -10,7 +10,7 @@ #include "logger.h" #include "shared_func.h" -#define COUNT 10000000 +#define COUNT 1000 #define LEVEL_COUNT 18 #define MIN_ALLOC_ONCE 32 #define LAST_INDEX (COUNT - 1) @@ -205,6 +205,7 @@ int main(int argc, char *argv[]) test_delete(); printf("\n"); skiplist_destroy(&sl); + fast_mblock_manager_stat_print(false); test_stable_sort();