skiplist add function find_range

pull/37/head
yuqing 2018-06-01 18:30:26 +08:00
parent 2f76b8c4b1
commit 890d0bf2d4
11 changed files with 444 additions and 46 deletions

View File

@ -1,5 +1,5 @@
Version 1.38 2018-05-30
Version 1.38 2018-06-01
* connection_pool.c: set err_no to 0 when success
* shared_func.h: add functions float2buff / buff2float, double2buff / buff2double
* logger.h: add function log_get_level_caption

View File

@ -221,6 +221,81 @@ static FlatSkiplistNode *flat_skiplist_get_previous(FlatSkiplist *sl, void *data
return NULL;
}
static FlatSkiplistNode *flat_skiplist_get_first_larger_or_equal(
FlatSkiplist *sl, void *data)
{
int i;
int cmp;
FlatSkiplistNode *previous;
FlatSkiplistNode *current;
previous = sl->top;
for (i=sl->top_level_index; i>=0; i--) {
while (previous->links[i] != sl->tail) {
cmp = sl->compare_func(data, previous->links[i]->data);
if (cmp > 0) {
break;
}
else if (cmp == 0) {
current = previous->links[i]->links[0];
while ((current != sl->tail) && (sl->compare_func(
data, current->data) == 0))
{
current = current->links[0];
}
return current->prev;
}
previous = previous->links[i];
}
}
return previous;
/*
if (previous == sl->top) {
return sl->top;
}
else {
return previous->prev;
}
return previous->links[0];
*/
}
static FlatSkiplistNode *flat_skiplist_get_first_larger(
FlatSkiplist *sl, void *data)
{
int i;
int cmp;
FlatSkiplistNode *previous;
previous = sl->top;
for (i=sl->top_level_index; i>=0; i--) {
while (previous->links[i] != sl->tail) {
cmp = sl->compare_func(data, previous->links[i]->data);
if (cmp > 0) {
break;
}
else if (cmp == 0) {
previous = previous->links[i]->prev;
while ((previous != sl->top) && (sl->compare_func(
data, previous->data) == 0))
{
previous = previous->prev;
}
return previous;
}
previous = previous->links[i];
}
}
return previous;
//return previous->links[0];
}
int flat_skiplist_delete(FlatSkiplist *sl, void *data)
{
int i;
@ -298,3 +373,22 @@ int flat_skiplist_find_all(FlatSkiplist *sl, void *data, FlatSkiplistIterator *i
iterator->current = last->prev;
return 0;
}
int flat_skiplist_find_range(FlatSkiplist *sl, void *start_data, void *end_data,
FlatSkiplistIterator *iterator)
{
if (sl->compare_func(start_data, end_data) > 0) {
iterator->current = sl->top;
iterator->top = sl->top;
return EINVAL;
}
iterator->current = flat_skiplist_get_first_larger_or_equal(sl, start_data);
if (iterator->current == sl->top) {
iterator->top = sl->top;
return ENOENT;
}
iterator->top = flat_skiplist_get_first_larger(sl, end_data);
return iterator->current != iterator->top ? 0 : ENOENT;
}

View File

@ -62,6 +62,8 @@ int flat_skiplist_delete(FlatSkiplist *sl, void *data);
int flat_skiplist_delete_all(FlatSkiplist *sl, void *data, int *delete_count);
void *flat_skiplist_find(FlatSkiplist *sl, void *data);
int flat_skiplist_find_all(FlatSkiplist *sl, void *data, FlatSkiplistIterator *iterator);
int flat_skiplist_find_range(FlatSkiplist *sl, void *start_data, void *end_data,
FlatSkiplistIterator *iterator);
static inline void flat_skiplist_iterator(FlatSkiplist *sl, FlatSkiplistIterator *iterator)
{

View File

@ -178,6 +178,56 @@ static MultiSkiplistNode *multi_skiplist_get_previous(MultiSkiplist *sl, void *d
return NULL;
}
static MultiSkiplistNode *multi_skiplist_get_first_larger_or_equal(
MultiSkiplist *sl, void *data)
{
int i;
int cmp;
MultiSkiplistNode *previous;
previous = sl->top;
for (i=sl->top_level_index; i>=0; i--) {
while (previous->links[i] != sl->tail) {
cmp = sl->compare_func(data, previous->links[i]->head->data);
if (cmp < 0) {
break;
}
else if (cmp == 0) {
return previous->links[i];
}
previous = previous->links[i];
}
}
return previous->links[0];
}
static MultiSkiplistNode *multi_skiplist_get_first_larger(
MultiSkiplist *sl, void *data)
{
int i;
int cmp;
MultiSkiplistNode *previous;
previous = sl->top;
for (i=sl->top_level_index; i>=0; i--) {
while (previous->links[i] != sl->tail) {
cmp = sl->compare_func(data, previous->links[i]->head->data);
if (cmp < 0) {
break;
}
else if (cmp == 0) {
return previous->links[i]->links[0];
}
previous = previous->links[i];
}
}
return previous->links[0];
}
static inline void multi_skiplist_free_data_node(MultiSkiplist *sl,
MultiSkiplistData *dataNode)
{
@ -354,3 +404,30 @@ int multi_skiplist_find_all(MultiSkiplist *sl, void *data,
return 0;
}
}
int multi_skiplist_find_range(MultiSkiplist *sl, void *start_data, void *end_data,
MultiSkiplistIterator *iterator)
{
if (sl->compare_func(start_data, end_data) > 0) {
iterator->current.node = sl->tail;
iterator->current.data = NULL;
iterator->tail = sl->tail;
return EINVAL;
}
iterator->current.node = multi_skiplist_get_first_larger_or_equal(sl, start_data);
if (iterator->current.node == sl->tail) {
iterator->current.data = NULL;
iterator->tail = sl->tail;
return ENOENT;
}
iterator->tail = multi_skiplist_get_first_larger(sl, end_data);
if (iterator->current.node != iterator->tail) {
iterator->current.data = iterator->current.node->head;
return 0;
} else {
iterator->current.data = NULL;
return ENOENT;
}
}

View File

@ -73,6 +73,8 @@ int multi_skiplist_delete_all(MultiSkiplist *sl, void *data, int *delete_count);
void *multi_skiplist_find(MultiSkiplist *sl, void *data);
int multi_skiplist_find_all(MultiSkiplist *sl, void *data,
MultiSkiplistIterator *iterator);
int multi_skiplist_find_range(MultiSkiplist *sl, void *start_data, void *end_data,
MultiSkiplistIterator *iterator);
static inline void multi_skiplist_iterator(MultiSkiplist *sl,
MultiSkiplistIterator *iterator)

View File

@ -162,6 +162,25 @@ static inline int skiplist_find_all(Skiplist *sl, void *data, SkiplistIterator *
}
}
int skiplist_find_range(Skiplist *sl, void *start_data, void *end_data,
SkiplistIterator *iterator)
{
iterator->type = sl->type;
switch (sl->type) {
case SKIPLIST_TYPE_FLAT:
return flat_skiplist_find_range(&sl->u.flat,
start_data, end_data, &iterator->u.flat);
case SKIPLIST_TYPE_MULTI:
return multi_skiplist_find_range(&sl->u.multi,
start_data, end_data, &iterator->u.multi);
case SKIPLIST_TYPE_SET:
return skiplist_set_find_range(&sl->u.set,
start_data, end_data, &iterator->u.set);
default:
return EINVAL;
}
}
static inline void skiplist_iterator(Skiplist *sl, SkiplistIterator *iterator)
{
iterator->type = sl->type;

View File

@ -15,7 +15,7 @@
#include <string.h>
#include "common_define.h"
#define SKIPLIST_DEFAULT_MIN_ALLOC_ELEMENTS_ONCE 128
#define SKIPLIST_DEFAULT_MIN_ALLOC_ELEMENTS_ONCE 64
typedef int (*skiplist_compare_func)(const void *p1, const void *p2);
typedef void (*skiplist_free_func)(void *ptr);

View File

@ -203,8 +203,8 @@ int skiplist_set_insert(SkiplistSet *sl, void *data)
return 0;
}
static SkiplistSetNode *skiplist_set_get_previous(SkiplistSet *sl, void *data,
int *level_index)
static SkiplistSetNode *skiplist_set_get_equal_previous(SkiplistSet *sl,
void *data, int *level_index)
{
int i;
int cmp;
@ -229,6 +229,56 @@ static SkiplistSetNode *skiplist_set_get_previous(SkiplistSet *sl, void *data,
return NULL;
}
static SkiplistSetNode *skiplist_set_get_first_larger_or_equal(
SkiplistSet *sl, void *data)
{
int i;
int cmp;
SkiplistSetNode *previous;
previous = sl->top;
for (i=sl->top_level_index; i>=0; i--) {
while (previous->links[i] != sl->tail) {
cmp = sl->compare_func(data, previous->links[i]->data);
if (cmp < 0) {
break;
}
else if (cmp == 0) {
return previous->links[i];
}
previous = previous->links[i];
}
}
return previous->links[0];
}
static SkiplistSetNode *skiplist_set_get_first_larger(
SkiplistSet *sl, void *data)
{
int i;
int cmp;
SkiplistSetNode *previous;
previous = sl->top;
for (i=sl->top_level_index; i>=0; i--) {
while (previous->links[i] != sl->tail) {
cmp = sl->compare_func(data, previous->links[i]->data);
if (cmp < 0) {
break;
}
else if (cmp == 0) {
return previous->links[i]->links[0];
}
previous = previous->links[i];
}
}
return previous->links[0];
}
int skiplist_set_delete(SkiplistSet *sl, void *data)
{
int i;
@ -236,7 +286,7 @@ int skiplist_set_delete(SkiplistSet *sl, void *data)
SkiplistSetNode *previous;
SkiplistSetNode *deleted;
previous = skiplist_set_get_previous(sl, data, &level_index);
previous = skiplist_set_get_equal_previous(sl, data, &level_index);
if (previous == NULL) {
return ENOENT;
}
@ -265,7 +315,7 @@ void *skiplist_set_find(SkiplistSet *sl, void *data)
int level_index;
SkiplistSetNode *previous;
previous = skiplist_set_get_previous(sl, data, &level_index);
previous = skiplist_set_get_equal_previous(sl, data, &level_index);
return (previous != NULL) ? previous->links[level_index]->data : NULL;
}
@ -274,7 +324,7 @@ int skiplist_set_find_all(SkiplistSet *sl, void *data, SkiplistSetIterator *iter
int level_index;
SkiplistSetNode *previous;
previous = skiplist_set_get_previous(sl, data, &level_index);
previous = skiplist_set_get_equal_previous(sl, data, &level_index);
if (previous == NULL) {
iterator->tail = sl->tail;
iterator->current = sl->tail;
@ -285,3 +335,22 @@ int skiplist_set_find_all(SkiplistSet *sl, void *data, SkiplistSetIterator *iter
iterator->tail = iterator->current->links[0];
return 0;
}
int skiplist_set_find_range(SkiplistSet *sl, void *start_data, void *end_data,
SkiplistSetIterator *iterator)
{
if (sl->compare_func(start_data, end_data) > 0) {
iterator->current = sl->tail;
iterator->tail = sl->tail;
return EINVAL;
}
iterator->current = skiplist_set_get_first_larger_or_equal(sl, start_data);
if (iterator->current == sl->tail) {
iterator->tail = sl->tail;
return ENOENT;
}
iterator->tail = skiplist_set_get_first_larger(sl, end_data);
return iterator->current != iterator->tail ? 0 : ENOENT;
}

View File

@ -59,11 +59,13 @@ int skiplist_set_insert(SkiplistSet *sl, void *data);
int skiplist_set_delete(SkiplistSet *sl, void *data);
void *skiplist_set_find(SkiplistSet *sl, void *data);
int skiplist_set_find_all(SkiplistSet *sl, void *data, SkiplistSetIterator *iterator);
int skiplist_set_find_range(SkiplistSet *sl, void *start_data, void *end_data,
SkiplistSetIterator *iterator);
static inline void skiplist_set_iterator(SkiplistSet *sl, SkiplistSetIterator *iterator)
{
iterator->tail = sl->tail;
iterator->current = sl->top->links[0];
iterator->tail = sl->tail;
}
static inline void *skiplist_set_next(SkiplistSetIterator *iterator)

View File

@ -32,6 +32,29 @@ static int compare_func(const void *p1, const void *p2)
return *((int *)p1) - *((int *)p2);
}
void set_rand_numbers(const int multiple)
{
int i;
int tmp;
int index1;
int index2;
for (i=0; i<COUNT; i++) {
numbers[i] = multiple * i + 1;
}
for (i=0; i<COUNT; i++) {
index1 = LAST_INDEX * (int64_t)rand() / (int64_t)RAND_MAX;
index2 = LAST_INDEX * (int64_t)rand() / (int64_t)RAND_MAX;
if (index1 == index2) {
continue;
}
tmp = numbers[index1];
numbers[index1] = numbers[index2];
numbers[index2] = tmp;
}
}
static int test_insert()
{
int i;
@ -40,6 +63,8 @@ static int test_insert()
int64_t end_time;
void *value;
set_rand_numbers(1);
instance_count = 0;
start_time = get_current_time_ms();
for (i=0; i<COUNT; i++) {
@ -145,7 +170,10 @@ static int test_stable_sort()
Record tmp_records[RECORDS];
Record *record;
Record target;
Record start;
Record end;
void *value;
int div;
printf("test_stable_sort ...\n");
instance_count = 0;
@ -155,9 +183,15 @@ static int test_stable_sort()
return result;
}
if (skiplist_type == SKIPLIST_TYPE_SET) {
div = 1;
}
else {
div = 3;
}
for (i=0; i<RECORDS; i++) {
records[i].line = i + 1;
records[i].key = i + 1;
records[i].key = i / div + 1;
}
if (skiplist_type != SKIPLIST_TYPE_SET) {
@ -229,6 +263,29 @@ static int test_stable_sort()
}
printf("found record count: %d\n", i);
start.key = 10;
end.key = 1;
result = skiplist_find_range(&sl, &start, &end, &iterator);
assert(result == EINVAL);
start.key = -1;
end.key = 0;
result = skiplist_find_range(&sl, &start, &end, &iterator);
assert(result == ENOENT);
start.key = max_occur_key;
end.key = 32;
result = skiplist_find_range(&sl, &start, &end, &iterator);
assert(result == 0);
i = 0;
while ((value=skiplist_next(&iterator)) != NULL) {
record = (Record *)value;
printf("%d => #%d\n", record->key, record->line);
i++;
}
printf("count: %d\n\n", i);
/*
if (skiplist_type == SKIPLIST_TYPE_FLAT) {
flat_skiplist_print(&sl.u.flat, skiplist_tostring);
@ -272,12 +329,49 @@ static int test_stable_sort()
return 0;
}
static void test_find_range()
{
int n_start;
int n_end;
int result;
int i;
int *value;
SkiplistIterator iterator;
set_rand_numbers(2);
for (i=0; i<COUNT; i++) {
if ((result=skiplist_insert(&sl, numbers + i)) != 0) {
return;
}
instance_count++;
}
n_start = 10;
n_end = 1;
result = skiplist_find_range(&sl, &n_start, &n_end, &iterator);
assert(result == EINVAL);
n_start = -1;
n_end = 0;
result = skiplist_find_range(&sl, &n_start, &n_end, &iterator);
assert(result == ENOENT);
n_start = 0;
n_end = 10;
result = skiplist_find_range(&sl, &n_start, &n_end, &iterator);
assert(result == 0);
i = 0;
while ((value=(int *)skiplist_next(&iterator)) != NULL) {
printf("value: %d\n", *value);
i++;
}
printf("count: %d\n\n", i);
}
int main(int argc, char *argv[])
{
int i;
int tmp;
int index1;
int index2;
int result;
@ -294,20 +388,6 @@ int main(int argc, char *argv[])
numbers = (int *)malloc(sizeof(int) * COUNT);
srand(time(NULL));
for (i=0; i<COUNT; i++) {
numbers[i] = i + 1;
}
for (i=0; i<COUNT; i++) {
index1 = LAST_INDEX * (int64_t)rand() / (int64_t)RAND_MAX;
index2 = LAST_INDEX * (int64_t)rand() / (int64_t)RAND_MAX;
if (index1 == index2) {
continue;
}
tmp = numbers[index1];
numbers[index1] = numbers[index2];
numbers[index2] = tmp;
}
fast_mblock_manager_init();
result = skiplist_init_ex(&sl, LEVEL_COUNT, compare_func,
@ -326,7 +406,7 @@ int main(int argc, char *argv[])
printf("\n");
assert(instance_count == 0);
test_insert();
test_find_range();
printf("\n");
skiplist_destroy(&sl);

View File

@ -30,6 +30,29 @@ static int compare_func(const void *p1, const void *p2)
return *((int *)p1) - *((int *)p2);
}
void set_rand_numbers(const int multiple)
{
int i;
int tmp;
int index1;
int index2;
for (i=0; i<COUNT; i++) {
numbers[i] = multiple * i + 1;
}
for (i=0; i<COUNT; i++) {
index1 = LAST_INDEX * (int64_t)rand() / (int64_t)RAND_MAX;
index2 = LAST_INDEX * (int64_t)rand() / (int64_t)RAND_MAX;
if (index1 == index2) {
continue;
}
tmp = numbers[index1];
numbers[index1] = numbers[index2];
numbers[index2] = tmp;
}
}
static int test_insert()
{
int i;
@ -38,6 +61,8 @@ static int test_insert()
int64_t end_time;
void *value;
set_rand_numbers(1);
instance_count = 0;
start_time = get_current_time_ms();
for (i=0; i<COUNT; i++) {
@ -108,31 +133,54 @@ static void test_delete()
assert(i==0);
}
static void test_find_range()
{
int n_start;
int n_end;
int result;
int i;
int *value;
SkiplistSetIterator iterator;
set_rand_numbers(2);
for (i=0; i<COUNT; i++) {
if ((result=skiplist_set_insert(&sl, numbers + i)) != 0) {
return;
}
instance_count++;
}
n_start = 10;
n_end = 1;
result = skiplist_set_find_range(&sl, &n_start, &n_end, &iterator);
assert(result == EINVAL);
n_start = -1;
n_end = 0;
result = skiplist_set_find_range(&sl, &n_start, &n_end, &iterator);
assert(result == ENOENT);
n_start = 0;
n_end = 10;
result = skiplist_set_find_range(&sl, &n_start, &n_end, &iterator);
assert(result == 0);
i = 0;
while ((value=(int *)skiplist_set_next(&iterator)) != NULL) {
printf("value: %d\n", *value);
i++;
}
printf("count: %d\n\n", i);
}
int main(int argc, char *argv[])
{
int i;
int tmp;
int index1;
int index2;
int result;
log_init();
numbers = (int *)malloc(sizeof(int) * COUNT);
srand(time(NULL));
for (i=0; i<COUNT; i++) {
numbers[i] = i + 1;
}
for (i=0; i<COUNT; i++) {
index1 = LAST_INDEX * (int64_t)rand() / (int64_t)RAND_MAX;
index2 = LAST_INDEX * (int64_t)rand() / (int64_t)RAND_MAX;
if (index1 == index2) {
continue;
}
tmp = numbers[index1];
numbers[index1] = numbers[index2];
numbers[index2] = tmp;
}
fast_mblock_manager_init();
result = skiplist_set_init_ex(&sl, LEVEL_COUNT, compare_func,
@ -149,6 +197,11 @@ int main(int argc, char *argv[])
test_delete();
printf("\n");
test_find_range();
test_delete();
printf("\n");
test_insert();
printf("\n");