-Definition at line 445 of file skiplist.c.
+Definition at line 446 of file skiplist.c.
diff --git a/html/skiplist_8h_source.html b/html/skiplist_8h_source.html
index 3f199d6..780e28d 100644
--- a/html/skiplist_8h_source.html
+++ b/html/skiplist_8h_source.html
@@ -178,41 +178,41 @@
void(* dict_delete_func)(void *, void *)
bool(* dict_visit_func)(const void *, void *, void *)
-void skiplist_itor_free(skiplist_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)
+void skiplist_itor_free(skiplist_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)
-int skiplist_itor_compare(const skiplist_itor *it1, const skiplist_itor *it2)
-bool skiplist_itor_next(skiplist_itor *itor)
-bool skiplist_itor_prevn(skiplist_itor *itor, size_t count)
+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)
+int skiplist_itor_compare(const skiplist_itor *it1, const skiplist_itor *it2)
+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)
+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)
-void ** skiplist_itor_datum(skiplist_itor *itor)
-dict_itor * skiplist_dict_itor_new(skiplist *list)
-void ** skiplist_search_lt(skiplist *list, const void *key)
-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)
+void ** skiplist_search_ge(skiplist *list, const void *key)
+bool skiplist_itor_search_ge(skiplist_itor *itor, const void *key)
+void ** skiplist_itor_datum(skiplist_itor *itor)
+dict_itor * skiplist_dict_itor_new(skiplist *list)
+void ** skiplist_search_lt(skiplist *list, const void *key)
+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)
diff --git a/xml/hb__tree_8c.xml b/xml/hb__tree_8c.xml
index 8e2c8f0..40dd1a5 100644
--- a/xml/hb__tree_8c.xml
+++ b/xml/hb__tree_8c.xml
@@ -278,7 +278,7 @@
-
+
[hb_node] *
@@ -295,7 +295,7 @@
-
+
[hb_node] *
@@ -312,7 +312,7 @@
-
+
bool
@@ -345,7 +345,7 @@
-
+
[hb_tree] *
@@ -694,7 +694,7 @@
-
+
[dict_remove_result]
@@ -715,7 +715,7 @@
-
+
hb_node::datum
hb_node::key
tree_search_node
@@ -743,7 +743,7 @@
-
+
tree_traverse
@@ -773,7 +773,7 @@
-
+
tree::count
hb_node::datum
hb_node::key
@@ -796,7 +796,7 @@
-
+
tree_count
@@ -814,7 +814,7 @@
-
+
tree_min_path_length
@@ -832,7 +832,7 @@
-
+
tree_max_path_length
@@ -850,7 +850,7 @@
-
+
tree_total_path_length
@@ -868,7 +868,7 @@
-
+
tree::count
tree::root
VERIFY
@@ -888,7 +888,7 @@
-
+
MALLOC
hb_itor::node
hb_itor::tree
@@ -908,11 +908,11 @@
-
+
dict_itor::_itor
dict_itor::_vtable
FREE
- hb_itor_new
+ hb_itor_new
MALLOC
@@ -930,7 +930,7 @@
-
+
tree_iterator_free
@@ -948,7 +948,7 @@
-
+
tree_iterator_valid
@@ -966,7 +966,7 @@
-
+
tree_iterator_invalidate
@@ -984,7 +984,7 @@
-
+
hb_itor::node
@@ -1002,7 +1002,7 @@
-
+
hb_itor::node
@@ -1024,7 +1024,7 @@
-
+
hb_itor::node
@@ -1046,7 +1046,7 @@
-
+
hb_itor::node
@@ -1064,7 +1064,7 @@
-
+
tree_iterator_first
@@ -1082,7 +1082,7 @@
-
+
tree_iterator_last
@@ -1104,7 +1104,7 @@
-
+
tree_iterator_search_ge
@@ -1126,7 +1126,7 @@
-
+
tree_iterator_search_le
@@ -1148,7 +1148,7 @@
-
+
tree_iterator_search_lt
@@ -1170,7 +1170,7 @@
-
+
tree_iterator_search_ge
@@ -1192,7 +1192,7 @@
-
+
tree_iterator_search_gt
@@ -1214,7 +1214,7 @@
-
+
tree_iterator_compare
@@ -1232,7 +1232,7 @@
-
+
tree_iterator_key
@@ -1250,7 +1250,7 @@
-
+
tree_iterator_datum
@@ -1268,7 +1268,7 @@
-
+
hb_itor::node
hb_itor::tree
@@ -1681,267 +1681,266 @@
rotate_rl([tree],p);
}else{
rotations+=1;
-if(rotate_l([tree],p))
-break;
-}
-node=[PARENT](p);
-}elseif([BAL_NEG](p)){
-p->[bal]&=~BAL_MASK;
-node=p;
-}else{
-[ASSERT]((p->[bal]&[BAL_MASK])==0);
-p->[bal]|=1;
-break;
-}
-}else{
-[ASSERT](p->[rlink]==node);
-if([BAL_NEG](p)){
-if([BAL_POS](p->[llink])){
-rotations+=2;
-rotate_lr([tree],p);
-}else{
-rotations+=1;
-if(rotate_r([tree],p))
-break;
-}
-node=[PARENT](p);
-}elseif([BAL_POS](p)){
-p->[bal]&=~BAL_MASK;
-node=p;
-}else{
-[ASSERT]((p->[bal]&[BAL_MASK])==0);
-p->[bal]|=2;
-break;
-}
-}
-
-if(!(p=[PARENT](node)))
-break;
-if(p->[llink]==node){
-left=true;
-}else{
-[ASSERT](p->[rlink]==node);
-left=false;
-}
-}
-[tree]->[rotation_count]+=rotations;
-}
-
-[dict_remove_result]
-[hb_tree_remove]([hb_tree]*[tree],constvoid*key)
-{
-[hb_node]*node=[tree_search_node]([tree],key);
-if(!node)
-return([dict_remove_result]){NULL,NULL,false};
-const[dict_remove_result]result={node->[key],node->[datum],true};
-remove_node([tree],node);
-returnresult;
-}
-
-size_t
-[hb_tree_traverse]([hb_tree]*[tree],[dict_visit_func]visit,void*user_data)
-{
-return[tree_traverse]([tree],visit,user_data);
-}
-
-bool
-[hb_tree_select]([hb_tree]*[tree],size_tn,constvoid**key,void**datum)
-{
-if(n>=[tree]->[count]){
-if(key)
-*key=NULL;
-if(datum)
-*datum=NULL;
-returnfalse;
-}
-[hb_node]*node;
-if(n>=[tree]->[count]/2){
-node=[tree_node_max]([tree]->[root]);
-n=[tree]->[count]-1-n;
-while(n--)
-node=node_prev(node);
-}else{
-node=[tree_node_min]([tree]->[root]);
-while(n--)
-node=node_next(node);
-}
-if(key)
-*key=node->[key];
-if(datum)
-*datum=node->[datum];
-returntrue;
-}
-
-size_t[hb_tree_count](const[hb_tree]*[tree]){return[tree_count]([tree]);}
-size_t[hb_tree_min_path_length](const[hb_tree]*[tree]){return[tree_min_path_length]([tree]);}
-size_t[hb_tree_max_path_length](const[hb_tree]*[tree]){return[tree_max_path_length]([tree]);}
-size_t[hb_tree_total_path_length](const[hb_tree]*[tree]){return[tree_total_path_length]([tree]);}
-
-static[hb_node]*
-node_new(void*key)
-{
-[hb_node]*node=[MALLOC](sizeof(*node));
-if(node){
-[ASSERT]((((intptr_t)node)&3)==0);
-node->[key]=key;
-node->[datum]=NULL;
-node->[bal]=0;
-node->[llink]=NULL;
-node->[rlink]=NULL;
-}
-returnnode;
-}
-
-static[hb_node]*
-node_prev([hb_node]*node)
-{
-if(node->[llink])
-return[tree_node_max](node->[llink]);
-[hb_node]*parent=[PARENT](node);
-while(parent&&parent->[llink]==node){
-node=parent;
-parent=[PARENT](parent);
-}
-returnparent;
-}
-
-static[hb_node]*
-node_next([hb_node]*node)
-{
-if(node->[rlink])
-return[tree_node_min](node->[rlink]);
-[hb_node]*parent=[PARENT](node);
-while(parent&&parent->[rlink]==node){
-node=parent;
-parent=[PARENT](parent);
-}
-returnparent;
-}
-
-staticbool
-node_verify(const[hb_tree]*[tree],const[hb_node]*parent,const[hb_node]*node,
-unsigned*height,size_t*count)
-{
-if(!parent){
-[VERIFY]([tree]->[root]==node);
-}else{
-if(parent->[llink]==node){
-if(node)
-[VERIFY]([tree]->[cmp_func](parent->[key],node->[key])>0);
-}else{
-[ASSERT](parent->[rlink]==node);
-if(node)
-[VERIFY]([tree]->[cmp_func](parent->[key],node->[key])<0);
-}
-}
-if(node){
-intbal=node->[bal]&[BAL_MASK];
-[VERIFY](bal>=0);
-[VERIFY](bal<=2);
-if(bal==2){
-[VERIFY](node->[llink]!=NULL);
-bal=-1;
-}elseif(bal==1){
-[VERIFY](node->[rlink]!=NULL);
-}
-[VERIFY]([PARENT](node)==parent);
-unsignedlheight,rheight;
-if(!node_verify([tree],node,node->[llink],&lheight,count)||
-!node_verify([tree],node,node->[rlink],&rheight,count))
-returnfalse;
-[VERIFY](bal==(int)rheight-(int)lheight);
-if(height)
-*height=[MAX](lheight,rheight)+1;
-*count+=1;
-}else{
-if(height)
-*height=0;
-}
-returntrue;
-}
-
-bool
-[hb_tree_verify](const[hb_tree]*[tree])
-{
-size_tcount=0;
-boolverified=node_verify([tree],NULL,[tree]->[root],NULL,&count);
-[VERIFY]([tree]->[count]==count);
-returnverified;
-}
-
-[hb_itor]*
-[hb_itor_new]([hb_tree]*[tree])
-{
-[hb_itor]*itor=[MALLOC](sizeof(*itor));
-if(itor){
-itor->[tree]=[tree];
-itor->[node]=NULL;
-}
-returnitor;
-}
-
-[dict_itor]*
-[hb_dict_itor_new]([hb_tree]*[tree])
-{
-[dict_itor]*itor=[MALLOC](sizeof(*itor));
-if(itor){
-if(!(itor->[_itor]=[hb_itor_new]([tree]))){
-[FREE](itor);
-returnNULL;
-}
-itor->[_vtable]=&hb_tree_itor_vtable;
-}
-returnitor;
-}
-
-void[hb_itor_free]([hb_itor]*itor){[tree_iterator_free](itor);}
-bool[hb_itor_valid](const[hb_itor]*itor){return[tree_iterator_valid](itor);}
-void[hb_itor_invalidate]([hb_itor]*itor){[tree_iterator_invalidate](itor);}
-
-bool[hb_itor_next]([hb_itor]*itor){
-if(itor->[node])
-itor->[node]=node_next(itor->[node]);
-returnitor->[node]!=NULL;
-}
-
-bool[hb_itor_prev]([hb_itor]*itor){
-if(itor->[node])
-itor->[node]=node_prev(itor->[node]);
-returnitor->[node]!=NULL;
-}
-
-bool[hb_itor_nextn]([hb_itor]*itor,size_tcount){
-while(itor->[node]&&count--)
-itor->[node]=node_next(itor->[node]);
-returnitor->[node]!=NULL;
-}
-
-bool[hb_itor_prevn]([hb_itor]*itor,size_tcount){
-while(itor->[node]&&count--)
-itor->[node]=node_prev(itor->[node]);
-returnitor->[node]!=NULL;
-}
-
-bool[hb_itor_first]([hb_itor]*itor){return[tree_iterator_first](itor);}
-bool[hb_itor_last]([hb_itor]*itor){return[tree_iterator_last](itor);}
-bool[hb_itor_search]([hb_itor]*itor,constvoid*key){return[tree_iterator_search_ge](itor,key);}
-bool[hb_itor_search_le]([hb_itor]*itor,constvoid*key){return[tree_iterator_search_le](itor,key);}
-bool[hb_itor_search_lt]([hb_itor]*itor,constvoid*key){return[tree_iterator_search_lt](itor,key);}
-bool[hb_itor_search_ge]([hb_itor]*itor,constvoid*key){return[tree_iterator_search_ge](itor,key);}
-bool[hb_itor_search_gt]([hb_itor]*itor,constvoid*key){return[tree_iterator_search_gt](itor,key);}
-int[hb_itor_compare](const[hb_itor]*i1,const[hb_itor]*i2){return[tree_iterator_compare](i1,i2);}
-constvoid*[hb_itor_key](const[hb_itor]*itor){return[tree_iterator_key](itor);}
-void**[hb_itor_datum]([hb_itor]*itor){return[tree_iterator_datum](itor);}
-
-bool
-[hb_itor_remove]([hb_itor]*itor)
-{
-if(!itor->[node])
-returnfalse;
-remove_node(itor->[tree],itor->[node]);
-itor->[node]=NULL;
-returntrue;
-}
+if(rotate_l([tree],p))break;
+}
+node=[PARENT](p);
+}elseif([BAL_NEG](p)){
+p->[bal]&=~BAL_MASK;
+node=p;
+}else{
+[ASSERT]((p->[bal]&[BAL_MASK])==0);
+p->[bal]|=1;
+break;
+}
+}else{
+[ASSERT](p->[rlink]==node);
+if([BAL_NEG](p)){
+if([BAL_POS](p->[llink])){
+rotations+=2;
+rotate_lr([tree],p);
+}else{
+rotations+=1;
+if(rotate_r([tree],p))
+break;
+}
+node=[PARENT](p);
+}elseif([BAL_POS](p)){
+p->[bal]&=~BAL_MASK;
+node=p;
+}else{
+[ASSERT]((p->[bal]&[BAL_MASK])==0);
+p->[bal]|=2;
+break;
+}
+}
+
+if(!(p=[PARENT](node)))
+break;
+if(p->[llink]==node){
+left=true;
+}else{
+[ASSERT](p->[rlink]==node);
+left=false;
+}
+}
+[tree]->[rotation_count]+=rotations;
+}
+
+[dict_remove_result]
+[hb_tree_remove]([hb_tree]*[tree],constvoid*key)
+{
+[hb_node]*node=[tree_search_node]([tree],key);
+if(!node)
+return([dict_remove_result]){NULL,NULL,false};
+const[dict_remove_result]result={node->[key],node->[datum],true};
+remove_node([tree],node);
+returnresult;
+}
+
+size_t
+[hb_tree_traverse]([hb_tree]*[tree],[dict_visit_func]visit,void*user_data)
+{
+return[tree_traverse]([tree],visit,user_data);
+}
+
+bool
+[hb_tree_select]([hb_tree]*[tree],size_tn,constvoid**key,void**datum)
+{
+if(n>=[tree]->[count]){
+if(key)
+*key=NULL;
+if(datum)
+*datum=NULL;
+returnfalse;
+}
+[hb_node]*node;
+if(n>=[tree]->[count]/2){
+node=[tree_node_max]([tree]->[root]);
+n=[tree]->[count]-1-n;
+while(n--)
+node=node_prev(node);
+}else{
+node=[tree_node_min]([tree]->[root]);
+while(n--)
+node=node_next(node);
+}
+if(key)
+*key=node->[key];
+if(datum)
+*datum=node->[datum];
+returntrue;
+}
+
+size_t[hb_tree_count](const[hb_tree]*[tree]){return[tree_count]([tree]);}
+size_t[hb_tree_min_path_length](const[hb_tree]*[tree]){return[tree_min_path_length]([tree]);}
+size_t[hb_tree_max_path_length](const[hb_tree]*[tree]){return[tree_max_path_length]([tree]);}
+size_t[hb_tree_total_path_length](const[hb_tree]*[tree]){return[tree_total_path_length]([tree]);}
+
+static[hb_node]*
+node_new(void*key)
+{
+[hb_node]*node=[MALLOC](sizeof(*node));
+if(node){
+[ASSERT]((((intptr_t)node)&3)==0);
+node->[key]=key;
+node->[datum]=NULL;
+node->[bal]=0;
+node->[llink]=NULL;
+node->[rlink]=NULL;
+}
+returnnode;
+}
+
+static[hb_node]*
+node_prev([hb_node]*node)
+{
+if(node->[llink])
+return[tree_node_max](node->[llink]);
+[hb_node]*parent=[PARENT](node);
+while(parent&&parent->[llink]==node){
+node=parent;
+parent=[PARENT](parent);
+}
+returnparent;
+}
+
+static[hb_node]*
+node_next([hb_node]*node)
+{
+if(node->[rlink])
+return[tree_node_min](node->[rlink]);
+[hb_node]*parent=[PARENT](node);
+while(parent&&parent->[rlink]==node){
+node=parent;
+parent=[PARENT](parent);
+}
+returnparent;
+}
+
+staticbool
+node_verify(const[hb_tree]*[tree],const[hb_node]*parent,const[hb_node]*node,
+unsigned*height,size_t*count)
+{
+if(!parent){
+[VERIFY]([tree]->[root]==node);
+}else{
+if(parent->[llink]==node){
+if(node)
+[VERIFY]([tree]->[cmp_func](parent->[key],node->[key])>0);
+}else{
+[ASSERT](parent->[rlink]==node);
+if(node)
+[VERIFY]([tree]->[cmp_func](parent->[key],node->[key])<0);
+}
+}
+if(node){
+intbal=node->[bal]&[BAL_MASK];
+[VERIFY](bal>=0);
+[VERIFY](bal<=2);
+if(bal==2){
+[VERIFY](node->[llink]!=NULL);
+bal=-1;
+}elseif(bal==1){
+[VERIFY](node->[rlink]!=NULL);
+}
+[VERIFY]([PARENT](node)==parent);
+unsignedlheight,rheight;
+if(!node_verify([tree],node,node->[llink],&lheight,count)||
+!node_verify([tree],node,node->[rlink],&rheight,count))
+returnfalse;
+[VERIFY](bal==(int)rheight-(int)lheight);
+if(height)
+*height=[MAX](lheight,rheight)+1;
+*count+=1;
+}else{
+if(height)
+*height=0;
+}
+returntrue;
+}
+
+bool
+[hb_tree_verify](const[hb_tree]*[tree])
+{
+size_tcount=0;
+boolverified=node_verify([tree],NULL,[tree]->[root],NULL,&count);
+[VERIFY]([tree]->[count]==count);
+returnverified;
+}
+
+[hb_itor]*
+[hb_itor_new]([hb_tree]*[tree])
+{
+[hb_itor]*itor=[MALLOC](sizeof(*itor));
+if(itor){
+itor->[tree]=[tree];
+itor->[node]=NULL;
+}
+returnitor;
+}
+
+[dict_itor]*
+[hb_dict_itor_new]([hb_tree]*[tree])
+{
+[dict_itor]*itor=[MALLOC](sizeof(*itor));
+if(itor){
+if(!(itor->[_itor]=[hb_itor_new]([tree]))){
+[FREE](itor);
+returnNULL;
+}
+itor->[_vtable]=&hb_tree_itor_vtable;
+}
+returnitor;
+}
+
+void[hb_itor_free]([hb_itor]*itor){[tree_iterator_free](itor);}
+bool[hb_itor_valid](const[hb_itor]*itor){return[tree_iterator_valid](itor);}
+void[hb_itor_invalidate]([hb_itor]*itor){[tree_iterator_invalidate](itor);}
+
+bool[hb_itor_next]([hb_itor]*itor){
+if(itor->[node])
+itor->[node]=node_next(itor->[node]);
+returnitor->[node]!=NULL;
+}
+
+bool[hb_itor_prev]([hb_itor]*itor){
+if(itor->[node])
+itor->[node]=node_prev(itor->[node]);
+returnitor->[node]!=NULL;
+}
+
+bool[hb_itor_nextn]([hb_itor]*itor,size_tcount){
+while(itor->[node]&&count--)
+itor->[node]=node_next(itor->[node]);
+returnitor->[node]!=NULL;
+}
+
+bool[hb_itor_prevn]([hb_itor]*itor,size_tcount){
+while(itor->[node]&&count--)
+itor->[node]=node_prev(itor->[node]);
+returnitor->[node]!=NULL;
+}
+
+bool[hb_itor_first]([hb_itor]*itor){return[tree_iterator_first](itor);}
+bool[hb_itor_last]([hb_itor]*itor){return[tree_iterator_last](itor);}
+bool[hb_itor_search]([hb_itor]*itor,constvoid*key){return[tree_iterator_search_ge](itor,key);}
+bool[hb_itor_search_le]([hb_itor]*itor,constvoid*key){return[tree_iterator_search_le](itor,key);}
+bool[hb_itor_search_lt]([hb_itor]*itor,constvoid*key){return[tree_iterator_search_lt](itor,key);}
+bool[hb_itor_search_ge]([hb_itor]*itor,constvoid*key){return[tree_iterator_search_ge](itor,key);}
+bool[hb_itor_search_gt]([hb_itor]*itor,constvoid*key){return[tree_iterator_search_gt](itor,key);}
+int[hb_itor_compare](const[hb_itor]*i1,const[hb_itor]*i2){return[tree_iterator_compare](i1,i2);}
+constvoid*[hb_itor_key](const[hb_itor]*itor){return[tree_iterator_key](itor);}
+void**[hb_itor_datum]([hb_itor]*itor){return[tree_iterator_datum](itor);}
+
+bool
+[hb_itor_remove]([hb_itor]*itor)
+{
+if(!itor->[node])
+returnfalse;
+remove_node(itor->[tree],itor->[node]);
+itor->[node]=NULL;
+returntrue;
+}
diff --git a/xml/hb__tree_8h.xml b/xml/hb__tree_8h.xml
index 323d764..c3f7204 100644
--- a/xml/hb__tree_8h.xml
+++ b/xml/hb__tree_8h.xml
@@ -548,7 +548,7 @@
-
+
hb_node::datum
hb_node::key
tree_search_node
@@ -606,7 +606,7 @@
-
+
tree_traverse
@@ -636,7 +636,7 @@
-
+
tree::count
hb_node::datum
hb_node::key
@@ -659,7 +659,7 @@
-
+
tree_count
@@ -677,7 +677,7 @@
-
+
tree_min_path_length
@@ -695,7 +695,7 @@
-
+
tree_max_path_length
@@ -713,7 +713,7 @@
-
+
tree_total_path_length
@@ -731,7 +731,7 @@
-
+
tree::count
tree::root
VERIFY
@@ -751,7 +751,7 @@
-
+
MALLOC
hb_itor::node
hb_itor::tree
@@ -771,11 +771,11 @@
-
+
dict_itor::_itor
dict_itor::_vtable
FREE
- hb_itor_new
+ hb_itor_new
MALLOC
@@ -793,7 +793,7 @@
-
+
tree_iterator_free
@@ -811,7 +811,7 @@
-
+
tree_iterator_valid
@@ -829,7 +829,7 @@
-
+
tree_iterator_invalidate
@@ -847,7 +847,7 @@
-
+
hb_itor::node
@@ -865,7 +865,7 @@
-
+
hb_itor::node
@@ -887,7 +887,7 @@
-
+
hb_itor::node
@@ -909,7 +909,7 @@
-
+
hb_itor::node
@@ -927,7 +927,7 @@
-
+
tree_iterator_first
@@ -945,7 +945,7 @@
-
+
tree_iterator_last
@@ -967,7 +967,7 @@
-
+
tree_iterator_search_ge
@@ -989,7 +989,7 @@
-
+
tree_iterator_search_le
@@ -1011,7 +1011,7 @@
-
+
tree_iterator_search_lt
@@ -1033,7 +1033,7 @@
-
+
tree_iterator_search_ge
@@ -1055,7 +1055,7 @@
-
+
tree_iterator_search_gt
@@ -1073,7 +1073,7 @@
-
+
tree_iterator_key
@@ -1091,7 +1091,7 @@
-
+
tree_iterator_datum
@@ -1113,7 +1113,7 @@
-
+
tree_iterator_compare
@@ -1131,7 +1131,7 @@
-
+
hb_itor::node
hb_itor::tree
diff --git a/xml/skiplist_8c.xml b/xml/skiplist_8c.xml
index f019afc..e2c784a 100644
--- a/xml/skiplist_8c.xml
+++ b/xml/skiplist_8c.xml
@@ -243,7 +243,7 @@
-
+
void
@@ -268,7 +268,7 @@
-
+
[skip_node] *
@@ -289,7 +289,7 @@
-
+
[skip_node] *
@@ -310,7 +310,7 @@
-
+
[skip_node] *
@@ -331,7 +331,7 @@
-
+
[skip_node] *
@@ -352,7 +352,7 @@
-
+
[skip_node] *
@@ -373,7 +373,7 @@
-
+
unsigned
@@ -390,7 +390,7 @@
-
+
[skiplist] *
@@ -470,7 +470,7 @@
FREE
skiplist::head
- skiplist_clear
+ skiplist_clear
[dict_insert_result]
@@ -491,7 +491,7 @@
-
+
ASSERT
skiplist::cmp_func
skip_node::datum
@@ -521,7 +521,7 @@
-
+
skip_node::datum
@@ -543,7 +543,7 @@
-
+
skip_node::datum
@@ -565,7 +565,7 @@
-
+
skip_node::datum
@@ -587,7 +587,7 @@
-
+
skip_node::datum
@@ -609,7 +609,7 @@
-
+
skip_node::datum
@@ -631,7 +631,7 @@
-
+
ASSERT
skiplist::cmp_func
skiplist::count
@@ -664,7 +664,7 @@
-
+
skiplist::count
skip_node::datum
FREE
@@ -696,7 +696,7 @@
-
+
skiplist::head
skip_node::link
@@ -715,7 +715,7 @@
-
+
skiplist::count
@@ -733,7 +733,7 @@
-
+
skiplist::count
skiplist::head
skip_node::link
@@ -767,7 +767,7 @@
-
+
skiplist::head
skip_node::link
@@ -786,7 +786,7 @@
-
+
skiplist_itor::list
MALLOC
skiplist_itor::node
@@ -806,12 +806,12 @@
-
+
dict_itor::_itor
dict_itor::_vtable
FREE
MALLOC
- skiplist_itor_new
+ skiplist_itor_new
void
@@ -828,7 +828,7 @@
-
+
FREE
@@ -846,7 +846,7 @@
-
+
skiplist_itor::node
@@ -864,7 +864,7 @@
-
+
skiplist_itor::node
@@ -882,7 +882,7 @@
-
+
skip_node::link
skiplist_itor::node
@@ -901,7 +901,7 @@
-
+
skiplist_itor::node
skip_node::prev
@@ -924,9 +924,9 @@
-
+
skiplist_itor::node
- skiplist_itor_next
+ skiplist_itor_next
bool
@@ -947,9 +947,9 @@
-
+
skiplist_itor::node
- skiplist_itor_prev
+ skiplist_itor_prev
bool
@@ -966,7 +966,7 @@
-
+
skiplist::head
skip_node::link
skiplist_itor::list
@@ -987,7 +987,7 @@
-
+
skiplist::head
skip_node::link
skiplist_itor::list
@@ -1013,7 +1013,7 @@
-
+
skiplist_itor::list
skiplist_itor::node
@@ -1036,7 +1036,7 @@
-
+
skiplist_itor::list
skiplist_itor::node
@@ -1059,7 +1059,7 @@
-
+
skiplist_itor::list
skiplist_itor::node
@@ -1082,7 +1082,7 @@
-
+
skiplist_itor::list
skiplist_itor::node
@@ -1105,7 +1105,7 @@
-
+
skiplist_itor::list
skiplist_itor::node
@@ -1124,7 +1124,7 @@
-
+
skip_node::key
skiplist_itor::node
@@ -1143,7 +1143,7 @@
-
+
skip_node::datum
skiplist_itor::node
@@ -1166,7 +1166,7 @@
-
+
ASSERT
skiplist::cmp_func
skip_node::key
@@ -1188,13 +1188,13 @@
-
+
ASSERT
skip_node::key
skiplist_itor::list
skiplist_itor::node
dict_remove_result::removed
- skiplist_remove
+ skiplist_remove
@@ -1376,518 +1376,519 @@
if(update[0]->link&&update[0]->link[0])
update[0]->[link][0]->[prev]=x;
for(unsignedk=0;k<nlinks;k++){
-[ASSERT](update[k]->link_count>k);
-x->[link][k]=update[k]->[link][k];
-update[k]->[link][k]=x;
-}
-++list->[count];
-}
-
-[dict_insert_result]
-[skiplist_insert]([skiplist]*list,void*key)
-{
-[skip_node]*x=list->[head];
-[skip_node]*update[[MAX_LINK]]={0};
-for(unsignedk=list->[top_link]+1;k-->0;){
-[ASSERT](x->[link_count]>k);
-for(;;){
-[skip_node]*consty=x->[link][k];
-if(!y)
-break;
-constintcmp=list->[cmp_func](key,y->[key]);
-if(cmp<0){
-while(k>0&&x->[link][k-1]==y)
-update[k--]=x;
-break;
-}elseif(cmp==0)
-return([dict_insert_result]){&y->[datum],false};
-x=y;
-}
-update[k]=x;
-}
-
-x=node_new(key,rand_link_count(list));
-if(!x)
-return([dict_insert_result]){NULL,false};
-node_insert(list,x,update);
-return([dict_insert_result]){&x->[datum],true};
-}
-
-staticinline[skip_node]*
-node_search([skiplist]*list,constvoid*key)
-{
-[skip_node]*x=list->[head];
-for(unsignedk=list->[top_link]+1;k-->0;){
-for(;;){
-[skip_node]*consty=x->[link][k];
-if(!y)
-break;
-constintcmp=list->[cmp_func](key,y->[key]);
-if(cmp<0){
-while(k>0&&x->[link][k-1]==y)
-k--;
-break;
-}elseif(cmp==0)
-returny;
-x=y;
-}
-}
-returnNULL;
-}
-
-staticinline[skip_node]*
-node_search_le([skiplist]*list,constvoid*key)
-{
-[skip_node]*x=list->[head];
-for(unsignedk=list->[top_link]+1;k-->0;){
-for(;;){
-[skip_node]*consty=x->[link][k];
-if(!y)
-break;
-constintcmp=list->[cmp_func](key,y->[key]);
-if(cmp<0){
-while(k>0&&x->[link][k-1]==y)
-k--;
-break;
-}elseif(cmp==0)
-returny;
-x=y;
-}
-}
-returnx==list->[head]?NULL:x;
-}
-
-staticinline[skip_node]*
-node_search_lt([skiplist]*list,constvoid*key)
-{
-[skip_node]*x=list->[head];
-for(unsignedk=list->[top_link]+1;k-->0;){
-for(;;){
-[skip_node]*consty=x->[link][k];
-if(!y)
-break;
-constintcmp=list->[cmp_func](key,y->[key]);
-if(cmp<0){
-while(k>0&&x->[link][k-1]==y)
-k--;
-break;
-}elseif(cmp==0)
-returny->[prev];
-x=y;
-}
-}
-returnx==list->[head]?NULL:x;
-}
-
-staticinline[skip_node]*
-node_search_ge([skiplist]*list,constvoid*key)
-{
-[skip_node]*x=list->[head];
-[skip_node]*ret=NULL;
-for(unsignedk=list->[top_link]+1;k-->0;){
-for(;;){
-[skip_node]*consty=x->[link][k];
-if(!y)
-break;
-constintcmp=list->[cmp_func](key,y->[key]);
-if(cmp<0){
-ret=y;
-while(k>0&&x->[link][k-1]==y)
-k--;
-break;
-}elseif(cmp==0)
-returny;
-x=y;
-}
-}
-returnret;
-}
-
-staticinline[skip_node]*
-node_search_gt([skiplist]*list,constvoid*key)
-{
-[skip_node]*x=list->[head];
-[skip_node]*ret=NULL;
-for(unsignedk=list->[top_link]+1;k-->0;){
-for(;;){
-[skip_node]*consty=x->[link][k];
-if(!y)
-break;
-constintcmp=list->[cmp_func](key,y->[key]);
-if(cmp<0){
-ret=y;
-while(k>0&&x->[link][k-1]==y)
-k--;
-break;
-}elseif(cmp==0)
-returny->[link][0];
-x=y;
-}
-}
-returnret;
-}
-
-void**
-[skiplist_search]([skiplist]*list,constvoid*key)
-{
-[skip_node]*x=node_search(list,key);
-returnx?&x->[datum]:NULL;
-}
-
-void**
-[skiplist_search_le]([skiplist]*list,constvoid*key)
-{
-[skip_node]*x=node_search_le(list,key);
-returnx?&x->[datum]:NULL;
-}
-
-void**
-[skiplist_search_lt]([skiplist]*list,constvoid*key)
-{
-[skip_node]*x=node_search_lt(list,key);
-returnx?&x->[datum]:NULL;
-}
-
-void**
-[skiplist_search_ge]([skiplist]*list,constvoid*key)
-{
-[skip_node]*x=node_search_ge(list,key);
-returnx?&x->[datum]:NULL;
-}
-
-void**
-[skiplist_search_gt]([skiplist]*list,constvoid*key)
-{
-[skip_node]*x=node_search_gt(list,key);
-returnx?&x->[datum]:NULL;
-}
-
-[dict_remove_result]
-[skiplist_remove]([skiplist]*list,constvoid*key)
-{
-[skip_node]*x=list->[head];
-[skip_node]*update[[MAX_LINK]]={0};
-boolfound=false;
-for(unsignedk=list->[top_link]+1;k-->0;){
-[ASSERT](x->[link_count]>k);
-for(;;){
-[skip_node]*consty=x->[link][k];
-if(!y)
-break;
-constintcmp=list->[cmp_func](key,y->[key]);
-if(cmp>0)
-x=y;
-else{
-while(k>0&&x->[link][k-1]==y)
-update[k--]=x;
-if(cmp==0)
-found=true;
-break;
-}
-}
-update[k]=x;
-}
-if(!found)
-return([dict_remove_result]){NULL,NULL,false};
-x=x->[link][0];
-for(unsignedk=0;k<=list->[top_link];k++){
-[ASSERT](update[k]!=NULL);
-[ASSERT](update[k]->link_count>k);
-if(update[k]->link[k]!=x)break;
-update[k]->[link][k]=x->[link][k];
-}
-if(x->[prev])
-x->[prev]->[link][0]=x->[link][0];
-if(x->[link][0])
-x->[link][0]->[prev]=x->[prev];
-[dict_remove_result]result={x->[key],x->[datum],true};
-[FREE](x);
-while(list->[top_link]>0&&!list->[head]->[link][list->[top_link]-1])
-list->[top_link]--;
-list->[count]--;
-returnresult;
-}
-
-size_t
-[skiplist_clear]([skiplist]*list,[dict_delete_func]delete_func)
-{
-[skip_node]*node=list->[head]->[link][0];
-while(node){
-[skip_node]*next=node->[link][0];
-if(delete_func)delete_func(node->[key],node->[datum]);
-[FREE](node);
-node=next;
-}
-
-constsize_tcount=list->[count];
-list->[count]=0;
-list->[head]->[link][list->[top_link]]=NULL;
-while(list->[top_link])
-list->[head]->[link][--list->[top_link]]=NULL;
-
-returncount;
-}
-
-size_t
-[skiplist_traverse]([skiplist]*list,[dict_visit_func]visit,void*user_data)
-{
-size_tcount=0;
-for([skip_node]*node=list->[head]->[link][0];node;node=node->link[0]){
-++count;
-if(!visit(node->key,node->datum,user_data))break;
-}
-returncount;
-}
-
-size_t
-[skiplist_count](const[skiplist]*list)
-{
-returnlist->[count];
-}
-
-bool
-[skiplist_verify](const[skiplist]*list)
-{
-if(list->[count]==0){
-[VERIFY](list->[top_link]==0);
-}else{
-[VERIFY](list->[top_link]>0);
-}
-[VERIFY](list->[top_link]<list->[max_link]);
-for(unsignedi=0;i<list->[top_link];++i){
-[VERIFY](list->[head]->[link][i]!=NULL);
-}
-for(unsignedi=list->[top_link];i<list->[max_link];++i){
-[VERIFY](list->[head]->[link][i]==NULL);
-}
-unsignedobserved_top_link=0;
-
-[skip_node]*prev=NULL;
-[skip_node]*node=list->[head]->[link][0];
-while(node){
-if(observed_top_link<node->link_count)
-observed_top_link=node->[link_count];
-
-[VERIFY](node->[prev]==prev);
-[VERIFY](node->[link_count]>=1);
-[VERIFY](node->[link_count]<=list->[top_link]);
-for(unsignedk=0;k<node->[link_count];k++){
-if(node->[link][k]){
-[VERIFY](node->[link][k]->[link_count]>=k);
-}
-}
-
-prev=node;
-node=node->[link][0];
-}
-[VERIFY](list->[top_link]==observed_top_link);
-returntrue;
-}
-
-size_t
-[skiplist_link_count_histogram](const[skiplist]*list,size_tcounts[],size_tncounts)
-{
-for(size_ti=0;i<ncounts;++i)
-counts[i]=0;
-
-size_tmax_num_links=0;
-for(const[skip_node]*node=list->[head]->[link][0];node;node=node->link[0]){
-if(max_num_links<node->link_count)
-max_num_links=node->link_count;
-if(ncounts>node->link_count)
-counts[node->link_count]++;
-}
-returnmax_num_links;
-}
-
-[skiplist_itor]*
-[skiplist_itor_new]([skiplist]*list)
-{
-[skiplist_itor]*itor=[MALLOC](sizeof(*itor));
-if(itor){
-itor->[list]=list;
-itor->[node]=NULL;
-}
-returnitor;
-}
-
-[dict_itor]*
-[skiplist_dict_itor_new]([skiplist]*list)
-{
-[dict_itor]*itor=[MALLOC](sizeof(*itor));
-if(itor){
-if(!(itor->[_itor]=[skiplist_itor_new](list))){
-[FREE](itor);
-returnNULL;
-}
-itor->[_vtable]=&skiplist_itor_vtable;
-}
-returnitor;
-}
-
-void
-[skiplist_itor_free]([skiplist_itor]*itor)
-{
-[FREE](itor);
-}
-
-bool
-[skiplist_itor_valid](const[skiplist_itor]*itor)
-{
-returnitor->[node]!=NULL;
-}
-
-void
-[skiplist_itor_invalidate]([skiplist_itor]*itor)
-{
-itor->[node]=NULL;
-}
-
-bool
-[skiplist_itor_next]([skiplist_itor]*itor)
-{
-if(itor->[node])
-itor->[node]=itor->[node]->[link][0];
-returnitor->[node]!=NULL;
-}
-
-bool
-[skiplist_itor_prev]([skiplist_itor]*itor)
-{
-if(itor->[node])
-itor->[node]=itor->[node]->[prev];
-returnitor->[node]!=NULL;
-}
-
-bool
-[skiplist_itor_nextn]([skiplist_itor]*itor,size_tcount)
-{
-while(count--)
-if(![skiplist_itor_next](itor))
-returnfalse;
-returnitor->[node]!=NULL;
-}
-
-bool
-[skiplist_itor_prevn]([skiplist_itor]*itor,size_tcount)
-{
-while(count--)
-if(![skiplist_itor_prev](itor))
-returnfalse;
-returnitor->[node]!=NULL;
-}
-
-bool
-[skiplist_itor_first]([skiplist_itor]*itor)
-{
-return(itor->[node]=itor->[list]->[head]->[link][0])!=NULL;
-}
-
-bool
-[skiplist_itor_last]([skiplist_itor]*itor)
-{
-[skip_node]*x=itor->[list]->[head];
-for(unsignedk=itor->[list]->[top_link];k-->0;){
-while(x->[link][k])
-x=x->[link][k];
-}
-if(x==itor->[list]->[head]){
-itor->[node]=NULL;
-returnfalse;
-}else{
-itor->[node]=x;
-returntrue;
-}
-}
-
-bool
-[skiplist_itor_search]([skiplist_itor]*itor,constvoid*key)
-{
-return(itor->[node]=node_search(itor->[list],key))!=NULL;
-}
-
-bool
-[skiplist_itor_search_le]([skiplist_itor]*itor,constvoid*key)
-{
-return(itor->[node]=node_search_le(itor->[list],key))!=NULL;
-}
-
-bool
-[skiplist_itor_search_lt]([skiplist_itor]*itor,constvoid*key)
-{
-return(itor->[node]=node_search_lt(itor->[list],key))!=NULL;
-}
-
-bool
-[skiplist_itor_search_ge]([skiplist_itor]*itor,constvoid*key)
-{
-return(itor->[node]=node_search_ge(itor->[list],key))!=NULL;
-}
-
-bool
-[skiplist_itor_search_gt]([skiplist_itor]*itor,constvoid*key)
-{
-return(itor->[node]=node_search_gt(itor->[list],key))!=NULL;
-}
-
-constvoid*
-[skiplist_itor_key](const[skiplist_itor]*itor)
-{
-returnitor->[node]?itor->[node]->[key]:NULL;
-}
-
-void**
-[skiplist_itor_datum]([skiplist_itor]*itor)
-{
-returnitor->[node]?&itor->[node]->[datum]:NULL;
-}
-
-int
-[skiplist_itor_compare](const[skiplist_itor]*itor1,const[skiplist_itor]*itor2)
-{
-[ASSERT](itor1->[list]==itor2->[list]);
-if(!itor1->[node])
-return!itor2->[node]?0:-1;
-if(!itor2->[node])
-return1;
-returnitor1->[list]->[cmp_func](itor1->[node]->[key],itor2->[node]->[key]);
-}
-
-bool
-[skiplist_itor_remove]([skiplist_itor]*itor)
-{
-if(!itor->[node])
-returnfalse;
-
-[dict_remove_result]result=[skiplist_remove](itor->[list],itor->[node]->[key]);
-[ASSERT](result.[removed]);
-itor->[node]=NULL;
-returntrue;
-}
-
-staticinline[skip_node]*
-node_new(void*key,unsignedlink_count)
-{
-[ASSERT](link_count>=1);
-
-[skip_node]*node=[MALLOC](sizeof(*node)+
-sizeof(node->[link][0])*link_count);
-if(node){
-node->[key]=key;
-node->[datum]=NULL;
-node->[prev]=NULL;
-node->[link_count]=link_count;
-memset(node->[link],0,sizeof(node->[link][0])*link_count);
-}
-returnnode;
-}
-
-staticinlineunsigned
-rand_link_count([skiplist]*list)
-{
-unsignedcount=(unsigned)__builtin_ctz(dict_rand())/2+1;
-return(count>=list->[max_link])?list->[max_link]-1:count;
-}
+[ASSERT](!update[k]);
+[ASSERT](update[k]->link_count>k);
+x->[link][k]=update[k]->[link][k];
+update[k]->[link][k]=x;
+}
+++list->[count];
+}
+
+[dict_insert_result]
+[skiplist_insert]([skiplist]*list,void*key)
+{
+[skip_node]*x=list->[head];
+[skip_node]*update[[MAX_LINK]]={0};
+for(unsignedk=list->[top_link]+1;k-->0;){
+[ASSERT](x->[link_count]>k);
+for(;;){
+[skip_node]*consty=x->[link][k];
+if(!y)
+break;
+constintcmp=list->[cmp_func](key,y->[key]);
+if(cmp<0){
+while(k>0&&x->[link][k-1]==y)
+update[k--]=x;
+break;
+}elseif(cmp==0)
+return([dict_insert_result]){&y->[datum],false};
+x=y;
+}
+update[k]=x;
+}
+
+x=node_new(key,rand_link_count(list));
+if(!x)
+return([dict_insert_result]){NULL,false};
+node_insert(list,x,update);
+return([dict_insert_result]){&x->[datum],true};
+}
+
+staticinline[skip_node]*
+node_search([skiplist]*list,constvoid*key)
+{
+[skip_node]*x=list->[head];
+for(unsignedk=list->[top_link]+1;k-->0;){
+for(;;){
+[skip_node]*consty=x->[link][k];
+if(!y)
+break;
+constintcmp=list->[cmp_func](key,y->[key]);
+if(cmp<0){
+while(k>0&&x->[link][k-1]==y)
+k--;
+break;
+}elseif(cmp==0)
+returny;
+x=y;
+}
+}
+returnNULL;
+}
+
+staticinline[skip_node]*
+node_search_le([skiplist]*list,constvoid*key)
+{
+[skip_node]*x=list->[head];
+for(unsignedk=list->[top_link]+1;k-->0;){
+for(;;){
+[skip_node]*consty=x->[link][k];
+if(!y)
+break;
+constintcmp=list->[cmp_func](key,y->[key]);
+if(cmp<0){
+while(k>0&&x->[link][k-1]==y)
+k--;
+break;
+}elseif(cmp==0)
+returny;
+x=y;
+}
+}
+returnx==list->[head]?NULL:x;
+}
+
+staticinline[skip_node]*
+node_search_lt([skiplist]*list,constvoid*key)
+{
+[skip_node]*x=list->[head];
+for(unsignedk=list->[top_link]+1;k-->0;){
+for(;;){
+[skip_node]*consty=x->[link][k];
+if(!y)
+break;
+constintcmp=list->[cmp_func](key,y->[key]);
+if(cmp<0){
+while(k>0&&x->[link][k-1]==y)
+k--;
+break;
+}elseif(cmp==0)
+returny->[prev];
+x=y;
+}
+}
+returnx==list->[head]?NULL:x;
+}
+
+staticinline[skip_node]*
+node_search_ge([skiplist]*list,constvoid*key)
+{
+[skip_node]*x=list->[head];
+[skip_node]*ret=NULL;
+for(unsignedk=list->[top_link]+1;k-->0;){
+for(;;){
+[skip_node]*consty=x->[link][k];
+if(!y)
+break;
+constintcmp=list->[cmp_func](key,y->[key]);
+if(cmp<0){
+ret=y;
+while(k>0&&x->[link][k-1]==y)
+k--;
+break;
+}elseif(cmp==0)
+returny;
+x=y;
+}
+}
+returnret;
+}
+
+staticinline[skip_node]*
+node_search_gt([skiplist]*list,constvoid*key)
+{
+[skip_node]*x=list->[head];
+[skip_node]*ret=NULL;
+for(unsignedk=list->[top_link]+1;k-->0;){
+for(;;){
+[skip_node]*consty=x->[link][k];
+if(!y)
+break;
+constintcmp=list->[cmp_func](key,y->[key]);
+if(cmp<0){
+ret=y;
+while(k>0&&x->[link][k-1]==y)
+k--;
+break;
+}elseif(cmp==0)
+returny->[link][0];
+x=y;
+}
+}
+returnret;
+}
+
+void**
+[skiplist_search]([skiplist]*list,constvoid*key)
+{
+[skip_node]*x=node_search(list,key);
+returnx?&x->[datum]:NULL;
+}
+
+void**
+[skiplist_search_le]([skiplist]*list,constvoid*key)
+{
+[skip_node]*x=node_search_le(list,key);
+returnx?&x->[datum]:NULL;
+}
+
+void**
+[skiplist_search_lt]([skiplist]*list,constvoid*key)
+{
+[skip_node]*x=node_search_lt(list,key);
+returnx?&x->[datum]:NULL;
+}
+
+void**
+[skiplist_search_ge]([skiplist]*list,constvoid*key)
+{
+[skip_node]*x=node_search_ge(list,key);
+returnx?&x->[datum]:NULL;
+}
+
+void**
+[skiplist_search_gt]([skiplist]*list,constvoid*key)
+{
+[skip_node]*x=node_search_gt(list,key);
+returnx?&x->[datum]:NULL;
+}
+
+[dict_remove_result]
+[skiplist_remove]([skiplist]*list,constvoid*key)
+{
+[skip_node]*x=list->[head];
+[skip_node]*update[[MAX_LINK]]={0};
+boolfound=false;
+for(unsignedk=list->[top_link]+1;k-->0;){
+[ASSERT](x->[link_count]>k);
+for(;;){
+[skip_node]*consty=x->[link][k];
+if(!y)
+break;
+constintcmp=list->[cmp_func](key,y->[key]);
+if(cmp>0)
+x=y;
+else{
+while(k>0&&x->[link][k-1]==y)
+update[k--]=x;
+if(cmp==0)
+found=true;
+break;
+}
+}
+update[k]=x;
+}
+if(!found)
+return([dict_remove_result]){NULL,NULL,false};
+x=x->[link][0];
+for(unsignedk=0;k<=list->[top_link];k++){
+[ASSERT](update[k]!=NULL);
+[ASSERT](update[k]->link_count>k);
+if(update[k]->link[k]!=x)break;
+update[k]->[link][k]=x->[link][k];
+}
+if(x->[prev])
+x->[prev]->[link][0]=x->[link][0];
+if(x->[link][0])
+x->[link][0]->[prev]=x->[prev];
+[dict_remove_result]result={x->[key],x->[datum],true};
+[FREE](x);
+while(list->[top_link]>0&&!list->[head]->[link][list->[top_link]-1])
+list->[top_link]--;
+list->[count]--;
+returnresult;
+}
+
+size_t
+[skiplist_clear]([skiplist]*list,[dict_delete_func]delete_func)
+{
+[skip_node]*node=list->[head]->[link][0];
+while(node){
+[skip_node]*next=node->[link][0];
+if(delete_func)delete_func(node->[key],node->[datum]);
+[FREE](node);
+node=next;
+}
+
+constsize_tcount=list->[count];
+list->[count]=0;
+list->[head]->[link][list->[top_link]]=NULL;
+while(list->[top_link])
+list->[head]->[link][--list->[top_link]]=NULL;
+
+returncount;
+}
+
+size_t
+[skiplist_traverse]([skiplist]*list,[dict_visit_func]visit,void*user_data)
+{
+size_tcount=0;
+for([skip_node]*node=list->[head]->[link][0];node;node=node->link[0]){
+++count;
+if(!visit(node->key,node->datum,user_data))break;
+}
+returncount;
+}
+
+size_t
+[skiplist_count](const[skiplist]*list)
+{
+returnlist->[count];
+}
+
+bool
+[skiplist_verify](const[skiplist]*list)
+{
+if(list->[count]==0){
+[VERIFY](list->[top_link]==0);
+}else{
+[VERIFY](list->[top_link]>0);
+}
+[VERIFY](list->[top_link]<list->[max_link]);
+for(unsignedi=0;i<list->[top_link];++i){
+[VERIFY](list->[head]->[link][i]!=NULL);
+}
+for(unsignedi=list->[top_link];i<list->[max_link];++i){
+[VERIFY](list->[head]->[link][i]==NULL);
+}
+unsignedobserved_top_link=0;
+
+[skip_node]*prev=NULL;
+[skip_node]*node=list->[head]->[link][0];
+while(node){
+if(observed_top_link<node->link_count)
+observed_top_link=node->[link_count];
+
+[VERIFY](node->[prev]==prev);
+[VERIFY](node->[link_count]>=1);
+[VERIFY](node->[link_count]<=list->[top_link]);
+for(unsignedk=0;k<node->[link_count];k++){
+if(node->[link][k]){
+[VERIFY](node->[link][k]->[link_count]>=k);
+}
+}
+
+prev=node;
+node=node->[link][0];
+}
+[VERIFY](list->[top_link]==observed_top_link);
+returntrue;
+}
+
+size_t
+[skiplist_link_count_histogram](const[skiplist]*list,size_tcounts[],size_tncounts)
+{
+for(size_ti=0;i<ncounts;++i)
+counts[i]=0;
+
+size_tmax_num_links=0;
+for(const[skip_node]*node=list->[head]->[link][0];node;node=node->link[0]){
+if(max_num_links<node->link_count)
+max_num_links=node->link_count;
+if(ncounts>node->link_count)
+counts[node->link_count]++;
+}
+returnmax_num_links;
+}
+
+[skiplist_itor]*
+[skiplist_itor_new]([skiplist]*list)
+{
+[skiplist_itor]*itor=[MALLOC](sizeof(*itor));
+if(itor){
+itor->[list]=list;
+itor->[node]=NULL;
+}
+returnitor;
+}
+
+[dict_itor]*
+[skiplist_dict_itor_new]([skiplist]*list)
+{
+[dict_itor]*itor=[MALLOC](sizeof(*itor));
+if(itor){
+if(!(itor->[_itor]=[skiplist_itor_new](list))){
+[FREE](itor);
+returnNULL;
+}
+itor->[_vtable]=&skiplist_itor_vtable;
+}
+returnitor;
+}
+
+void
+[skiplist_itor_free]([skiplist_itor]*itor)
+{
+[FREE](itor);
+}
+
+bool
+[skiplist_itor_valid](const[skiplist_itor]*itor)
+{
+returnitor->[node]!=NULL;
+}
+
+void
+[skiplist_itor_invalidate]([skiplist_itor]*itor)
+{
+itor->[node]=NULL;
+}
+
+bool
+[skiplist_itor_next]([skiplist_itor]*itor)
+{
+if(itor->[node])
+itor->[node]=itor->[node]->[link][0];
+returnitor->[node]!=NULL;
+}
+
+bool
+[skiplist_itor_prev]([skiplist_itor]*itor)
+{
+if(itor->[node])
+itor->[node]=itor->[node]->[prev];
+returnitor->[node]!=NULL;
+}
+
+bool
+[skiplist_itor_nextn]([skiplist_itor]*itor,size_tcount)
+{
+while(count--)
+if(![skiplist_itor_next](itor))
+returnfalse;
+returnitor->[node]!=NULL;
+}
+
+bool
+[skiplist_itor_prevn]([skiplist_itor]*itor,size_tcount)
+{
+while(count--)
+if(![skiplist_itor_prev](itor))
+returnfalse;
+returnitor->[node]!=NULL;
+}
+
+bool
+[skiplist_itor_first]([skiplist_itor]*itor)
+{
+return(itor->[node]=itor->[list]->[head]->[link][0])!=NULL;
+}
+
+bool
+[skiplist_itor_last]([skiplist_itor]*itor)
+{
+[skip_node]*x=itor->[list]->[head];
+for(unsignedk=itor->[list]->[top_link];k-->0;){
+while(x->[link][k])
+x=x->[link][k];
+}
+if(x==itor->[list]->[head]){
+itor->[node]=NULL;
+returnfalse;
+}else{
+itor->[node]=x;
+returntrue;
+}
+}
+
+bool
+[skiplist_itor_search]([skiplist_itor]*itor,constvoid*key)
+{
+return(itor->[node]=node_search(itor->[list],key))!=NULL;
+}
+
+bool
+[skiplist_itor_search_le]([skiplist_itor]*itor,constvoid*key)
+{
+return(itor->[node]=node_search_le(itor->[list],key))!=NULL;
+}
+
+bool
+[skiplist_itor_search_lt]([skiplist_itor]*itor,constvoid*key)
+{
+return(itor->[node]=node_search_lt(itor->[list],key))!=NULL;
+}
+
+bool
+[skiplist_itor_search_ge]([skiplist_itor]*itor,constvoid*key)
+{
+return(itor->[node]=node_search_ge(itor->[list],key))!=NULL;
+}
+
+bool
+[skiplist_itor_search_gt]([skiplist_itor]*itor,constvoid*key)
+{
+return(itor->[node]=node_search_gt(itor->[list],key))!=NULL;
+}
+
+constvoid*
+[skiplist_itor_key](const[skiplist_itor]*itor)
+{
+returnitor->[node]?itor->[node]->[key]:NULL;
+}
+
+void**
+[skiplist_itor_datum]([skiplist_itor]*itor)
+{
+returnitor->[node]?&itor->[node]->[datum]:NULL;
+}
+
+int
+[skiplist_itor_compare](const[skiplist_itor]*itor1,const[skiplist_itor]*itor2)
+{
+[ASSERT](itor1->[list]==itor2->[list]);
+if(!itor1->[node])
+return!itor2->[node]?0:-1;
+if(!itor2->[node])
+return1;
+returnitor1->[list]->[cmp_func](itor1->[node]->[key],itor2->[node]->[key]);
+}
+
+bool
+[skiplist_itor_remove]([skiplist_itor]*itor)
+{
+if(!itor->[node])
+returnfalse;
+
+[dict_remove_result]result=[skiplist_remove](itor->[list],itor->[node]->[key]);
+[ASSERT](result.[removed]);
+itor->[node]=NULL;
+returntrue;
+}
+
+staticinline[skip_node]*
+node_new(void*key,unsignedlink_count)
+{
+[ASSERT](link_count>=1);
+
+[skip_node]*node=[MALLOC](sizeof(*node)+
+sizeof(node->[link][0])*link_count);
+if(node){
+node->[key]=key;
+node->[datum]=NULL;
+node->[prev]=NULL;
+node->[link_count]=link_count;
+memset(node->[link],0,sizeof(node->[link][0])*link_count);
+}
+returnnode;
+}
+
+staticinlineunsigned
+rand_link_count([skiplist]*list)
+{
+unsignedcount=(unsigned)__builtin_ctz(dict_rand())/2+1;
+return(count>=list->[max_link])?list->[max_link]-1:count;
+}
diff --git a/xml/skiplist_8h.xml b/xml/skiplist_8h.xml
index 5fe3aa5..9a28135 100644
--- a/xml/skiplist_8h.xml
+++ b/xml/skiplist_8h.xml
@@ -393,7 +393,7 @@
FREE
skiplist::head
- skiplist_clear
+ skiplist_clear
[dict_insert_result]
@@ -414,7 +414,7 @@
-
+
ASSERT
skiplist::cmp_func
skip_node::datum
@@ -444,7 +444,7 @@
-
+
skip_node::datum
@@ -466,7 +466,7 @@
-
+
skip_node::datum
@@ -488,7 +488,7 @@
-
+
skip_node::datum
@@ -510,7 +510,7 @@
-
+
skip_node::datum
@@ -532,7 +532,7 @@
-
+
skip_node::datum
@@ -554,7 +554,7 @@
-
+
ASSERT
skiplist::cmp_func
skiplist::count
@@ -587,7 +587,7 @@
-
+
skiplist::count
skip_node::datum
FREE
@@ -619,7 +619,7 @@
-
+
skiplist::head
skip_node::link
@@ -638,7 +638,7 @@
-
+
skiplist::count
@@ -656,7 +656,7 @@
-
+
skiplist::count
skiplist::head
skip_node::link
@@ -690,7 +690,7 @@
-
+
skiplist::head
skip_node::link
@@ -709,7 +709,7 @@
-
+
skiplist_itor::list
MALLOC
skiplist_itor::node
@@ -729,12 +729,12 @@
-
+
dict_itor::_itor
dict_itor::_vtable
FREE
MALLOC
- skiplist_itor_new
+ skiplist_itor_new
void
@@ -751,7 +751,7 @@
-
+
FREE
@@ -769,7 +769,7 @@
-
+
skiplist_itor::node
@@ -787,7 +787,7 @@
-
+
skiplist_itor::node
@@ -805,7 +805,7 @@
-
+
skip_node::link
skiplist_itor::node
@@ -824,7 +824,7 @@
-
+
skiplist_itor::node
skip_node::prev
@@ -847,9 +847,9 @@
-
+
skiplist_itor::node
- skiplist_itor_next
+ skiplist_itor_next
bool
@@ -870,9 +870,9 @@
-
+
skiplist_itor::node
- skiplist_itor_prev
+ skiplist_itor_prev
bool
@@ -889,7 +889,7 @@
-
+
skiplist::head
skip_node::link
skiplist_itor::list
@@ -910,7 +910,7 @@
-
+
skiplist::head
skip_node::link
skiplist_itor::list
@@ -936,7 +936,7 @@
-
+
skiplist_itor::list
skiplist_itor::node
@@ -959,7 +959,7 @@
-
+
skiplist_itor::list
skiplist_itor::node
@@ -982,7 +982,7 @@
-
+
skiplist_itor::list
skiplist_itor::node
@@ -1005,7 +1005,7 @@
-
+
skiplist_itor::list
skiplist_itor::node
@@ -1028,7 +1028,7 @@
-
+
skiplist_itor::list
skiplist_itor::node
@@ -1047,7 +1047,7 @@
-
+
skip_node::key
skiplist_itor::node
@@ -1066,7 +1066,7 @@
-
+
skip_node::datum
skiplist_itor::node
@@ -1089,7 +1089,7 @@
-
+
ASSERT
skiplist::cmp_func
skip_node::key
@@ -1111,13 +1111,13 @@
-
+
ASSERT
skip_node::key
skiplist_itor::list
skiplist_itor::node
dict_remove_result::removed
- skiplist_remove
+ skiplist_remove