9 * Anderson tree implementation with extensions:
10 * parents are kept track of
11 * duplicates are allowed
12 * data is never allocated or destroyed here
14 * TODO: seperate offset,stride,base into 'generic array', seperate pool
17 typedef struct aatree aatree
;
18 typedef struct aatree_node aatree_node
;
19 typedef struct aatree_pool_node aatree_pool_node
;
21 typedef u32 aatree_ptr
;
22 #define AATREE_PTR_NIL 0xffffffff
26 u32 offset
, stride
; /* distance between elements */
29 int (*p_cmp
)( void *a
, void *b
);
35 aatree_ptr left
, right
, parent
;
39 struct aatree_pool_node
46 * ===========================================================================*/
48 /* return a pointer to the start of the data referenced by t */
49 static void *aatree_get_data( aatree
*tree
, aatree_ptr t
);
51 /* link node x into the tree with root t */
52 static aatree_ptr
aatree_insert( aatree
*tree
, aatree_ptr t
, aatree_ptr x
);
54 /* delete node x from tree, does not free memory */
55 static aatree_ptr
aatree_del( aatree
*tree
, aatree_ptr x
);
57 /* get pointer to element in tree with index k */
58 static aatree_ptr
aatree_kth( aatree
*tree
, aatree_ptr t
, u32 k
);
60 /* get pointer to the element above x */
61 static aatree_ptr
aatree_next( aatree
*tree
, aatree_ptr x
);
63 /* get pointer by value, returns NIL if not found.
65 * if duplicates values are present then the result is undefined, but it will be
66 * AN node with that value, just maybe not the first lexicographically
68 static aatree_ptr
aatree_find( aatree
*tree
, aatree_ptr t
, void *value
);
71 * ===========================================================================*/
73 static void *aatree_get_data( aatree
*tree
, aatree_ptr t
)
75 return (u8
*)tree
->base
+ tree
->stride
*t
;
78 static u8
*aatree_node_base( aatree
*tree
, aatree_ptr t
)
80 return (u8
*)tree
->base
+ tree
->stride
*t
+ tree
->offset
;
83 static aatree_pool_node
*aatree_get_pool_node( aatree
*tree
, aatree_ptr t
)
85 return (aatree_pool_node
*)aatree_node_base( tree
, t
);
88 static aatree_node
*aatree_get_node( aatree
*tree
, aatree_ptr t
)
90 return (aatree_node
*)aatree_node_base( tree
, t
);
93 static void aatree_recount( aatree
*tree
, aatree_ptr n
)
95 aatree_node
*pnode
= aatree_get_node( tree
, n
);
98 if( pnode
->left
!= AATREE_PTR_NIL
)
99 pnode
->count
+= aatree_get_node( tree
, pnode
->left
)->count
;
101 if( pnode
->right
!= AATREE_PTR_NIL
)
102 pnode
->count
+= aatree_get_node( tree
, pnode
->right
)->count
;
111 static aatree_ptr
aatree_skew( aatree
*tree
, u32 t
)
113 if( t
== AATREE_PTR_NIL
) return t
;
115 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
116 if( ptnode
->left
== AATREE_PTR_NIL
) return t
;
118 aatree_node
*plnode
= aatree_get_node( tree
, ptnode
->left
);
119 if( plnode
->level
== ptnode
->level
)
121 aatree_ptr l
= ptnode
->left
;
122 ptnode
->left
= plnode
->right
;
125 aatree_recount( tree
, t
);
126 aatree_recount( tree
, l
);
128 plnode
->parent
= ptnode
->parent
;
130 if( ptnode
->left
!= AATREE_PTR_NIL
)
131 aatree_get_node( tree
, ptnode
->left
)->parent
= t
;
147 static aatree_ptr
aatree_split( aatree
*tree
, aatree_ptr t
)
149 if( t
== AATREE_PTR_NIL
) return t
;
151 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
152 if( ptnode
->right
== AATREE_PTR_NIL
) return t
;
154 aatree_node
*prnode
= aatree_get_node( tree
, ptnode
->right
);
155 if( prnode
->right
== AATREE_PTR_NIL
) return t
;
157 aatree_node
*prrnode
= aatree_get_node( tree
, prnode
->right
);
158 if( ptnode
->level
== prrnode
->level
)
160 aatree_ptr r
= ptnode
->right
;
161 ptnode
->right
= prnode
->left
;
165 aatree_recount( tree
, t
);
166 aatree_recount( tree
, r
);
168 prnode
->parent
= ptnode
->parent
;
170 if( ptnode
->right
!= AATREE_PTR_NIL
)
171 aatree_get_node( tree
, ptnode
->right
)->parent
= t
;
179 static aatree_ptr
aatree_insert( aatree
*tree
, aatree_ptr t
, aatree_ptr x
)
181 aatree_node
*pxnode
= aatree_get_node( tree
, x
);
183 if( t
== AATREE_PTR_NIL
)
185 pxnode
->left
= AATREE_PTR_NIL
;
186 pxnode
->right
= AATREE_PTR_NIL
;
187 pxnode
->parent
= AATREE_PTR_NIL
;
193 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
194 int cmp_result
= tree
->p_cmp( aatree_get_data( tree
, t
),
195 aatree_get_data( tree
, x
) );
199 if( cmp_result
<= 0 )
201 ptnode
->left
= aatree_insert( tree
, ptnode
->left
, x
);
202 aatree_node
*plnode
= aatree_get_node( tree
, ptnode
->left
);
207 ptnode
->right
= aatree_insert( tree
, ptnode
->right
, x
);
208 aatree_node
*prnode
= aatree_get_node( tree
, ptnode
->right
);
212 t
= aatree_skew( tree
, t
);
213 t
= aatree_split( tree
, t
);
217 static void aatree_link_down( aatree
*tree
, aatree_ptr p
, aatree_ptr
*pl
,
222 if( *pl
!= AATREE_PTR_NIL
)
223 aatree_get_node( tree
, *pl
)->parent
= p
;
226 static aatree_ptr
aatree_copy_links( aatree
*tree
, aatree_ptr root
,
227 aatree_ptr src
, aatree_ptr dst
)
229 aatree_node
*pdst
= aatree_get_node( tree
, dst
),
230 *psrc
= aatree_get_node( tree
, src
);
232 pdst
->count
= psrc
->count
;
233 pdst
->level
= psrc
->level
;
234 pdst
->parent
= psrc
->parent
;
236 aatree_link_down( tree
, dst
, &pdst
->left
, psrc
->left
);
237 aatree_link_down( tree
, dst
, &pdst
->right
, psrc
->right
);
239 if( pdst
->parent
!= AATREE_PTR_NIL
)
241 aatree_node
*parent
= aatree_get_node( tree
, pdst
->parent
);
243 if( parent
->left
== src
)
245 else if( parent
->right
== src
)
254 static aatree_ptr
aatree_del( aatree
*tree
, aatree_ptr x
)
259 int count
= 1, dir
= 0;
261 /* TODO: maybe be a better way to do this, without counting back up */
262 for( aatree_node
*s
= aatree_get_node( tree
, x
);
263 s
->parent
!= AATREE_PTR_NIL
;
265 s
= aatree_get_node( tree
, s
->parent
);
270 int index
= count
- (++top
);
273 aatree_node
*itnode
= aatree_get_node( tree
, it
);
274 if( itnode
->parent
== AATREE_PTR_NIL
)
280 aatree_ptr _ptrswap_src
= AATREE_PTR_NIL
,
281 _ptrswap_dst
= AATREE_PTR_NIL
;
283 aatree_node
*pxnode
= aatree_get_node( tree
, x
);
284 aatree_ptr root
= up
[ count
-1 ];
285 if( pxnode
->left
== AATREE_PTR_NIL
|| pxnode
->right
== AATREE_PTR_NIL
)
289 aatree_node
*pnode
= aatree_get_node( tree
, up
[top
-1] ),
290 *parent
= aatree_get_node( tree
, pxnode
->parent
);
292 aatree_ptr next
= pxnode
->left
== AATREE_PTR_NIL
?
296 if( parent
->left
== x
) pnode
->left
= next
;
297 else pnode
->right
= next
;
299 if( next
!= AATREE_PTR_NIL
)
301 aatree_node
*pnext
= aatree_get_node( tree
, next
);
302 pnext
->parent
= up
[top
-1];
307 if( pxnode
->right
!= AATREE_PTR_NIL
) root
= pxnode
->right
;
308 else if( pxnode
->left
!= AATREE_PTR_NIL
) root
= pxnode
->left
;
309 else return AATREE_PTR_NIL
;
311 aatree_node
*newroot
= aatree_get_node( tree
, root
);
312 newroot
->parent
= AATREE_PTR_NIL
;
317 aatree_ptr heir
= pxnode
->right
,
320 aatree_node
*pheir
= aatree_get_node( tree
, heir
);
322 while( pheir
->left
!= AATREE_PTR_NIL
)
324 up
[top
++] = prev
= heir
;
326 pheir
= aatree_get_node( tree
, heir
);
332 aatree_node
*pprev
= aatree_get_node( tree
, prev
);
335 aatree_link_down( tree
, prev
, &pprev
->right
, pheir
->right
);
337 aatree_link_down( tree
, prev
, &pprev
->left
, pheir
->right
);
345 aatree_node
*above
= aatree_get_node( tree
, up
[top
-1] );
346 dir
= above
->right
== up
[top
];
349 aatree_recount( tree
, up
[top
] );
350 aatree_node
*pntop
= aatree_get_node( tree
, up
[top
] );
352 if( !(pntop
->left
== AATREE_PTR_NIL
|| pntop
->right
== AATREE_PTR_NIL
) )
354 aatree_node
*pnl
= aatree_get_node( tree
, pntop
->left
),
355 *pnr
= aatree_get_node( tree
, pntop
->right
);
357 if( pnl
->level
< pntop
->level
-1 || pnr
->level
< pntop
->level
-1 )
359 if( pnr
->level
> --pntop
->level
)
360 pnr
->level
= pntop
->level
;
362 up
[top
] = aatree_skew( tree
, up
[top
] );
364 aatree_node
*ut
= aatree_get_node( tree
, up
[top
] );
365 ut
->right
= aatree_skew( tree
, ut
->right
);
367 aatree_node
*utr
= aatree_get_node( tree
, ut
->right
);
368 utr
->right
= aatree_skew( tree
, utr
->right
);
370 up
[top
] = aatree_split( tree
, up
[top
] );
371 ut
= aatree_get_node( tree
, up
[top
] );
373 ut
->right
= aatree_split( tree
, ut
->right
);
379 aatree_node
*ut1
= aatree_get_node( tree
, up
[top
-1] );
382 aatree_link_down( tree
, up
[top
-1], &ut1
->right
, up
[top
] );
384 aatree_link_down( tree
, up
[top
-1], &ut1
->left
, up
[top
] );
389 aatree_get_node( tree
, root
)->parent
= AATREE_PTR_NIL
;
393 /* This is our extension to the original non-recursive delete, so no data
395 if( _ptrswap_dst
!= AATREE_PTR_NIL
)
396 root
= aatree_copy_links( tree
, root
, _ptrswap_src
, _ptrswap_dst
);
401 static aatree_ptr
aatree_kth( aatree
*tree
, aatree_ptr t
, u32 k
)
405 while( t
!= AATREE_PTR_NIL
)
407 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
410 if( ptnode
->left
!= AATREE_PTR_NIL
)
411 j
+= aatree_get_node( tree
, ptnode
->left
)->count
;
431 return AATREE_PTR_NIL
;
434 static aatree_ptr
aatree_next( aatree
*tree
, aatree_ptr x
)
436 /* if can go left, go left then all the way right,
437 * else go up, if it was right link accept
440 aatree_node
*pnode
= aatree_get_node( tree
, x
);
441 if( pnode
->right
!= AATREE_PTR_NIL
)
443 aatree_ptr next
= pnode
->right
;
447 aatree_node
*pnext
= aatree_get_node( tree
, next
);
449 if( pnext
->left
!= AATREE_PTR_NIL
)
461 aatree_node
*pnode
= aatree_get_node( tree
, next
);
463 if( pnode
->parent
== AATREE_PTR_NIL
)
464 return AATREE_PTR_NIL
;
466 aatree_node
*pabove
= aatree_get_node( tree
, pnode
->parent
);
467 if( pabove
->left
== next
)
468 return pnode
->parent
;
470 next
= pnode
->parent
;
475 static aatree_ptr
aatree_find( aatree
*tree
, aatree_ptr t
, void *value
)
477 while( t
!= AATREE_PTR_NIL
)
479 int cmp_result
= tree
->p_cmp( aatree_get_data( tree
, t
), value
);
481 if( cmp_result
== 0 )
485 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
497 * Debugging stuff, everything below is scaffholding and will be removed
498 * =============================================================================
501 static int aatree_verify_split( aatree
*tree
, aatree_ptr t
)
503 if( t
== AATREE_PTR_NIL
) return 1;
505 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
506 if( ptnode
->right
== AATREE_PTR_NIL
) return 1;
508 aatree_node
*prnode
= aatree_get_node( tree
, ptnode
->right
);
509 if( prnode
->right
== AATREE_PTR_NIL
) return 1;
511 aatree_node
*prrnode
= aatree_get_node( tree
, prnode
->right
);
512 if( ptnode
->level
== prrnode
->level
)
518 static int aatree_verify_skew( aatree
*tree
, aatree_ptr t
)
520 if( t
== AATREE_PTR_NIL
) return 1;
522 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
523 if( ptnode
->left
== AATREE_PTR_NIL
) return 1;
525 aatree_node
*plnode
= aatree_get_node( tree
, ptnode
->left
);
526 if( plnode
->level
== ptnode
->level
)
532 static int aatree_verify( aatree
*tree
, aatree_ptr t
)
534 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
535 if( ptnode
->parent
!= AATREE_PTR_NIL
)
537 aatree_node
*parent
= aatree_get_node( tree
, ptnode
->parent
);
538 if( !(parent
->left
== t
|| parent
->right
== t
) )
542 if( ptnode
->left
!= AATREE_PTR_NIL
)
543 if( aatree_get_node( tree
, ptnode
->left
)->parent
!= t
)
545 if( ptnode
->right
!= AATREE_PTR_NIL
)
546 if( aatree_get_node( tree
, ptnode
->right
)->parent
!= t
)
549 return aatree_verify_skew( tree
, t
) &&
550 aatree_verify_split( tree
, t
);
554 static void aatree_show_r( aatree
*tree
, aatree_ptr t
, int lvl
,
555 void(*p_show
)(void *data
) )
557 if( t
!= AATREE_PTR_NIL
)
559 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
560 aatree_show_r( tree
, ptnode
->left
, lvl
+1, p_show
);
562 void *data
= aatree_get_data( tree
, t
);
564 for( int i
=0; i
<lvl
; i
++ )
569 vg_info( " (%d) \n", t
);
571 aatree_show_r( tree
, ptnode
->right
, lvl
+1, p_show
);
575 static void aatree_show( aatree
*tree
, aatree_ptr t
, void(*p_show
)(void *data
))
577 if( t
!= AATREE_PTR_NIL
)
579 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
580 aatree_show( tree
, ptnode
->left
, p_show
);
581 void *data
= aatree_get_data( tree
, t
);
583 for( int i
=0; i
<ptnode
->level
; i
++ )
588 vg_info( " (%d) \n", t
);
590 aatree_show( tree
, ptnode
->right
, p_show
);
594 static void aatree_show_counts( aatree
*tree
, aatree_ptr t
, int lvl
, int *ln
,
596 void(*p_show
)(void *data
), int show
)
600 if( t
== AATREE_PTR_NIL
) return;
602 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
603 void *data
= aatree_get_data( tree
, t
);
605 aatree_show_counts( tree
, ptnode
->left
, lvl
+1, ln
, err
, p_show
, show
);
607 if( show
) vg_info( "%03d| ", *ln
);
611 for( int i
=0; i
<lvl
; i
++ )
618 if( ptnode
->left
!= AATREE_PTR_NIL
&& ptnode
->right
!= AATREE_PTR_NIL
)
620 if( ptnode
->left
!= AATREE_PTR_NIL
&& ptnode
->right
== AATREE_PTR_NIL
)
622 if( ptnode
->left
== AATREE_PTR_NIL
&& ptnode
->right
!= AATREE_PTR_NIL
)
625 printf( " (%d, %d, parent: %d. V: %d, level: %d) \n", t
,
626 ptnode
->count
, ptnode
->parent
,
627 aatree_verify( tree
, t
), ptnode
->level
);
630 if( !aatree_verify( tree
, t
) )
633 vg_info( "error\n" );
637 aatree_show_counts( tree
, ptnode
->right
, lvl
+1, ln
, err
, p_show
, show
);
641 * Pool allocator utility which can be placed in a union with regular aa nodes.
644 static aatree_ptr
aatree_init_pool( aatree
*info
, u32 item_count
)
646 for( aatree_ptr i
=0; i
<item_count
; i
++ )
648 aatree_pool_node
*pn
= aatree_get_pool_node( info
, i
);
650 if( i
==item_count
-1 )
651 pn
->next_free
= AATREE_PTR_NIL
;
659 static aatree_ptr
aatree_pool_alloc( aatree
*info
, aatree_ptr
*head
)
661 if( *head
== AATREE_PTR_NIL
)
663 vg_error( "No nodes free in pool allocator!\n" );
664 return AATREE_PTR_NIL
;
668 aatree_ptr gap
= *head
;
669 *head
= aatree_get_pool_node( info
, *head
)->next_free
;
674 static void aatree_pool_free( aatree
*info
, aatree_ptr node
, aatree_ptr
*head
)
676 aatree_pool_node
*pn
= aatree_get_pool_node( info
, node
);
677 pn
->next_free
= *head
;
681 #endif /* VG_STORE_H */