libfastcommon/src/skiplist.h

227 lines
6.3 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"
#include "skiplist_set.h"
#define SKIPLIST_TYPE_FLAT 0
#define SKIPLIST_TYPE_MULTI 1
#define SKIPLIST_TYPE_SET 2
typedef struct skiplist
{
int type;
union {
FlatSkiplist flat;
MultiSkiplist multi;
SkiplistSet set;
} u;
} Skiplist;
typedef struct skiplist_iterator {
int type;
union {
FlatSkiplistIterator flat;
MultiSkiplistIterator multi;
SkiplistSetIterator set;
} 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;
switch (type) {
case SKIPLIST_TYPE_FLAT:
return flat_skiplist_init_ex(&sl->u.flat, level_count,
compare_func, free_func, min_alloc_elements_once);
case SKIPLIST_TYPE_MULTI:
return multi_skiplist_init_ex(&sl->u.multi, level_count,
compare_func, free_func, min_alloc_elements_once);
case SKIPLIST_TYPE_SET:
return skiplist_set_init_ex(&sl->u.set, level_count,
compare_func, free_func, min_alloc_elements_once);
default:
return EINVAL;
}
}
static inline void skiplist_destroy(Skiplist *sl)
{
switch (sl->type) {
case SKIPLIST_TYPE_FLAT:
flat_skiplist_destroy(&sl->u.flat);
break;
case SKIPLIST_TYPE_MULTI:
multi_skiplist_destroy(&sl->u.multi);
break;
case SKIPLIST_TYPE_SET:
skiplist_set_destroy(&sl->u.set);
break;
default:
break;
}
}
static inline int skiplist_insert(Skiplist *sl, void *data)
{
switch (sl->type) {
case SKIPLIST_TYPE_FLAT:
return flat_skiplist_insert(&sl->u.flat, data);
case SKIPLIST_TYPE_MULTI:
return multi_skiplist_insert(&sl->u.multi, data);
case SKIPLIST_TYPE_SET:
return skiplist_set_insert(&sl->u.set, data);
default:
return EINVAL;
}
}
static inline int skiplist_delete(Skiplist *sl, void *data)
{
switch (sl->type) {
case SKIPLIST_TYPE_FLAT:
return flat_skiplist_delete(&sl->u.flat, data);
case SKIPLIST_TYPE_MULTI:
return multi_skiplist_delete(&sl->u.multi, data);
case SKIPLIST_TYPE_SET:
return skiplist_set_delete(&sl->u.set, data);
default:
return EINVAL;
}
}
static inline int skiplist_delete_all(Skiplist *sl, void *data, int *delete_count)
{
int result;
switch (sl->type) {
case SKIPLIST_TYPE_FLAT:
return flat_skiplist_delete_all(&sl->u.flat, data, delete_count);
case SKIPLIST_TYPE_MULTI:
return multi_skiplist_delete_all(&sl->u.multi, data, delete_count);
case SKIPLIST_TYPE_SET:
result = skiplist_set_delete(&sl->u.set, data);
*delete_count = (result == 0) ? 1 : 0;
return result;
default:
return EINVAL;
}
}
static inline void *skiplist_find(Skiplist *sl, void *data)
{
switch (sl->type) {
case SKIPLIST_TYPE_FLAT:
return flat_skiplist_find(&sl->u.flat, data);
case SKIPLIST_TYPE_MULTI:
return multi_skiplist_find(&sl->u.multi, data);
case SKIPLIST_TYPE_SET:
return skiplist_set_find(&sl->u.set, data);
default:
return NULL;
}
}
static inline int skiplist_find_all(Skiplist *sl, void *data, SkiplistIterator *iterator)
{
iterator->type = sl->type;
switch (sl->type) {
case SKIPLIST_TYPE_FLAT:
return flat_skiplist_find_all(&sl->u.flat, data, &iterator->u.flat);
case SKIPLIST_TYPE_MULTI:
return multi_skiplist_find_all(&sl->u.multi, data, &iterator->u.multi);
case SKIPLIST_TYPE_SET:
return EOPNOTSUPP;
default:
return EINVAL;
}
}
static inline void skiplist_iterator(Skiplist *sl, SkiplistIterator *iterator)
{
iterator->type = sl->type;
switch (sl->type) {
case SKIPLIST_TYPE_FLAT:
return flat_skiplist_iterator(&sl->u.flat, &iterator->u.flat);
case SKIPLIST_TYPE_MULTI:
return multi_skiplist_iterator(&sl->u.multi, &iterator->u.multi);
case SKIPLIST_TYPE_SET:
return skiplist_set_iterator(&sl->u.set, &iterator->u.set);
default:
return EINVAL;
}
}
static inline void *skiplist_next(SkiplistIterator *iterator)
{
switch (iterator->type) {
case SKIPLIST_TYPE_FLAT:
return flat_skiplist_next(&iterator->u.flat);
case SKIPLIST_TYPE_MULTI:
return multi_skiplist_next(&iterator->u.multi);
case SKIPLIST_TYPE_SET:
return skiplist_set_next(&iterator->u.set);
default:
return NULL;
}
}
static inline bool skiplist_empty(Skiplist *sl)
{
switch (sl->type) {
case SKIPLIST_TYPE_FLAT:
return flat_skiplist_empty(&sl->u.flat);
case SKIPLIST_TYPE_MULTI:
return multi_skiplist_empty(&sl->u.multi);
case SKIPLIST_TYPE_SET:
return skiplist_set_empty(&sl->u.set);
default:
return false;
}
}
static inline const char* skiplist_get_type_caption(Skiplist *sl)
{
switch (sl->type) {
case SKIPLIST_TYPE_FLAT:
return "flat";
case SKIPLIST_TYPE_MULTI:
return "multi";
case SKIPLIST_TYPE_SET:
return "set";
default:
return "unknown";
}
}
#ifdef __cplusplus
}
#endif
#endif