#include #include "skiplist.h" struct skiplist_t{ skiplist_node_t* header; skiplist_size_t size; int level; skiplist_probability_t probability; skiplist_cmp cmp; }; #define SKIPLIST_LEVEL_MAX 32 struct skiplist_level_t{ skiplist_node_t* next; }; struct skiplist_node_t{ void* data; skiplist_node_t* prev; skiplist_level_t lev[]; }; static inline skiplist_node_t* __skiplist_node_create(int level){ return (skiplist_node_t*)SKIPLIST_ALLOC_MEM(sizeof(skiplist_node_t) + sizeof(skiplist_level_t) * level); } static inline void __skiplist_node_destroy(skiplist_node_t* node){ SKIPLIST_FREE_MEM(node); } static inline int __skiplist_random_level(skiplist_t* sl){ int level = 1; while(SKIPLIST_RAND() >= (RAND_MAX * sl->probability)){ ++ level; } return (level > SKIPLIST_LEVEL_MAX ? SKIPLIST_LEVEL_MAX : level); } static inline int __skiplist_create( skiplist_t** sl, skiplist_probability_t probability, skiplist_cmp cmp ){ skiplist_t* tsl = (skiplist_t*)SKIPLIST_ALLOC_MEM(sizeof(skiplist_t)); if(tsl == NULL){ *sl = tsl; return SKIPLISTERR_POINTR; } if((tsl->header = __skiplist_node_create(SKIPLIST_LEVEL_MAX)) == NULL){ *sl = NULL; SKIPLIST_FREE_MEM(tsl); return SKIPLISTERR_POINTR; } tsl->header->prev = tsl->header; int i = 0; for(;i < SKIPLIST_LEVEL_MAX; ++i){ tsl->header->lev[i].next = tsl->header; } tsl->size = 0; tsl->level = 1; tsl->probability = probability; tsl->cmp = cmp; *sl = tsl; return SKIPLISTOK; } static inline int __skiplist_insert( skiplist_t* sl, void* key, void* data ){ skiplist_node_t* level_prev[SKIPLIST_LEVEL_MAX]; skiplist_node_t *cur = sl->header,*end = sl->header; skiplist_node_t* node; int i = sl->level - 1,level; for(;i >= 0; -- i){ for(;cur->lev[i].next != end && sl->cmp(key,cur->lev[i].next->data) > 0;cur = cur->lev[i].next); level_prev[i] = cur; } if(cur->lev[0].next != end && sl->cmp(key,cur->lev[0].next->data) == 0){ return SKIPLISTERR_REEXIST; } level = __skiplist_random_level(sl); if((node = __skiplist_node_create(level)) == NULL){ return SKIPLISTERR_POINTR; } node->data = data; if(level > sl->level){ for(i = sl->level;i < level; ++ i){ level_prev[i] = sl->header; } sl->level = level; } for(i = 0;i < level; ++ i){ node->lev[i].next = level_prev[i]->lev[i].next; level_prev[i]->lev[i].next = node; } node->prev = level_prev[0]; node->lev[0].next->prev = node; ++ sl->size; return SKIPLISTOK; } static inline int __skiplist_erase( skiplist_t* sl, void* key, void** retdata ){ skiplist_node_t* level_prev[SKIPLIST_LEVEL_MAX]; skiplist_node_t *cur = sl->header,*end = sl->header; skiplist_node_t* node; int i = sl->level - 1; for(;i >= 0; -- i){ for(;cur->lev[i].next != end && sl->cmp(key,cur->lev[i].next->data) > 0;cur = cur->lev[i].next); level_prev[i] = cur; } if(cur->lev[0].next == end || sl->cmp(key,cur->lev[0].next->data) < 0){ return SKIPLISTERR_NOEXIST; } cur = cur->lev[0].next; node = cur; for(i = 0;i < sl->level; ++i){ if(level_prev[i]->lev[i].next == node){ level_prev[i]->lev[i].next = node->lev[i].next; } } node->lev[0].next->prev = node->prev; for(;sl->level > 1 && sl->header->lev[sl->level - 1].next == end; -- sl->level); if(retdata != NULL){ *retdata = node->data; } __skiplist_node_destroy(node); -- sl->size; return SKIPLISTOK; } static inline int __skiplist_exist( skiplist_t* sl, void* key, void** retdata ){ skiplist_node_t *cur = sl->header,*end = sl->header; int i = sl->level - 1; for(;i >= 0; -- i){ for(;cur->lev[i].next != end && sl->cmp(key,cur->lev[i].next->data) > 0;cur = cur->lev[i].next); } if(cur->lev[0].next != end && sl->cmp(key,cur->lev[0].next->data) == 0){ if(retdata != NULL){ *retdata = cur->lev[0].next->data; } return SKIPLISTOK_EXIST; } return SKIPLISTERR_NOEXIST; } static inline int __skiplist_update( skiplist_t* sl, void* oldkey, void* newkey, void* newdata, void** retdata ){ skiplist_node_t* level_prev[SKIPLIST_LEVEL_MAX]; skiplist_node_t *cur = sl->header,*node,*end = sl->header; int i = sl->level - 1; for(;i >= 0; -- i){ for(;cur->lev[i].next != end && sl->cmp(oldkey,cur->lev[i].next->data) > 0;cur = cur->lev[i].next); level_prev[i] = cur; } if(cur->lev[0].next != end && sl->cmp(oldkey,cur->lev[0].next->data) == 0){ cur = cur->lev[0].next; if((cur->prev != end && sl->cmp(newkey,cur->prev->data) == 0) || (cur->lev[0].next != end && sl->cmp(newkey,cur->lev[0].next->data) == 0)){ return SKIPLISTERR_REEXIST; } if(sl->cmp(newkey,cur->data) == 0){ if(retdata != NULL){ *retdata = cur->data; } cur->data = newdata; } else{ node = cur; for(i = 0;i < sl->level; ++ i){ if(level_prev[i]->lev[i].next == node){ level_prev[i]->lev[i].next = node->lev[i].next; } } node->lev[0].next->prev = node->prev; for(;sl->level > 1 && sl->header->lev[sl->level - 1].next == end; -- sl->level); if(retdata != NULL){ *retdata = node->data; } __skiplist_node_destroy(node); -- sl->size; return __skiplist_insert(sl,newkey,newdata); } return SKIPLISTOK; } return SKIPLISTERR_NOEXIST; } int skiplist_create(skiplist_t** sl,skiplist_probability_t probability,skiplist_cmp cmp){ if(sl == NULL || probability <= 1e-6 || probability - 1 >= 1e-6 || cmp == NULL){ return SKIPLISTERR_PARAM; } return __skiplist_create(sl,probability,cmp); } int skiplist_size(skiplist_t* sl,skiplist_size_t* size){ if(sl == NULL || size == NULL){ *size = 0; return SKIPLISTERR_PARAM; } *size = sl->size; return SKIPLISTOK; } int skiplist_getcmp(skiplist_t* sl,skiplist_cmp* cmp){ if(sl == NULL || cmp == NULL){ return SKIPLISTERR_PARAM; } *cmp = sl->cmp; return SKIPLISTOK; } int skiplist_insert(skiplist_t* sl,void* key,void* data){ if(sl == NULL || key == NULL || data == NULL){ return SKIPLISTERR_PARAM; } return __skiplist_insert(sl,key,data); } int skiplist_erase(skiplist_t* sl,void* key,void** retdata){ if(sl == NULL || key == NULL){ return SKIPLISTERR_PARAM; } return __skiplist_erase(sl,key,retdata); } int skiplist_exist(skiplist_t* sl,void* key,void** retdata){ if(sl == NULL || key == NULL){ return SKIPLISTERR_PARAM; } return __skiplist_exist(sl,key,retdata); } int skiplist_update(skiplist_t* sl,void* oldkey,void* newkey,void* newdata,void** retdata){ if(sl == NULL || oldkey == NULL || newkey == NULL || newdata == NULL){ return SKIPLISTERR_PARAM; } return __skiplist_update(sl,oldkey,newkey,newdata,retdata); } int skiplist_destroy(skiplist_t** sl){ if(sl == NULL || *sl == NULL){ return SKIPLISTERR_PARAM; } skiplist_node_t *cur = (*sl)->header,*tmp,*end = (*sl)->header; for( ;cur != end; cur = tmp){ tmp = cur->lev[0].next; __skiplist_node_destroy(cur); } SKIPLIST_FREE_MEM(*sl); *sl = NULL; return SKIPLISTOK; } int skiplist_begin(skiplist_t* sl,skiplist_iterator_t* it){ int ret = SKIPLISTERR_PARAM; if(sl == NULL || it == NULL){ return ret; } if((ret = skiplist_iterator_create(it)) == SKIPLISTOK){ *it = sl->header->lev[0].next; } return ret; } int skiplist_end(skiplist_t* sl,skiplist_iterator_t* it){ int ret = SKIPLISTERR_PARAM; if(sl == NULL || it == NULL){ return ret; } if((ret = skiplist_iterator_create(it)) == SKIPLISTOK){ *it = sl->header; } return ret; } int skiplist_iterator_create(skiplist_iterator_t* it){ return SKIPLISTOK; } int skiplist_iterator_equal(skiplist_iterator_t* it1,skiplist_iterator_t* it2){ return ((*it1) == (*it2)); } void skiplist_iterator_assign(skiplist_iterator_t* dit,const skiplist_iterator_t* sit){ (*dit) = (*sit); } const void* skiplist_iterator_value(skiplist_iterator_t* it){ return (*it)->data; } void skiplist_iterator_next(skiplist_iterator_t* it){ (*it) = (*it)->lev[0].next; } void skiplist_iterator_prev(skiplist_iterator_t* it){ (*it) = (*it)->prev; } void skiplist_iterator_destroy(skiplist_iterator_t* it){ ; }