101static inline skip_node* node_new(
void* key,
unsigned link_count);
108static inline unsigned rand_link_count(
skiplist* list);
121 if (!(list->
head = node_new(NULL, max_link))) {
143 dct->
_vtable = &skiplist_vtable;
161 ASSERT(nlinks < list->max_link);
164 for (
unsigned k = list->
top_link+1; k <= nlinks; k++) {
166 update[k] = list->
head;
171 x->
prev = (update[0] == list->
head) ? NULL : update[0];
172 if (update[0]->link[0])
174 for (
unsigned k = 0; k < nlinks; k++) {
175 ASSERT(update[k]->link_count > k);
177 update[k]->
link[k] = x;
187 for (
unsigned k = list->
top_link+1; k-->0; ) {
195 while (k > 0 && x->
link[k - 1] == y)
205 x = node_new(key, rand_link_count(list));
208 node_insert(list, x, update);
213node_search(
skiplist* list,
const void* key)
216 for (
unsigned k = list->
top_link+1; k-->0;) {
223 while (k > 0 && x->
link[k - 1] == y)
235node_search_le(
skiplist* list,
const void* key)
238 for (
unsigned k = list->
top_link+1; k-->0;) {
245 while (k > 0 && x->
link[k - 1] == y)
253 return x == list->
head ? NULL : x;
257node_search_lt(
skiplist* list,
const void* key)
260 for (
unsigned k = list->
top_link+1; k-->0;) {
267 while (k > 0 && x->
link[k - 1] == y)
275 return x == list->
head ? NULL : x;
279node_search_ge(
skiplist* list,
const void* key)
283 for (
unsigned k = list->
top_link+1; k-->0;) {
291 while (k > 0 && x->
link[k - 1] == y)
303node_search_gt(
skiplist* list,
const void* key)
307 for (
unsigned k = list->
top_link+1; k-->0;) {
315 while (k > 0 && x->
link[k - 1] == y)
330 return x ? &x->
datum : NULL;
336 skip_node* x = node_search_le(list, key);
337 return x ? &x->
datum : NULL;
343 skip_node* x = node_search_lt(list, key);
344 return x ? &x->
datum : NULL;
350 skip_node* x = node_search_ge(list, key);
351 return x ? &x->
datum : NULL;
357 skip_node* x = node_search_gt(list, key);
358 return x ? &x->
datum : NULL;
367 for (
unsigned k = list->
top_link+1; k-->0;) {
377 while (k > 0 && x->
link[k - 1] == y)
389 for (
unsigned k = 0; k <= list->
top_link; k++) {
390 ASSERT(update[k] != NULL);
391 ASSERT(update[k]->link_count > k);
392 if (update[k]->link[k] != x)
break;
413 if (delete_func) delete_func(node->
key, node->
datum);
418 const size_t count = list->
count;
433 if (!visit(node->key, node->datum, user_data))
break;
447 if (list->
count == 0) {
453 for (
unsigned i = 0; i < list->
top_link; ++i) {
456 for (
unsigned i = list->
top_link; i < list->max_link; ++i) {
459 unsigned observed_top_link = 0;
464 if (observed_top_link < node->link_count)
470 for (
unsigned k = 0; k < node->
link_count; k++) {
477 node = node->
link[0];
486 for (
size_t i = 0; i < ncounts; ++i)
489 size_t max_num_links = 0;
491 if (max_num_links < node->link_count)
492 max_num_links = node->link_count;
493 if (ncounts > node->link_count)
494 counts[node->link_count]++;
496 return max_num_links;
519 itor->
_vtable = &skiplist_itor_vtable;
533 return itor->
node != NULL;
547 return itor->
node != NULL;
555 return itor->
node != NULL;
564 return itor->
node != NULL;
573 return itor->
node != NULL;
602 return (itor->
node = node_search(itor->
list, key)) != NULL;
608 return (itor->
node = node_search_le(itor->
list, key)) != NULL;
614 return (itor->
node = node_search_lt(itor->
list, key)) != NULL;
620 return (itor->
node = node_search_ge(itor->
list, key)) != NULL;
626 return (itor->
node = node_search_gt(itor->
list, key)) != NULL;
646 return !itor2->
node ? 0 : -1;
665node_new(
void* key,
unsigned link_count)
670 sizeof(node->
link[0]) * link_count);
676 memset(node->
link, 0,
sizeof(node->
link[0]) * link_count);
681static inline unsigned
684 unsigned count = (unsigned) __builtin_ctz(dict_rand()) / 2 + 1;
dict_remove_result(* dict_remove_func)(void *obj, const void *key)
int(* dict_compare_func)(const void *, const void *)
bool(* dict_select_func)(void *obj, size_t n, const void **key, void **datum)
void(* dict_invalidate_func)(void *itor)
size_t(* dict_traverse_func)(void *obj, dict_visit_func visit, void *user_data)
dict_insert_result(* dict_insert_func)(void *obj, void *key)
void(* dict_delete_func)(void *, void *)
int(* dict_icompare_func)(void *itor1, void *itor2)
bool(* dict_nextn_func)(void *itor, size_t count)
bool(* dict_valid_func)(const void *itor)
size_t(* dict_count_func)(const void *obj)
bool(* dict_first_func)(void *itor)
bool(* dict_next_func)(void *itor)
void *(* dict_key_func)(void *itor)
size_t(* dict_dfree_func)(void *obj, dict_delete_func delete_func)
void **(* dict_datum_func)(void *itor)
bool(* dict_prevn_func)(void *itor, size_t count)
void **(* dict_search_func)(void *obj, const void *key)
bool(* dict_isearch_func)(void *itor, const void *key)
bool(* dict_iremove_func)(void *itor)
bool(* dict_prev_func)(void *itor)
dict_itor *(* dict_inew_func)(void *obj)
bool(* dict_last_func)(void *itor)
bool(* dict_verify_func)(const void *obj)
bool(* dict_visit_func)(const void *, void *, void *)
size_t(* dict_clear_func)(void *obj, dict_delete_func delete_func)
void(* dict_ifree_func)(void *itor)
bool skiplist_itor_search_le(skiplist_itor *itor, const void *key)
size_t skiplist_traverse(skiplist *list, dict_visit_func visit, void *user_data)
skiplist * skiplist_new(dict_compare_func cmp_func, unsigned max_link)
bool skiplist_itor_search_gt(skiplist_itor *itor, const void *key)
bool skiplist_itor_remove(skiplist_itor *itor)
void ** skiplist_search_le(skiplist *list, const void *key)
void ** skiplist_search(skiplist *list, const void *key)
bool skiplist_itor_search(skiplist_itor *itor, const void *key)
bool skiplist_verify(const skiplist *list)
bool skiplist_itor_first(skiplist_itor *itor)
bool skiplist_itor_next(skiplist_itor *itor)
bool skiplist_itor_prevn(skiplist_itor *itor, size_t count)
size_t skiplist_free(skiplist *list, dict_delete_func delete_func)
void skiplist_itor_invalidate(skiplist_itor *itor)
const void * skiplist_itor_key(const skiplist_itor *itor)
void ** skiplist_search_gt(skiplist *list, const void *key)
bool skiplist_itor_search_lt(skiplist_itor *itor, const void *key)
bool skiplist_itor_valid(const skiplist_itor *itor)
dict * skiplist_dict_new(dict_compare_func cmp_func, unsigned max_link)
void ** skiplist_search_ge(skiplist *list, const void *key)
bool skiplist_itor_search_ge(skiplist_itor *itor, const void *key)
int skiplist_itor_compare(const skiplist_itor *itor1, const skiplist_itor *itor2)
void ** skiplist_itor_datum(skiplist_itor *itor)
dict_itor * skiplist_dict_itor_new(skiplist *list)
void ** skiplist_search_lt(skiplist *list, const void *key)
void skiplist_itor_free(skiplist_itor *itor)
dict_insert_result skiplist_insert(skiplist *list, void *key)
bool skiplist_itor_nextn(skiplist_itor *itor, size_t count)
skiplist_itor * skiplist_itor_new(skiplist *list)
size_t skiplist_clear(skiplist *list, dict_delete_func delete_func)
size_t skiplist_count(const skiplist *list)
dict_remove_result skiplist_remove(skiplist *list, const void *key)
bool skiplist_itor_last(skiplist_itor *itor)
size_t skiplist_link_count_histogram(const skiplist *list, size_t counts[], size_t ncounts)
bool skiplist_itor_prev(skiplist_itor *itor)
const itor_vtable * _vtable
const dict_vtable * _vtable
dict_compare_func cmp_func