7 #include "ul_utmalloc.h"
10 /*===========================================================*/
13 #define GAVL_CHECK_NOBAL 0x0020
15 #define GAVL_ERR_PARENT 0x0001
16 #define GAVL_ERR_HDIFF 0x0002
17 #define GAVL_ERR_HEIGHT 0x0010
18 #define GAVL_ERR_BALANCE 0x0020
20 typedef struct gavl_check_st{
27 int (*node_fnc)(gavl_node_t *node, struct gavl_check_st *check);
33 gavl_hdiff_check_recurse(gavl_node_t *node, gavl_node_t *parent,
34 gavl_check_st_t* check)
40 if(node->parent!=parent) check->err|=GAVL_ERR_PARENT;
41 lh=gavl_hdiff_check_recurse(node->left, node, check);
43 check->err|=check->node_fnc(node, check);
44 rh=gavl_hdiff_check_recurse(node->right, node, check);
46 if((rh>lh+1) || (rh+1<lh)){
47 if(!(check->mode&GAVL_CHECK_NOBAL)){
48 check->err|=GAVL_ERR_BALANCE;
51 if(node->hdiff!=lh-rh){
52 check->err|=GAVL_ERR_HDIFF;
55 if(check->err && !check->node) check->node=node;
57 return lh>rh?lh+1:rh+1;
61 gavl_hdiff_check_reperr(gavl_node_t *node, gavl_check_st_t* check)
68 gavl_hdiff_check(gavl_node_t *node, int mode)
72 gavl_check_st_t check;
82 h=gavl_hdiff_check_recurse(node, node->parent,&check);
84 if(!(check.mode&GAVL_CHECK_NOBAL)){
85 for(i=0;(1<<i)<=check.count;i++);
86 if(h>i+1) check.err|=GAVL_ERR_HEIGHT;
90 gavl_hdiff_check_reperr(node,&check);
95 /*===========================================================*/
96 /* custom tree definition */
98 #include "ul_gavlcust.h"
99 #include "ul_gavlrepcust.h"
100 #include "ul_gavlflesint.h"
102 #undef GAVL_TEST_FLES
104 typedef struct cust2_item {
110 typedef struct cust2_root {
111 #ifndef GAVL_TEST_FLES
112 gavl_cust_root_field_t my_root;
113 #else /*GAVL_TEST_FLES*/
114 gavl_fles_int_root_field_t my_root;
115 #endif /*GAVL_TEST_FLES*/
121 typedef int cust2_key_t;
123 /* Custom tree declarations */
124 /* GAVL_CUST_NODE_INT_DEC - standard custom tree with internal node */
125 /* GAVL_FLES_INT_DEC - tree with enhanced first last access speed */
127 #ifndef GAVL_TEST_FLES
128 GAVL_CUST_NODE_INT_DEC(cust2, cust2_root_t, cust2_item_t, cust2_key_t,
129 my_root, my_node, my_val, cust2_cmp_fnc)
130 #else /*GAVL_TEST_FLES*/
131 GAVL_FLES_INT_DEC(cust2, cust2_root_t, cust2_item_t, cust2_key_t,
132 my_root, my_node, my_val, cust2_cmp_fnc)
133 #endif /*GAVL_TEST_FLES*/
136 cust2_cmp_fnc(const cust2_key_t *a, const cust2_key_t *b)
139 if (*a<*b) return -1;
143 /* Custom tree implementation */
144 /* GAVL_CUST_NODE_INT_IMP - version with strict ordering */
145 /* GAVL_CUST_NODE_INT_REP_IMP - version without strict ordering */
146 /* GAVL_FLES_INT_IMP - tree with enhanced first last access speed */
148 #ifndef GAVL_TEST_FLES
149 GAVL_CUST_NODE_INT_IMP(cust2, cust2_root_t, cust2_item_t, cust2_key_t,
150 my_root, my_node, my_val, cust2_cmp_fnc)
151 #else /*GAVL_TEST_FLES*/
152 GAVL_FLES_INT_IMP(cust2, cust2_root_t, cust2_item_t, cust2_key_t,
153 my_root, my_node, my_val, cust2_cmp_fnc, 0,
154 root->my_first_val=cust2_first(root)->my_val,
155 root->my_last_val=cust2_first(root)->my_val,
157 #endif /*GAVL_TEST_FLES*/
159 cust2_root_t cust2_root;
162 void test_cust_tree(void)
166 cust2_item_t *item, *item2;
168 item=malloc(sizeof(cust2_item_t));
170 if(cust2_insert(&cust2_root,item)<0)
171 printf("cust2_insert error\n");
173 printf("Custom tree cust2 for_each:\n");
174 gavl_cust_for_each(cust2, &cust2_root, item)
175 printf("%d ",item->my_val);
179 printf("Custom tree cust2 for_each_from %ld:\n", (long)k);
180 gavl_cust_for_each_from(cust2, &cust2_root, &k, item){
181 printf("After %d : ",item->my_val);
182 gavl_cust_for_each_after(cust2, &cust2_root, &item->my_val, item2)
183 printf(" %d",item2->my_val);
187 printf("Custom tree cust2 delete 1-90:\n");
188 for(i=1;i<=100-10;i++){
189 item=cust2_find(&cust2_root,&i);
190 if(cust2_delete(&cust2_root,item)<0)
191 printf("cust2_delete error\n");
195 printf("Custom tree cust2 for_each_rev:\n");
196 gavl_cust_for_each_rev(cust2,&cust2_root,item)
197 printf("%d ",item->my_val);
200 printf("Custom tree cust2 for_each_cut:\n");
201 gavl_cust_for_each_cut(cust2,&cust2_root,item){
202 printf("%d ",item->my_val);
208 void test_cust_tree_it(void)
216 item=malloc(sizeof(cust2_item_t));
218 if(cust2_insert(&cust2_root,item)<0)
219 printf("cust2_insert error\n");
221 printf("Custom tree cust2 for each with iterator:\n");
222 for(cust2_first_it(&cust2_root, &it1);
223 (item=cust2_it2item(&it1));cust2_next_it(&it1))
224 printf("%d ",item->my_val);
228 printf("Custom tree cust2 for_each_from %ld:\n", (long)k);
229 for(cust2_find_first_it(&cust2_root, &k, &it1);
230 (item=cust2_it2item(&it1));cust2_next_it(&it1)){
231 printf("After %d : ",item->my_val);
232 for(cust2_find_after_it(&cust2_root, &item->my_val, &it2);
233 (item=cust2_it2item(&it2));cust2_next_it(&it2))
234 printf(" %d",item->my_val);
238 printf("Custom tree cust2 delete 1-90:\n");
239 for(i=1;i<=100-10;i++){
240 item=cust2_find(&cust2_root,&i);
241 if(cust2_delete(&cust2_root,item)<0)
242 printf("cust2_delete error\n");
246 printf("Custom tree cust2 for_each_rev:\n");
247 for(cust2_last_it(&cust2_root, &it1);
248 (item=cust2_it2item(&it1));cust2_prev_it(&it1))
249 printf("%d ",item->my_val);
252 printf("Custom tree cust2 for_each_cut:\n");
253 gavl_cust_for_each_cut(cust2,&cust2_root,item){
254 printf("%d ",item->my_val);
260 void test_cust_tree_macro_it(void)
268 item=malloc(sizeof(cust2_item_t));
270 if(cust2_insert(&cust2_root,item)<0)
271 printf("cust2_insert error\n");
273 printf("Custom tree cust2 for each with iterator:\n");
274 ul_for_each_it(cust2, &cust2_root, it1){
275 item=cust2_it2item(&it1);
276 printf("%d ",item->my_val);
281 printf("Custom tree cust2 for_each_from %ld:\n", (long)k);
282 ul_for_each_from_it(cust2, &cust2_root, &k, it1){
283 item=cust2_it2item(&it1);
284 printf("After %d : ",item->my_val);
285 ul_for_each_after_it(cust2, &cust2_root, &item->my_val, it2){
286 item=cust2_it2item(&it2);
287 printf(" %d",item->my_val);
292 printf("Custom tree cust2 delete 1-90:\n");
293 for(i=1;i<=100-10;i++){
294 item=cust2_find(&cust2_root,&i);
295 if(cust2_delete(&cust2_root,item)<0)
296 printf("cust2_delete error\n");
300 printf("Custom tree cust2 for_each_rev:\n");
301 ul_for_each_rev_it(cust2, &cust2_root, it1){
302 item=cust2_it2item(&it1);
303 printf("%d ",item->my_val);
307 printf("Custom tree cust2 for_each_cut:\n");
308 gavl_cust_for_each_cut(cust2,&cust2_root,item){
309 printf("%d ",item->my_val);
315 /*===========================================================*/
318 void timing_test_print(struct timeval *start, struct timeval *stop, char *s)
321 sec=stop->tv_sec-start->tv_sec;
322 usec=stop->tv_usec-start->tv_usec;
331 printf("%s :\t%4ld.%06ld\n",s,sec,usec);
334 void cust_timing_test(void)
337 int items_cnt=100000;
338 cust2_item_t *items, *item;
339 struct timeval time_start, time_stop;
341 printf("\nRunning custom tree timing test for %d items\n",items_cnt);
343 items=malloc(items_cnt*sizeof(cust2_item_t));
345 printf("malloc failed\n");
349 for(i=0;i<items_cnt;i++){
351 items[i].more_data=0;
354 gettimeofday(&time_start,NULL);
355 for(i=0;i<items_cnt;i++){
356 if(cust2_insert(&cust2_root,items+i)<0)
357 printf("cust2_insert error\n");
359 gettimeofday(&time_stop,NULL);
360 timing_test_print(&time_start,&time_stop,"cust insert");
362 gettimeofday(&time_start,NULL);
363 for(i=0;i<items_cnt;i++){
364 if(!(item=cust2_find(&cust2_root,&i)))
365 printf("cust2_find error\n");
368 printf("gavl_find mismatch\n");
370 gettimeofday(&time_stop,NULL);
371 timing_test_print(&time_start,&time_stop,"cust find");
373 gettimeofday(&time_start,NULL);
374 for(i=0;i<items_cnt;i++){
376 if(cust2_delete(&cust2_root,items+i)<0)
377 printf("cust2_delete error\n");
379 if(!cust2_cut_first(&cust2_root))
380 printf("cust2_cut_first NULL\n");
383 gettimeofday(&time_stop,NULL);
384 timing_test_print(&time_start,&time_stop,"cust delete");
389 void timing_test(void)
392 int items_cnt=100000;
395 struct timeval time_start, time_stop;
398 tt_root.root_node = NULL;
399 tt_root.node_offs = UL_OFFSETOF(cust2_item_t, my_node);
400 /*tt_root.node_offs = -1;*/
401 tt_root.key_offs = UL_OFFSETOF(cust2_item_t, my_val);
402 tt_root.cmp_fnc = gavl_cmp_int;
404 printf("\nRunning generic tree timing test for %d items\n",items_cnt);
406 items=malloc(items_cnt*sizeof(cust2_item_t));
408 printf("malloc failed\n");
412 for(i=0;i<items_cnt;i++){
414 items[i].more_data=0;
417 gettimeofday(&time_start,NULL);
418 for(i=0;i<items_cnt;i++){
419 if(gavl_insert(&tt_root,items+i,0)<0)
420 printf("gavl_insert error\n");
422 gettimeofday(&time_stop,NULL);
423 timing_test_print(&time_start,&time_stop,"GAVL insert");
425 gettimeofday(&time_start,NULL);
426 for(i=0;i<items_cnt;i++){
427 if(!(item=gavl_find(&tt_root,&i)))
428 printf("gavl_find error\n");
431 printf("gavl_find mismatch\n");
433 gettimeofday(&time_stop,NULL);
434 timing_test_print(&time_start,&time_stop,"GAVL find");
436 gettimeofday(&time_start,NULL);
437 for(i=0;i<items_cnt;i++){
438 if(gavl_delete(&tt_root,items+i)<0)
439 printf("gavl_delete error\n");
441 gettimeofday(&time_stop,NULL);
442 timing_test_print(&time_start,&time_stop,"GAVL delete");
447 /*===========================================================*/
450 typedef struct test_item1 {
454 gavl_root_t test_gavl1={
457 .key_offs = UL_OFFSETOF(test_item1_t, val),
458 .cmp_fnc = gavl_cmp_int
461 int gavl_print_tree1(gavl_root_t *root, gavl_node_t *node,
462 int lev, gavl_node_t *parent, int mode)
475 lh=gavl_print_tree1(root, node->left,lev+1, node, mode);
477 val=*(int*)gavl_node2key(root,node);
479 for(i=0;i++<lev;) printf(" ");
480 printf(">%d %d\n",val,node->hdiff);
482 if(node->parent!=parent) printf("Parent error\n");
483 rh=gavl_print_tree1(root, node->right,lev+1, node, mode);
484 if((rh>lh+1) || (rh+1<lh)){
486 printf("Balance error for value %d, lh %d, rd %d, hdiff %d\n",val,lh,rh,node->hdiff);
490 if(node->hdiff!=lh-rh){
491 printf("HDIFF error for value %d, lh %d, rd %d, hdiff %d\n",val,lh,rh,node->hdiff);
497 for(i=0;(1<<i)<=cnt;i++);
499 printf("Count %d log %d max %d\n",cnt,i,ret);
501 if(ret>i+1) printf("Tree height >log2(n)+1\n");
503 printf("Error %d\n",err);
510 int gavl_check(gavl_root_t *root)
515 ret=gavl_print_tree1(root, root->root_node, 0, NULL, 0xc0);
520 void gavl_foreach_test1(gavl_root_t *root)
522 int val, prev=-INT_MAX;
524 for(n=gavl_first_node(root);n;n=gavl_next_node(n)){
525 val=*(int*)gavl_node2key(&test_gavl1,n);
527 if(prev>val) printf("\nError in ordering\n");
535 void gavl_foreach_test2(gavl_root_t *root)
537 int val, prev=-INT_MAX;
540 printf("gavl_generic_for_each:\n");
541 gavl_generic_for_each(test_item1_t, root, item1){
543 printf("after %d:",val);
544 if(prev>val) printf("\nError in ordering\n");
546 gavl_generic_for_each_after(test_item1_t, root, &val, item2)
548 printf(" %d",item2->val);
555 int main(int argc, char *argv[])
562 gavl_node_t *node, *node1, *node2;
572 printf("\nTree edit: a <val>|d <val>|x..exit > ");
577 if (scanf("%d",&val)==1){
578 item=malloc(sizeof(test_item1_t));
580 ret=gavl_insert(&test_gavl1,item,0);
581 printf("gavl_insert of val %d returned %d\n\n",val,ret);
582 gavl_print_tree1(&test_gavl1, test_gavl1.root_node, 0, NULL, 0);
586 if (scanf("%d",&val)==1){
587 ret=gavl_search_node(&test_gavl1, &val, GAVL_FANY, &node);
589 printf("No node with key %d\n",val);
592 item=gavl_node2item(&test_gavl1,node);
593 ret=gavl_delete_node(&test_gavl1,node);
595 printf("gavl_delete_node of val %d returned %d\n\n",val,ret);
596 gavl_print_tree1(&test_gavl1, test_gavl1.root_node, 0, NULL, 0);
600 if (scanf("%d",&val)==1){
601 item=gavl_find_first(&test_gavl1, &val);
603 printf("gavl_find_first find item with value %d\n", item->val);
605 printf("gavl_find_first found no item\n");
606 item=gavl_find_after(&test_gavl1, &val);
608 printf("gavl_find_after find item with value %d\n", item->val);
610 printf("gavl_find_after found no item\n");
614 gavl_foreach_test1(&test_gavl1);
618 gavl_foreach_test2(&test_gavl1);
622 ret=scanf("%d %d %d",&val, &n, &i);
626 item=malloc(sizeof(test_item1_t));
628 ret=gavl_insert(&test_gavl1,item,0);
630 printf("gavl_insert of val %d returned %d\n\n",val,ret);
631 gavl_print_tree1(&test_gavl1, test_gavl1.root_node, 0, NULL, 0xc0);
635 gavl_print_tree1(&test_gavl1, test_gavl1.root_node, 0, NULL, 0);
636 gavl_print_tree1(&test_gavl1, test_gavl1.root_node, 0, NULL, 0xc0);
642 node=gavl_last_node(&test_gavl1);
644 node1=gavl_prev_node(node);
645 gavl_delete_node(&test_gavl1,node);
646 gavl_print_tree1(&test_gavl1, test_gavl1.root_node, 0, NULL, 0xc0);
648 node->right=node2; if(node2) node2->parent=node;
652 test_gavl1.root_node=node2;
653 gavl_print_tree1(&test_gavl1, test_gavl1.root_node, 0, NULL, 0x20);
658 node=gavl_first_node(&test_gavl1);
660 node1=gavl_next_node(node);
661 gavl_delete_node(&test_gavl1,node);
662 gavl_print_tree1(&test_gavl1, test_gavl1.root_node, 0, NULL, 0xc0);
664 node->left=node2; if(node2) node2->parent=node;
668 test_gavl1.root_node=node2;
669 gavl_print_tree1(&test_gavl1, test_gavl1.root_node, 0, NULL, 0x20);
672 gavl_balance_enhance(&test_gavl1.root_node);
673 gavl_print_tree1(&test_gavl1, test_gavl1.root_node, 0, NULL, 0x20);
676 for(node1=gavl_first_node(&test_gavl1);node1;node1=node2){
677 /*This is test code and it doesnot free node or item */
678 node2=gavl_delete_and_next_node(&test_gavl1, node1);
679 printf("Value of node %d\n",*(int*)gavl_node2key(&test_gavl1, node1));
680 gavl_print_tree1(&test_gavl1, test_gavl1.root_node, 0, NULL, 0x20);
684 gavl_balance(&test_gavl1);
685 gavl_print_tree1(&test_gavl1, test_gavl1.root_node, 0, NULL, 0x00);
688 if (scanf("%d",&val)==1){
689 ret=gavl_search_node(&test_gavl1, &val, GAVL_FANY, &node);
691 printf("No node with key %d\n",val);
696 if(node1->hdiff>0) node1=node1->left;
697 else node1=node1->right;
699 gavl_adjust_hdiff(node,-i);
700 if(!node->parent) test_gavl1.root_node=NULL;
701 else if(node==node->parent->left) node->parent->left=NULL;
702 else node->parent->right=NULL;
705 gavl_print_tree1(&test_gavl1, test_gavl1.root_node, 0, NULL, 0x20);
708 printf("\nCheck of custom tree for_each\n");
710 printf("\nCheck of custom tree iterators\n");
711 test_cust_tree_macro_it();
712 printf("\nCheck of custom tree for_each iterators\n");