152 lines
3.8 KiB
C
152 lines
3.8 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.
|
|
**/
|
|
|
|
//skiplist.h, support stable sort :)
|
|
#ifndef _SKIPLIST_H
|
|
#define _SKIPLIST_H
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "common_define.h"
|
|
#include "skiplist_common.h"
|
|
#include "flat_skiplist.h"
|
|
#include "multi_skiplist.h"
|
|
|
|
#define SKIPLIST_TYPE_FLAT 0
|
|
#define SKIPLIST_TYPE_MULTI 1
|
|
|
|
typedef struct skiplist
|
|
{
|
|
int type;
|
|
union {
|
|
FlatSkiplist flat;
|
|
MultiSkiplist multi;
|
|
} u;
|
|
} Skiplist;
|
|
|
|
typedef struct skiplist_iterator {
|
|
int type;
|
|
union {
|
|
FlatSkiplistIterator flat;
|
|
MultiSkiplistIterator multi;
|
|
} u;
|
|
} SkiplistIterator;
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define skiplist_init(sl, level_count, compare_func, free_func) \
|
|
skiplist_init_ex(sl, level_count, compare_func, free_func, \
|
|
SKIPLIST_DEFAULT_MIN_ALLOC_ELEMENTS_ONCE, SKIPLIST_TYPE_FLAT)
|
|
|
|
static inline int skiplist_init_ex(Skiplist *sl, const int level_count,
|
|
skiplist_compare_func compare_func, skiplist_free_func free_func,
|
|
const int min_alloc_elements_once, const int type)
|
|
{
|
|
sl->type = type;
|
|
if (type == SKIPLIST_TYPE_FLAT) {
|
|
return flat_skiplist_init_ex(&sl->u.flat, level_count,
|
|
compare_func, free_func, min_alloc_elements_once);
|
|
}
|
|
else {
|
|
return multi_skiplist_init_ex(&sl->u.multi, level_count,
|
|
compare_func, free_func, min_alloc_elements_once);
|
|
}
|
|
}
|
|
|
|
static inline void skiplist_destroy(Skiplist *sl)
|
|
{
|
|
if (sl->type == SKIPLIST_TYPE_FLAT) {
|
|
flat_skiplist_destroy(&sl->u.flat);
|
|
}
|
|
else {
|
|
multi_skiplist_destroy(&sl->u.multi);
|
|
}
|
|
}
|
|
|
|
static inline int skiplist_insert(Skiplist *sl, void *data)
|
|
{
|
|
if (sl->type == SKIPLIST_TYPE_FLAT) {
|
|
return flat_skiplist_insert(&sl->u.flat, data);
|
|
}
|
|
else {
|
|
return multi_skiplist_insert(&sl->u.multi, data);
|
|
}
|
|
}
|
|
|
|
static inline int skiplist_delete(Skiplist *sl, void *data)
|
|
{
|
|
if (sl->type == SKIPLIST_TYPE_FLAT) {
|
|
return flat_skiplist_delete(&sl->u.flat, data);
|
|
}
|
|
else {
|
|
return multi_skiplist_delete(&sl->u.multi, data);
|
|
}
|
|
}
|
|
|
|
static inline int skiplist_delete_all(Skiplist *sl, void *data, int *delete_count)
|
|
{
|
|
if (sl->type == SKIPLIST_TYPE_FLAT) {
|
|
return flat_skiplist_delete_all(&sl->u.flat, data, delete_count);
|
|
}
|
|
else {
|
|
return multi_skiplist_delete_all(&sl->u.multi, data, delete_count);
|
|
}
|
|
}
|
|
|
|
static inline void *skiplist_find(Skiplist *sl, void *data)
|
|
{
|
|
if (sl->type == SKIPLIST_TYPE_FLAT) {
|
|
return flat_skiplist_find(&sl->u.flat, data);
|
|
}
|
|
else {
|
|
return multi_skiplist_find(&sl->u.multi, data);
|
|
}
|
|
}
|
|
|
|
static inline int skiplist_find_all(Skiplist *sl, void *data, SkiplistIterator *iterator)
|
|
{
|
|
iterator->type = sl->type;
|
|
if (sl->type == SKIPLIST_TYPE_FLAT) {
|
|
return flat_skiplist_find_all(&sl->u.flat, data, &iterator->u.flat);
|
|
}
|
|
else {
|
|
return multi_skiplist_find_all(&sl->u.multi, data, &iterator->u.multi);
|
|
}
|
|
}
|
|
|
|
static inline void skiplist_iterator(Skiplist *sl, SkiplistIterator *iterator)
|
|
{
|
|
iterator->type = sl->type;
|
|
if (sl->type == SKIPLIST_TYPE_FLAT) {
|
|
return flat_skiplist_iterator(&sl->u.flat, &iterator->u.flat);
|
|
}
|
|
else {
|
|
return multi_skiplist_iterator(&sl->u.multi, &iterator->u.multi);
|
|
}
|
|
}
|
|
|
|
static inline void *skiplist_next(SkiplistIterator *iterator)
|
|
{
|
|
if (iterator->type == SKIPLIST_TYPE_FLAT) {
|
|
return flat_skiplist_next(&iterator->u.flat);
|
|
}
|
|
else {
|
|
return multi_skiplist_next(&iterator->u.multi);
|
|
}
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
|