libfastcommon/src/flat_skiplist.h

120 lines
3.4 KiB
C

/**
* Copyright (C) 2015 Happy Fish / YuQing
*
* libfastcommon may be copied only under the terms of the GNU General
* Public License V3, which may be found in the FastDFS source kit.
* Please visit the FastDFS Home Page http://www.csource.org/ for more detail.
**/
//flat_skiplist.h, support duplicated entries, and support stable sort :)
//you should use multi_skiplist with too many duplicated entries
#ifndef _FLAT_SKIPLIST_H
#define _FLAT_SKIPLIST_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common_define.h"
#include "skiplist_common.h"
#include "fast_mblock.h"
typedef struct flat_skiplist_node
{
void *data;
struct flat_skiplist_node *prev; //for stable sort
struct flat_skiplist_node *links[0];
} FlatSkiplistNode;
typedef struct flat_skiplist
{
int level_count;
int top_level_index;
skiplist_compare_func compare_func;
skiplist_free_func free_func;
struct fast_mblock_man *mblocks; //node allocators
FlatSkiplistNode *top; //the top node
FlatSkiplistNode *tail; //the tail node for interator
FlatSkiplistNode **tmp_previous; //thread safe for insert
} FlatSkiplist;
typedef struct flat_skiplist_iterator {
FlatSkiplistNode *top;
FlatSkiplistNode *current;
} FlatSkiplistIterator;
#ifdef __cplusplus
extern "C" {
#endif
#define flat_skiplist_init(sl, level_count, compare_func, free_func) \
flat_skiplist_init_ex(sl, level_count, compare_func, free_func, \
SKIPLIST_DEFAULT_MIN_ALLOC_ELEMENTS_ONCE)
int flat_skiplist_init_ex(FlatSkiplist *sl, const int level_count,
skiplist_compare_func compare_func, skiplist_free_func free_func,
const int min_alloc_elements_once);
void flat_skiplist_destroy(FlatSkiplist *sl);
int flat_skiplist_insert(FlatSkiplist *sl, void *data);
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)
{
iterator->top = sl->top;
iterator->current = sl->tail->prev;
}
static inline void *flat_skiplist_next(FlatSkiplistIterator *iterator)
{
void *data;
if (iterator->current == iterator->top) {
return NULL;
}
data = iterator->current->data;
iterator->current = iterator->current->prev;
return data;
}
static inline bool flat_skiplist_empty(FlatSkiplist *sl)
{
return sl->top->links[0] == sl->tail;
}
typedef const char * (*flat_skiplist_tostring_func)(void *data, char *buff, const int size);
static inline void flat_skiplist_print(FlatSkiplist *sl, flat_skiplist_tostring_func tostring_func)
{
int i;
FlatSkiplistNode *current;
char buff[1024];
printf("###################\n");
for (i=sl->top_level_index; i>=0; i--) {
printf("level %d: ", i);
current = sl->top->links[i];
while (current != sl->tail) {
printf("%s ", tostring_func(current->data, buff, sizeof(buff)));
current = current->links[i];
}
printf("\n");
}
printf("###################\n");
printf("\n");
}
#ifdef __cplusplus
}
#endif
#endif