├── README.md ├── LICENSE ├── skiplist_test.c ├── skiplist_with_rank_test.c ├── skiplist.h └── skiplist_with_rank.h /README.md: -------------------------------------------------------------------------------- 1 | skiplist 2 | ======== 3 | 4 | When skiplist meets list head, something interesting might happen...Code less than z_set in Redis. 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Leo Ma 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /skiplist_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015, Leo Ma 3 | */ 4 | #include 5 | #include 6 | #if defined(__MACH__) && !defined(CLOCK_REALTIME) 7 | #include 8 | 9 | #define CLOCK_REALTIME 0 10 | #define CLOCK_MONOTONIC 1 11 | 12 | int clock_gettime(int clk_id, struct timespec* t) { 13 | struct timeval now; 14 | int rv = gettimeofday(&now, NULL); 15 | if (rv) return rv; 16 | t->tv_sec = now.tv_sec; 17 | t->tv_nsec = now.tv_usec * 1000; 18 | return 0; 19 | } 20 | #else 21 | #include 22 | #endif 23 | 24 | #include "skiplist.h" 25 | 26 | #define N 2 * 1024 * 1024 27 | // #define SKIPLIST_DEBUG 28 | 29 | int 30 | main(void) 31 | { 32 | int i; 33 | struct timespec start, end; 34 | 35 | int *key = malloc(N * sizeof(int)); 36 | if (key == NULL) { 37 | exit(-1); 38 | } 39 | 40 | struct skiplist *list = skiplist_new(); 41 | if (list == NULL) { 42 | exit(-1); 43 | } 44 | 45 | printf("Test start!\n"); 46 | printf("Add %d nodes...\n", N); 47 | 48 | /* Insert test */ 49 | srandom(time(NULL)); 50 | clock_gettime(CLOCK_MONOTONIC, &start); 51 | for (i = 0; i < N; i++) { 52 | int value = key[i] = (int)random(); 53 | skiplist_insert(list, key[i], value); 54 | } 55 | clock_gettime(CLOCK_MONOTONIC, &end); 56 | printf("time span: %ldms\n", (end.tv_sec - start.tv_sec)*1000 + (end.tv_nsec - start.tv_nsec)/1000000); 57 | #ifdef SKIPLIST_DEBUG 58 | skiplist_dump(list); 59 | #endif 60 | 61 | /* Search test */ 62 | printf("Now search each node...\n"); 63 | clock_gettime(CLOCK_MONOTONIC, &start); 64 | for (i = 0; i < N; i++) { 65 | struct skipnode *node = skiplist_search(list, key[i]); 66 | if (node != NULL) { 67 | #ifdef SKIPLIST_DEBUG 68 | printf("key:0x%08x value:0x%08x\n", node->key, node->value); 69 | #endif 70 | } else { 71 | printf("Not found:0x%08x\n", key[i]); 72 | } 73 | } 74 | clock_gettime(CLOCK_MONOTONIC, &end); 75 | printf("time span: %ldms\n", (end.tv_sec - start.tv_sec)*1000 + (end.tv_nsec - start.tv_nsec)/1000000); 76 | 77 | /* Delete test */ 78 | printf("Now remove all nodes...\n"); 79 | clock_gettime(CLOCK_MONOTONIC, &start); 80 | for (i = 0; i < N; i++) { 81 | skiplist_remove(list, key[i]); 82 | } 83 | clock_gettime(CLOCK_MONOTONIC, &end); 84 | printf("time span: %ldms\n", (end.tv_sec - start.tv_sec)*1000 + (end.tv_nsec - start.tv_nsec)/1000000); 85 | #ifdef SKIPLIST_DEBUG 86 | skiplist_dump(list); 87 | #endif 88 | 89 | printf("End of Test.\n"); 90 | skiplist_delete(list); 91 | 92 | free(key); 93 | 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /skiplist_with_rank_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015, Leo Ma 3 | */ 4 | 5 | #include 6 | #include 7 | #if defined(__MACH__) && !defined(CLOCK_REALTIME) 8 | #include 9 | 10 | #define CLOCK_REALTIME 0 11 | #define CLOCK_MONOTONIC 1 12 | 13 | int clock_gettime(int clk_id, struct timespec* t) { 14 | struct timeval now; 15 | int rv = gettimeofday(&now, NULL); 16 | if (rv) return rv; 17 | t->tv_sec = now.tv_sec; 18 | t->tv_nsec = now.tv_usec * 1000; 19 | return 0; 20 | } 21 | #else 22 | #include 23 | #endif 24 | 25 | #include "skiplist_with_rank.h" 26 | 27 | #define N 1024 * 1024 * 2 28 | //#define SKIPLIST_DEBUG 29 | 30 | int 31 | main(void) 32 | { 33 | int i; 34 | struct timespec start, end; 35 | 36 | int *key = (int *)malloc(N * sizeof(int)); 37 | if (key == NULL) { 38 | exit(-1); 39 | } 40 | 41 | struct skiplist *list = skiplist_new(); 42 | if (list == NULL) { 43 | exit(-1); 44 | } 45 | 46 | printf("Test start!\n"); 47 | printf("Add %d nodes...\n", N); 48 | 49 | /* Insert test */ 50 | srandom(time(NULL)); 51 | clock_gettime(CLOCK_MONOTONIC, &start); 52 | for (i = 0; i < N; i++) { 53 | int value = key[i] = (int)random(); 54 | skiplist_insert(list, key[i], value); 55 | } 56 | clock_gettime(CLOCK_MONOTONIC, &end); 57 | printf("time span: %ldms\n", (end.tv_sec - start.tv_sec)*1000 + (end.tv_nsec - start.tv_nsec)/1000000); 58 | #ifdef SKIPLIST_DEBUG 59 | skiplist_dump(list); 60 | #endif 61 | 62 | /* Search test 1 */ 63 | printf("Now search each node by key...\n"); 64 | clock_gettime(CLOCK_MONOTONIC, &start); 65 | for (i = 0; i < N; i++) { 66 | struct skipnode *node = skiplist_search_by_key(list, key[i]); 67 | if (node != NULL) { 68 | #ifdef SKIPLIST_DEBUG 69 | printf("key:0x%08x value:0x%08x\n", node->key, node->value); 70 | #endif 71 | } else { 72 | printf("Not found:0x%08x\n", key[i]); 73 | } 74 | #ifdef SKIPLIST_DEBUG 75 | printf("key rank:%d\n", skiplist_key_rank(list, key[i])); 76 | #else 77 | //skiplist_key_rank(list, key[i]); 78 | #endif 79 | } 80 | clock_gettime(CLOCK_MONOTONIC, &end); 81 | printf("time span: %ldms\n", (end.tv_sec - start.tv_sec)*1000 + (end.tv_nsec - start.tv_nsec)/1000000); 82 | 83 | /* Search test 2 */ 84 | printf("Now search each node by rank...\n"); 85 | clock_gettime(CLOCK_MONOTONIC, &start); 86 | for (i = 0; i < N; i++) { 87 | struct skipnode *node = skiplist_search_by_rank(list, i + 1); 88 | if (node != NULL) { 89 | #ifdef SKIPLIST_DEBUG 90 | printf("rank:%d value:0x%08x\n", i + 1, node->value); 91 | #endif 92 | } else { 93 | printf("Not found:%d\n", i + 1); 94 | } 95 | } 96 | clock_gettime(CLOCK_MONOTONIC, &end); 97 | printf("time span: %ldms\n", (end.tv_sec - start.tv_sec)*1000 + (end.tv_nsec - start.tv_nsec)/1000000); 98 | 99 | /* Delete test */ 100 | printf("Now remove all nodes...\n"); 101 | clock_gettime(CLOCK_MONOTONIC, &start); 102 | for (i = 0; i < N; i++) { 103 | skiplist_remove(list, key[i]); 104 | } 105 | clock_gettime(CLOCK_MONOTONIC, &end); 106 | printf("time span: %ldms\n", (end.tv_sec - start.tv_sec)*1000 + (end.tv_nsec - start.tv_nsec)/1000000); 107 | #ifdef SKIPLIST_DEBUG 108 | skiplist_dump(list); 109 | #endif 110 | 111 | printf("End of Test.\n"); 112 | skiplist_delete(list); 113 | 114 | free(key); 115 | 116 | return 0; 117 | } 118 | -------------------------------------------------------------------------------- /skiplist.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015, Leo Ma 3 | */ 4 | 5 | #ifndef _SKIPLIST_H 6 | #define _SKIPLIST_H 7 | 8 | struct sk_link { 9 | struct sk_link *prev, *next; 10 | }; 11 | 12 | static inline void list_init(struct sk_link *link) 13 | { 14 | link->prev = link; 15 | link->next = link; 16 | } 17 | 18 | static inline void 19 | __list_add(struct sk_link *link, struct sk_link *prev, struct sk_link *next) 20 | { 21 | link->next = next; 22 | link->prev = prev; 23 | next->prev = link; 24 | prev->next = link; 25 | } 26 | 27 | static inline void __list_del(struct sk_link *prev, struct sk_link *next) 28 | { 29 | prev->next = next; 30 | next->prev = prev; 31 | } 32 | 33 | static inline void list_add(struct sk_link *link, struct sk_link *prev) 34 | { 35 | __list_add(link, prev, prev->next); 36 | } 37 | 38 | static inline void list_del(struct sk_link *link) 39 | { 40 | __list_del(link->prev, link->next); 41 | list_init(link); 42 | } 43 | 44 | static inline int list_empty(struct sk_link *link) 45 | { 46 | return link->next == link; 47 | } 48 | 49 | #define list_entry(ptr, type, member) \ 50 | ((type *)((char *)(ptr) - (size_t)(&((type *)0)->member))) 51 | 52 | #define skiplist_foreach(pos, end) \ 53 | for (; pos != end; pos = pos->next) 54 | 55 | #define skiplist_foreach_safe(pos, n, end) \ 56 | for (n = pos->next; pos != end; pos = n, n = pos->next) 57 | 58 | #define MAX_LEVEL 32 /* Should be enough for 2^32 elements */ 59 | 60 | struct skiplist { 61 | int level; 62 | int count; 63 | struct sk_link head[MAX_LEVEL]; 64 | }; 65 | 66 | struct skipnode { 67 | int key; 68 | int value; 69 | struct sk_link link[0]; 70 | }; 71 | 72 | static struct skipnode *skipnode_new(int level, int key, int value) 73 | { 74 | struct skipnode *node; 75 | node = malloc(sizeof(*node) + level * sizeof(struct sk_link)); 76 | if (node != NULL) { 77 | node->key = key; 78 | node->value = value; 79 | } 80 | return node; 81 | } 82 | 83 | static void skipnode_delete(struct skipnode *node) 84 | { 85 | free(node); 86 | } 87 | 88 | static struct skiplist *skiplist_new(void) 89 | { 90 | int i; 91 | struct skiplist *list = malloc(sizeof(*list)); 92 | if (list != NULL) { 93 | list->level = 1; 94 | list->count = 0; 95 | for (i = 0; i < sizeof(list->head) / sizeof(list->head[0]); i++) { 96 | list_init(&list->head[i]); 97 | } 98 | } 99 | return list; 100 | } 101 | 102 | static void skiplist_delete(struct skiplist *list) 103 | { 104 | struct sk_link *n; 105 | struct sk_link *pos = list->head[0].next; 106 | skiplist_foreach_safe(pos, n, &list->head[0]) { 107 | struct skipnode *node = list_entry(pos, struct skipnode, link[0]); 108 | skipnode_delete(node); 109 | } 110 | free(list); 111 | } 112 | 113 | static int random_level(void) 114 | { 115 | int level = 1; 116 | const double p = 0.25; 117 | while ((random() & 0xffff) < 0xffff * p) { 118 | level++; 119 | } 120 | return level > MAX_LEVEL ? MAX_LEVEL : level; 121 | } 122 | 123 | static struct skipnode *skiplist_search(struct skiplist *list, int key) 124 | { 125 | struct skipnode *node; 126 | int i = list->level - 1; 127 | struct sk_link *pos = &list->head[i]; 128 | struct sk_link *end = &list->head[i]; 129 | 130 | for (; i >= 0; i--) { 131 | pos = pos->next; 132 | skiplist_foreach(pos, end) { 133 | node = list_entry(pos, struct skipnode, link[i]); 134 | if (node->key >= key) { 135 | end = &node->link[i]; 136 | break; 137 | } 138 | } 139 | if (node->key == key) { 140 | return node; 141 | } 142 | pos = end->prev; 143 | pos--; 144 | end--; 145 | } 146 | 147 | return NULL; 148 | } 149 | 150 | static struct skipnode * 151 | skiplist_insert(struct skiplist *list, int key, int value) 152 | { 153 | int level = random_level(); 154 | if (level > list->level) { 155 | list->level = level; 156 | } 157 | 158 | struct skipnode *node = skipnode_new(level, key, value); 159 | if (node != NULL) { 160 | int i = list->level - 1; 161 | struct sk_link *pos = &list->head[i]; 162 | struct sk_link *end = &list->head[i]; 163 | 164 | for (; i >= 0; i--) { 165 | pos = pos->next; 166 | skiplist_foreach(pos, end) { 167 | struct skipnode *nd = list_entry(pos, struct skipnode, link[i]); 168 | if (nd->key >= key) { 169 | end = &nd->link[i]; 170 | break; 171 | } 172 | } 173 | pos = end->prev; 174 | if (i < level) { 175 | __list_add(&node->link[i], pos, end); 176 | } 177 | pos--; 178 | end--; 179 | } 180 | 181 | list->count++; 182 | } 183 | return node; 184 | } 185 | 186 | static void __remove(struct skiplist *list, struct skipnode *node, int level) 187 | { 188 | int i; 189 | for (i = 0; i < level; i++) { 190 | list_del(&node->link[i]); 191 | if (list_empty(&list->head[i])) { 192 | list->level--; 193 | } 194 | } 195 | skipnode_delete(node); 196 | list->count--; 197 | } 198 | 199 | static void skiplist_remove(struct skiplist *list, int key) 200 | { 201 | struct sk_link *n; 202 | struct skipnode *node; 203 | int i = list->level - 1; 204 | struct sk_link *pos = &list->head[i]; 205 | struct sk_link *end = &list->head[i]; 206 | 207 | for (; i >= 0; i--) { 208 | pos = pos->next; 209 | skiplist_foreach_safe(pos, n, end) { 210 | node = list_entry(pos, struct skipnode, link[i]); 211 | if (node->key > key) { 212 | end = &node->link[i]; 213 | break; 214 | } else if (node->key == key) { 215 | /* we allow nodes with same key. */ 216 | __remove(list, node, i + 1); 217 | } 218 | } 219 | pos = end->prev; 220 | pos--; 221 | end--; 222 | } 223 | } 224 | 225 | static void skiplist_dump(struct skiplist *list) 226 | { 227 | struct skipnode *node; 228 | int i = list->level - 1; 229 | struct sk_link *pos = &list->head[i]; 230 | struct sk_link *end = &list->head[i]; 231 | 232 | printf("\nTotal %d nodes: \n", list->count); 233 | for (; i >= 0; i--) { 234 | pos = pos->next; 235 | printf("level %d:\n", i + 1); 236 | skiplist_foreach(pos, end) { 237 | node = list_entry(pos, struct skipnode, link[i]); 238 | printf("key:0x%08x value:0x%08x\n", node->key, node->value); 239 | } 240 | pos = &list->head[i]; 241 | pos--; 242 | end--; 243 | } 244 | } 245 | 246 | #endif /* _SKIPLIST_H */ 247 | -------------------------------------------------------------------------------- /skiplist_with_rank.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015, Leo Ma 3 | */ 4 | 5 | #ifndef _SKIPLIST_H 6 | #define _SKIPLIST_H 7 | 8 | struct sk_link { 9 | struct sk_link *next, *prev; 10 | int span; 11 | }; 12 | 13 | static inline void list_init(struct sk_link *link) 14 | { 15 | link->prev = link; 16 | link->next = link; 17 | } 18 | 19 | static inline void 20 | __list_add(struct sk_link *link, struct sk_link *prev, struct sk_link *next) 21 | { 22 | link->next = next; 23 | link->prev = prev; 24 | next->prev = link; 25 | prev->next = link; 26 | } 27 | 28 | static inline void __list_del(struct sk_link *prev, struct sk_link *next) 29 | { 30 | prev->next = next; 31 | next->prev = prev; 32 | } 33 | 34 | static inline void list_add(struct sk_link *link, struct sk_link *next) 35 | { 36 | __list_add(link, next->prev, next); 37 | } 38 | 39 | static inline void list_del(struct sk_link *link) 40 | { 41 | __list_del(link->prev, link->next); 42 | list_init(link); 43 | } 44 | 45 | static inline int list_empty(struct sk_link *link) 46 | { 47 | return link->next == link; 48 | } 49 | 50 | #define list_entry(ptr, type, member) \ 51 | ((type *)((char *)(ptr) - (size_t)(&((type *)0)->member))) 52 | 53 | #define skiplist_foreach_forward(pos, end) \ 54 | for (; pos != end; pos = (pos)->next) 55 | 56 | #define skiplist_foreach_forward_safe(pos, n, end) \ 57 | for (n = (pos)->next; pos != end; pos = n, n = (pos)->next) 58 | 59 | #define skiplist_foreach_backward(pos, end) \ 60 | for (; pos != end; pos = (pos)->prev) 61 | 62 | #define skiplist_foreach_backward_safe(pos, n, end) \ 63 | for (n = (pos)->prev; pos != end; pos = n, n = (pos)->prev) 64 | 65 | #define MAX_LEVEL 32 /* Should be enough for 2^32 elements */ 66 | 67 | struct range_spec { 68 | int min, max; 69 | int minex, maxex; 70 | }; 71 | 72 | struct skiplist { 73 | int level; 74 | int count; 75 | struct sk_link head[MAX_LEVEL]; 76 | }; 77 | 78 | struct skipnode { 79 | int key; 80 | int value; 81 | struct sk_link link[0]; 82 | }; 83 | 84 | static struct skipnode *skipnode_new(int level, int key, int value) 85 | { 86 | struct skipnode *node; 87 | node = malloc(sizeof(*node) + level * sizeof(struct sk_link)); 88 | if (node != NULL) { 89 | node->key = key; 90 | node->value = value; 91 | } 92 | return node; 93 | } 94 | 95 | static void skipnode_delete(struct skipnode *node) 96 | { 97 | free(node); 98 | } 99 | 100 | static struct skiplist *skiplist_new(void) 101 | { 102 | int i; 103 | struct skiplist *list = malloc(sizeof(*list)); 104 | if (list != NULL) { 105 | list->level = 1; 106 | list->count = 0; 107 | for (i = 0; i < sizeof(list->head) / sizeof(list->head[0]); i++) { 108 | list_init(&list->head[i]); 109 | list->head[i].span = 0; 110 | } 111 | } 112 | return list; 113 | } 114 | 115 | static void skiplist_delete(struct skiplist *list) 116 | { 117 | struct sk_link *n; 118 | struct skipnode *node; 119 | struct sk_link *pos = list->head[0].next; 120 | skiplist_foreach_forward_safe(pos, n, &list->head[0]) { 121 | node = list_entry(pos, struct skipnode, link[0]); 122 | skipnode_delete(node); 123 | } 124 | free(list); 125 | } 126 | 127 | static int random_level(void) 128 | { 129 | int level = 1; 130 | const double p = 0.25; 131 | while ((random() & 0xffff) < 0xffff * p) { 132 | level++; 133 | } 134 | return level > MAX_LEVEL ? MAX_LEVEL : level; 135 | } 136 | 137 | static struct skipnode * 138 | skiplist_insert(struct skiplist *list, int key, int value) 139 | { 140 | struct skipnode *nd; 141 | int rank[MAX_LEVEL]; 142 | struct sk_link *update[MAX_LEVEL]; 143 | int level = random_level(); 144 | if (level > list->level) { 145 | list->level = level; 146 | } 147 | 148 | struct skipnode *node = skipnode_new(level, key, value); 149 | if (node != NULL) { 150 | int i = list->level - 1; 151 | struct sk_link *pos = &list->head[i]; 152 | struct sk_link *end = &list->head[i]; 153 | 154 | for (; i >= 0; i--) { 155 | rank[i] = i == list->level - 1 ? 0 : rank[i + 1]; 156 | pos = pos->next; 157 | skiplist_foreach_forward(pos, end) { 158 | nd = list_entry(pos, struct skipnode, link[i]); 159 | if (nd->key >= key) { 160 | end = &nd->link[i]; 161 | break; 162 | } 163 | rank[i] += nd->link[i].span; 164 | } 165 | 166 | update[i] = end; 167 | pos = end->prev; 168 | pos--; 169 | end--; 170 | } 171 | 172 | for (i = 0; i < list->level; i++) { 173 | if (i < level) { 174 | list_add(&node->link[i], update[i]); 175 | node->link[i].span = rank[0] - rank[i] + 1; 176 | update[i]->span -= node->link[i].span - 1; 177 | } else { 178 | update[i]->span++; 179 | } 180 | } 181 | 182 | list->count++; 183 | } 184 | 185 | return node; 186 | } 187 | 188 | static void 189 | __remove(struct skiplist *list, struct skipnode *node, int level, struct sk_link **update) 190 | { 191 | int i; 192 | int remain_level = list->level; 193 | for (i = 0; i < list->level; i++) { 194 | if (i < level) { 195 | list_del(&node->link[i]); 196 | update[i] = node->link[i].next; 197 | update[i]->span += node->link[i].span - 1; 198 | } else { 199 | update[i]->span--; 200 | } 201 | 202 | if (list_empty(&list->head[i])) { 203 | if (remain_level == list->level) { 204 | remain_level = i + 1; 205 | } 206 | } 207 | } 208 | 209 | skipnode_delete(node); 210 | list->count--; 211 | list->level = remain_level; 212 | } 213 | 214 | static void skiplist_remove(struct skiplist *list, int key) 215 | { 216 | struct skipnode *node; 217 | int i = list->level - 1; 218 | struct sk_link *pos = &list->head[i]; 219 | struct sk_link *end = &list->head[i]; 220 | struct sk_link *n, *update[MAX_LEVEL]; 221 | 222 | for (; i >= 0; i--) { 223 | pos = pos->next; 224 | skiplist_foreach_forward_safe(pos, n, end) { 225 | node = list_entry(pos, struct skipnode, link[i]); 226 | if (node->key > key) { 227 | end = &node->link[i]; 228 | break; 229 | } else if (node->key == key) { 230 | __remove(list, node, i + 1, update); 231 | return; 232 | } 233 | } 234 | update[i] = end; 235 | pos = end->prev; 236 | pos--; 237 | end--; 238 | } 239 | } 240 | 241 | static int key_gte_min(int key, struct range_spec *range) 242 | { 243 | return range->maxex ? (key > range->max) : (key >= range->max); 244 | } 245 | 246 | static int key_lte_max(int key, struct range_spec *range) 247 | { 248 | return range->minex ? (key < range->min) : (key <= range->min); 249 | } 250 | 251 | /* Returns if there is node key in range */ 252 | static int key_in_range(struct skiplist *list, struct range_spec *range) 253 | { 254 | if (range->min > range->max || 255 | (range->min == range->max && (range->minex || range->maxex))) { 256 | return 0; 257 | } 258 | 259 | if (list_empty(&list->head[0])) { 260 | return 0; 261 | } 262 | 263 | struct sk_link *link = list->head[0].next; 264 | struct skipnode *node = list_entry(link, struct skipnode, link[0]); 265 | if (!key_lte_max(node->key, range)) { 266 | return 0; 267 | } 268 | 269 | link = list->head[0].prev; 270 | node = list_entry(link, struct skipnode, link[0]); 271 | if (!key_gte_min(node->key, range)) { 272 | return 0; 273 | } 274 | 275 | return 1; 276 | } 277 | 278 | 279 | /* search the first node key that is contained in the specified range 280 | * where min and max are inclusive. */ 281 | static struct skipnode * 282 | first_in_range(struct skiplist *list, struct range_spec *range) 283 | { 284 | struct skipnode *node; 285 | int i = list->level - 1; 286 | struct sk_link *pos = &list->head[i]; 287 | struct sk_link *end = &list->head[i]; 288 | 289 | if (!key_in_range(list, range)) { 290 | return NULL; 291 | } 292 | 293 | for (; i >= 0; i--) { 294 | pos = pos->next; 295 | skiplist_foreach_forward(pos, end) { 296 | node = list_entry(pos, struct skipnode, link[i]); 297 | if (key_gte_min(node->key, range)) { 298 | pos = node->link[i].prev; 299 | end = node->link[i].next; 300 | goto CONTINUE; 301 | } 302 | } 303 | pos = end->prev; 304 | CONTINUE: 305 | pos--; 306 | end--; 307 | } 308 | 309 | return node; 310 | } 311 | 312 | /* search the last node key that is contained in the specified range 313 | * where min and max are inclusive. */ 314 | static struct skipnode * 315 | last_in_range(struct skiplist *list, struct range_spec *range) 316 | { 317 | int i = list->level - 1; 318 | struct sk_link *pos = &list->head[i]; 319 | struct sk_link *end = &list->head[i]; 320 | struct skipnode *node = NULL; 321 | 322 | if (!key_in_range(list, range)) { 323 | return NULL; 324 | } 325 | 326 | for (; i >= 0; i--) { 327 | pos = pos->prev; 328 | skiplist_foreach_backward(pos, end) { 329 | node = list_entry(pos, struct skipnode, link[i]); 330 | if (key_lte_max(node->key, range)) { 331 | pos = node->link[i].next; 332 | end = node->link[i].prev; 333 | goto CONTINUE; 334 | } 335 | } 336 | pos = end->next; 337 | CONTINUE: 338 | pos--; 339 | end--; 340 | } 341 | 342 | return node; 343 | } 344 | 345 | /* remove all the nodes with key in range 346 | * where min and max are inclusive. */ 347 | static int remove_in_range(struct skiplist *list, struct range_spec *range) 348 | { 349 | int removed = 0; 350 | struct skipnode *node; 351 | int i = list->level - 1; 352 | struct sk_link *pos = &list->head[i]; 353 | struct sk_link *end = &list->head[i]; 354 | struct sk_link *n, *update[MAX_LEVEL]; 355 | 356 | if (key_in_range(list, range)) { 357 | return 0; 358 | } 359 | 360 | for (; i >= 0; i--) { 361 | pos = pos->next; 362 | skiplist_foreach_forward_safe(pos, n, end) { 363 | node = list_entry(pos, struct skipnode, link[i]); 364 | if (!key_lte_max(node->key, range)) { 365 | end = &node->link[i]; 366 | break; 367 | } else if (key_gte_min(node->key, range)) { 368 | /* we allow nodes with same key. */ 369 | __remove(list, node, i + 1, update); 370 | removed++; 371 | } 372 | } 373 | update[i] = end; 374 | pos = end->prev; 375 | pos--; 376 | end--; 377 | } 378 | 379 | return removed; 380 | } 381 | 382 | /* remove all the nodes with key rank in range 383 | * where start and stop are inclusive. */ 384 | static int remove_in_rank(struct skiplist *list, int start, int stop) 385 | { 386 | struct skipnode *node; 387 | int i = list->level - 1; 388 | struct sk_link *pos = &list->head[i]; 389 | struct sk_link *end = &list->head[i]; 390 | int removed = 0, traversed = 0; 391 | struct sk_link *n, *update[MAX_LEVEL] = {0}; 392 | 393 | if (start <= 0 || stop <= 0 || start > list->count) { 394 | return 0; 395 | } 396 | 397 | for (; i >= 0; i--) { 398 | pos = pos->next; 399 | skiplist_foreach_forward_safe(pos, n, end) { 400 | node = list_entry(pos, struct skipnode, link[i]); 401 | if (traversed + node->link[i].span > stop) { 402 | end = &node->link[i]; 403 | break; 404 | } else if (traversed + node->link[i].span >= start) { 405 | /* we allow nodes with same key. */ 406 | __remove(list, node, i + 1, update); 407 | removed++; 408 | } 409 | traversed += node->link[i].span; 410 | } 411 | update[i] = end; 412 | pos = end->prev; 413 | pos--; 414 | end--; 415 | } 416 | 417 | return removed; 418 | } 419 | 420 | /* Get the node key rank */ 421 | static int skiplist_key_rank(struct skiplist *list, int key) 422 | { 423 | int rank = 0; 424 | int i = list->level - 1; 425 | struct sk_link *pos = &list->head[i]; 426 | struct sk_link *end = &list->head[i]; 427 | struct skipnode *node; 428 | 429 | for (; i >= 0; i--) { 430 | pos = pos->next; 431 | skiplist_foreach_forward(pos, end) { 432 | node = list_entry(pos, struct skipnode, link[i]); 433 | if (node->key >= key) { 434 | end = &node->link[i]; 435 | break; 436 | } 437 | rank += node->link[i].span; 438 | } 439 | if (node->key == key) { 440 | return rank + node->link[i].span; 441 | } 442 | pos = end->prev; 443 | pos--; 444 | end--; 445 | } 446 | 447 | return 0; 448 | } 449 | 450 | /* search the node with specified key. */ 451 | static struct skipnode *skiplist_search_by_key(struct skiplist *list, int key) 452 | { 453 | int i = list->level - 1; 454 | struct sk_link *pos = &list->head[i]; 455 | struct sk_link *end = &list->head[i]; 456 | struct skipnode *node; 457 | 458 | for (; i >= 0; i--) { 459 | pos = pos->next; 460 | skiplist_foreach_forward(pos, end) { 461 | node = list_entry(pos, struct skipnode, link[i]); 462 | if (node->key >= key) { 463 | end = &node->link[i]; 464 | break; 465 | } 466 | } 467 | if (node->key == key) { 468 | return node; 469 | } 470 | pos = end->prev; 471 | pos--; 472 | end--; 473 | } 474 | 475 | return NULL; 476 | } 477 | 478 | /* search the node with specified key rank. */ 479 | static struct skipnode *skiplist_search_by_rank(struct skiplist *list, int rank) 480 | { 481 | if (rank == 0 || rank > list->count) { 482 | return NULL; 483 | } 484 | 485 | int i = list->level - 1; 486 | int traversed = 0; 487 | struct sk_link *pos = &list->head[i]; 488 | struct sk_link *end = &list->head[i]; 489 | struct skipnode *node; 490 | 491 | for (; i >= 0; i--) { 492 | pos = pos->next; 493 | skiplist_foreach_forward(pos, end) { 494 | node = list_entry(pos, struct skipnode, link[i]); 495 | if (traversed + node->link[i].span > rank) { 496 | end = &node->link[i]; 497 | break; 498 | } 499 | traversed += node->link[i].span; 500 | if (rank == traversed) { 501 | return node; 502 | } 503 | } 504 | pos = end->prev; 505 | pos--; 506 | end--; 507 | } 508 | 509 | return NULL; 510 | } 511 | 512 | static void skiplist_dump(struct skiplist *list) 513 | { 514 | int traversed = 0; 515 | struct skipnode *node; 516 | int i = list->level - 1; 517 | struct sk_link *pos = &list->head[i]; 518 | struct sk_link *end = &list->head[i]; 519 | 520 | printf("\nTotal %d nodes: \n", list->count); 521 | for (; i >= 0; i--) { 522 | traversed = 0; 523 | pos = pos->next; 524 | printf("level %d:\n", i + 1); 525 | skiplist_foreach_forward(pos, end) { 526 | node = list_entry(pos, struct skipnode, link[i]); 527 | traversed += node->link[i].span; 528 | printf("key:0x%08x value:0x%08x rank:%u\n", 529 | node->key, node->value, traversed); 530 | } 531 | pos = &list->head[i]; 532 | pos--; 533 | end--; 534 | } 535 | } 536 | 537 | #endif /* _SKIPLIST_H */ 538 | --------------------------------------------------------------------------------