4 typedef struct aatree aatree
;
5 typedef struct aatree_node aatree_node
;
7 typedef u32 aatree_ptr
;
8 #define AATREE_PTR_NIL 0xffffffff
12 u32 offset
, stride
; /* distance between elements */
15 int (*p_cmp
)( void *a
, void *b
);
16 int (*p_cmpv
)( void *a
, void *v
);
21 aatree_ptr left
, right
, parent
;
25 static void *aatree_get_data( aatree
*tree
, aatree_ptr t
)
27 return tree
->base
+ tree
->stride
*t
;
30 static aatree_node
*aatree_get_node( aatree
*tree
, aatree_ptr t
)
32 return tree
->base
+ tree
->stride
*t
+ tree
->offset
;
35 static void aatree_recount( aatree
*tree
, aatree_ptr n
)
37 aatree_node
*pnode
= aatree_get_node( tree
, n
);
40 if( pnode
->left
!= AATREE_PTR_NIL
)
41 pnode
->count
+= aatree_get_node( tree
, pnode
->left
)->count
;
43 if( pnode
->right
!= AATREE_PTR_NIL
)
44 pnode
->count
+= aatree_get_node( tree
, pnode
->right
)->count
;
53 static aatree_ptr
aatree_skew( aatree
*tree
, u32 t
)
55 if( t
== AATREE_PTR_NIL
) return t
;
57 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
58 if( ptnode
->left
== AATREE_PTR_NIL
) return t
;
60 aatree_node
*plnode
= aatree_get_node( tree
, ptnode
->left
);
61 if( plnode
->level
== ptnode
->level
)
63 aatree_ptr l
= ptnode
->left
;
64 ptnode
->left
= plnode
->right
;
67 aatree_recount( tree
, t
);
68 aatree_recount( tree
, l
);
70 /* B's parent is now T,
71 * T's parent is now L,
72 * L's parent is now T's old parent */
73 plnode
->parent
= ptnode
->parent
;
75 if( ptnode
->left
!= AATREE_PTR_NIL
)
76 aatree_get_node( tree
, ptnode
->left
)->parent
= t
;
92 static aatree_ptr
aatree_split( aatree
*tree
, aatree_ptr t
)
94 if( t
== AATREE_PTR_NIL
) return t
;
96 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
97 if( ptnode
->right
== AATREE_PTR_NIL
) return t
;
99 aatree_node
*prnode
= aatree_get_node( tree
, ptnode
->right
);
100 if( prnode
->right
== AATREE_PTR_NIL
) return t
;
102 aatree_node
*prrnode
= aatree_get_node( tree
, prnode
->right
);
103 if( ptnode
->level
== prrnode
->level
)
105 aatree_ptr r
= ptnode
->right
;
106 ptnode
->right
= prnode
->left
;
110 aatree_recount( tree
, t
);
111 aatree_recount( tree
, r
);
113 /* B's parent is now T,
114 * T's parent is now R,
115 * R's parent is now T's old parent */
116 prnode
->parent
= ptnode
->parent
;
118 if( ptnode
->right
!= AATREE_PTR_NIL
)
119 aatree_get_node( tree
, ptnode
->right
)->parent
= t
;
127 static int aatree_verify( aatree
*tree
, aatree_ptr t
);
129 static aatree_ptr
aatree_insert( aatree
*tree
, aatree_ptr t
, aatree_ptr x
)
131 aatree_node
*pxnode
= aatree_get_node( tree
, x
);
133 if( t
== AATREE_PTR_NIL
)
135 pxnode
->left
= AATREE_PTR_NIL
;
136 pxnode
->right
= AATREE_PTR_NIL
;
137 pxnode
->parent
= AATREE_PTR_NIL
;
143 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
144 int cmp_result
= tree
->p_cmp( aatree_get_data( tree
, t
),
145 aatree_get_data( tree
, x
) );
149 if( cmp_result
<= 0 )
151 ptnode
->left
= aatree_insert( tree
, ptnode
->left
, x
);
152 aatree_node
*plnode
= aatree_get_node( tree
, ptnode
->left
);
157 ptnode
->right
= aatree_insert( tree
, ptnode
->right
, x
);
158 aatree_node
*prnode
= aatree_get_node( tree
, ptnode
->right
);
162 t
= aatree_skew( tree
, t
);
163 t
= aatree_split( tree
, t
);
167 static void aatree_link_down( aatree
*tree
, aatree_ptr p
, aatree_ptr
*pl
,
172 if( *pl
!= AATREE_PTR_NIL
)
173 aatree_get_node( tree
, *pl
)->parent
= p
;
176 static aatree_ptr
aatree_del( aatree
*tree
, aatree_ptr x
)
178 /* Simulate what we would have created on the tail,
179 * we work along the tail in order, doing the same as the regular
180 * implementation. This only works because we have parent pointers. */
185 int count
= 1, dir
= 0;
187 aatree_node
*search
= aatree_get_node( tree
, x
);
189 if( search
->parent
== AATREE_PTR_NIL
) break;
192 search
= aatree_get_node( tree
, search
->parent
);
199 int index
= count
- (++top
);
202 aatree_node
*itnode
= aatree_get_node( tree
, it
);
203 if( itnode
->parent
== AATREE_PTR_NIL
)
209 aatree_ptr _ptrswap_src
= AATREE_PTR_NIL
,
210 _ptrswap_dst
= AATREE_PTR_NIL
;
212 aatree_node
*pxnode
= aatree_get_node( tree
, x
);
213 aatree_ptr root
= up
[ count
-1 ];
214 if( pxnode
->left
== AATREE_PTR_NIL
|| pxnode
->right
== AATREE_PTR_NIL
)
218 aatree_node
*pnode
= aatree_get_node( tree
, up
[top
-1] ),
219 *parent
= aatree_get_node( tree
, pxnode
->parent
);
221 aatree_ptr next
= pxnode
->left
== AATREE_PTR_NIL
?
225 if( parent
->left
== x
) pnode
->left
= next
;
226 else pnode
->right
= next
;
228 if( next
!= AATREE_PTR_NIL
)
230 aatree_node
*pnext
= aatree_get_node( tree
, next
);
231 pnext
->parent
= up
[top
-1];
236 if( pxnode
->right
!= AATREE_PTR_NIL
) root
= pxnode
->right
;
237 else if( pxnode
->left
!= AATREE_PTR_NIL
) root
= pxnode
->left
;
238 else return AATREE_PTR_NIL
;
240 aatree_node
*newroot
= aatree_get_node( tree
, root
);
241 newroot
->parent
= AATREE_PTR_NIL
;
246 aatree_ptr heir
= pxnode
->right
,
249 aatree_node
*pheir
= aatree_get_node( tree
, heir
);
251 while( pheir
->left
!= AATREE_PTR_NIL
)
253 up
[top
++] = prev
= heir
;
255 pheir
= aatree_get_node( tree
, heir
);
261 aatree_node
*pprev
= aatree_get_node( tree
, prev
);
264 aatree_link_down( tree
, prev
, &pprev
->right
, pheir
->right
);
266 aatree_link_down( tree
, prev
, &pprev
->left
, pheir
->right
);
273 aatree_node
*above
= aatree_get_node( tree
, up
[top
-1] );
274 dir
= above
->right
== up
[top
];
277 aatree_recount( tree
, up
[top
] );
278 aatree_node
*pntop
= aatree_get_node( tree
, up
[top
] );
279 if( pntop
->left
== AATREE_PTR_NIL
|| pntop
->right
== AATREE_PTR_NIL
){}
283 *pnl
= aatree_get_node( tree
, pntop
->left
),
284 *pnr
= aatree_get_node( tree
, pntop
->right
);
286 if( pnl
->level
< pntop
->level
-1 || pnr
->level
< pntop
->level
-1 )
288 if( pnr
->level
> --pntop
->level
)
289 pnr
->level
= pntop
->level
;
291 up
[top
] = aatree_skew( tree
, up
[top
] );
293 aatree_node
*ut
= aatree_get_node( tree
, up
[top
] );
294 ut
->right
= aatree_skew( tree
, ut
->right
);
296 aatree_node
*utr
= aatree_get_node( tree
, ut
->right
);
297 utr
->right
= aatree_skew( tree
, utr
->right
);
299 up
[top
] = aatree_split( tree
, up
[top
] );
300 ut
= aatree_get_node( tree
, up
[top
] );
302 ut
->right
= aatree_split( tree
, ut
->right
);
308 aatree_node
*ut1
= aatree_get_node( tree
, up
[top
-1] );
311 aatree_link_down( tree
, up
[top
-1], &ut1
->right
, up
[top
] );
313 aatree_link_down( tree
, up
[top
-1], &ut1
->left
, up
[top
] );
318 aatree_get_node( tree
, root
)->parent
= AATREE_PTR_NIL
;
322 if( _ptrswap_dst
!= AATREE_PTR_NIL
)
324 /* Copy everything except data from _src to _dst, relink.
325 * This is a bit of a messy addon, since the algorithm is originally
326 * based around moving the actual data(key) around, but we have the
327 * requirement that data can't move, so everything is done normally but
328 * the pointers are just swapped afterwards.
331 aatree_node
*pdst
= aatree_get_node( tree
, _ptrswap_dst
),
332 *psrc
= aatree_get_node( tree
, _ptrswap_src
);
334 pdst
->count
= psrc
->count
;
335 pdst
->level
= psrc
->level
;
336 pdst
->left
= psrc
->left
;
337 pdst
->right
= psrc
->right
;
338 pdst
->parent
= psrc
->parent
;
340 if( pdst
->parent
!= AATREE_PTR_NIL
)
342 aatree_node
*parent
= aatree_get_node( tree
, pdst
->parent
);
344 if( parent
->left
== _ptrswap_src
)
345 parent
->left
= _ptrswap_dst
;
346 else if( parent
->right
== _ptrswap_src
)
347 parent
->right
= _ptrswap_dst
;
354 if( pdst
->left
!= AATREE_PTR_NIL
)
355 aatree_get_node( tree
, pdst
->left
)->parent
= _ptrswap_dst
;
356 if( pdst
->right
!= AATREE_PTR_NIL
)
357 aatree_get_node( tree
, pdst
->right
)->parent
= _ptrswap_dst
;
367 static aatree_ptr
aatree_kth( aatree
*tree
, aatree_ptr t
, u32 k
)
371 while( t
!= AATREE_PTR_NIL
)
373 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
376 if( ptnode
->left
!= AATREE_PTR_NIL
)
377 j
+= aatree_get_node( tree
, ptnode
->left
)->count
;
397 return AATREE_PTR_NIL
;
400 static aatree_ptr
aatree_ptrof( aatree
*tree
, aatree_ptr t
, void *value
)
402 while( t
!= AATREE_PTR_NIL
)
404 int cmp_result
= tree
->p_cmpv( aatree_get_data( tree
, t
), value
);
406 if( cmp_result
== 0 )
410 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
423 * Debugging stuff, everything below is scaffholding and will be removed
424 * =============================================================================
427 static int aatree_verify_split( aatree
*tree
, aatree_ptr t
)
429 if( t
== AATREE_PTR_NIL
) return 1;
431 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
432 if( ptnode
->right
== AATREE_PTR_NIL
) return 1;
434 aatree_node
*prnode
= aatree_get_node( tree
, ptnode
->right
);
435 if( prnode
->right
== AATREE_PTR_NIL
) return 1;
437 aatree_node
*prrnode
= aatree_get_node( tree
, prnode
->right
);
438 if( ptnode
->level
== prrnode
->level
)
444 static int aatree_verify_skew( aatree
*tree
, aatree_ptr t
)
446 if( t
== AATREE_PTR_NIL
) return 1;
448 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
449 if( ptnode
->left
== AATREE_PTR_NIL
) return 1;
451 aatree_node
*plnode
= aatree_get_node( tree
, ptnode
->left
);
452 if( plnode
->level
== ptnode
->level
)
458 static int aatree_verify( aatree
*tree
, aatree_ptr t
)
460 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
461 if( ptnode
->parent
!= AATREE_PTR_NIL
)
463 aatree_node
*parent
= aatree_get_node( tree
, ptnode
->parent
);
464 if( !(parent
->left
== t
|| parent
->right
== t
) )
468 if( ptnode
->left
!= AATREE_PTR_NIL
)
469 if( aatree_get_node( tree
, ptnode
->left
)->parent
!= t
)
471 if( ptnode
->right
!= AATREE_PTR_NIL
)
472 if( aatree_get_node( tree
, ptnode
->right
)->parent
!= t
)
475 return aatree_verify_skew( tree
, t
) &&
476 aatree_verify_split( tree
, t
);
480 static void aatree_show_r( aatree
*tree
, aatree_ptr t
, int lvl
,
481 void(*p_show
)(void *data
) )
483 if( t
!= AATREE_PTR_NIL
)
485 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
486 aatree_show_r( tree
, ptnode
->left
, lvl
+1, p_show
);
488 void *data
= aatree_get_data( tree
, t
);
490 for( int i
=0; i
<lvl
; i
++ )
495 printf( " (%d) \n", t
);
497 aatree_show_r( tree
, ptnode
->right
, lvl
+1, p_show
);
501 static void aatree_show( aatree
*tree
, aatree_ptr t
, void(*p_show
)(void *data
))
503 if( t
!= AATREE_PTR_NIL
)
505 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
506 aatree_show( tree
, ptnode
->left
, p_show
);
507 void *data
= aatree_get_data( tree
, t
);
509 for( int i
=0; i
<ptnode
->level
; i
++ )
514 printf( " (%d) \n", t
);
516 aatree_show( tree
, ptnode
->right
, p_show
);
520 static void aatree_show_counts( aatree
*tree
, aatree_ptr t
, int lvl
, int *ln
,
522 void(*p_show
)(void *data
), int show
)
526 if( t
== AATREE_PTR_NIL
) return;
528 aatree_node
*ptnode
= aatree_get_node( tree
, t
);
529 void *data
= aatree_get_data( tree
, t
);
531 aatree_show_counts( tree
, ptnode
->left
, lvl
+1, ln
, err
, p_show
, show
);
533 if( show
) printf( " %03d| ", *ln
);
537 for( int i
=0; i
<lvl
; i
++ )
544 if( ptnode
->left
!= AATREE_PTR_NIL
&& ptnode
->right
!= AATREE_PTR_NIL
)
546 if( ptnode
->left
!= AATREE_PTR_NIL
&& ptnode
->right
== AATREE_PTR_NIL
)
548 if( ptnode
->left
== AATREE_PTR_NIL
&& ptnode
->right
!= AATREE_PTR_NIL
)
551 printf( " (%d, %d, parent: %d. V: %d, level: %d) \n", t
,
552 ptnode
->count
, ptnode
->parent
,
553 aatree_verify( tree
, t
), ptnode
->level
);
556 if( !aatree_verify( tree
, t
) )
563 aatree_show_counts( tree
, ptnode
->right
, lvl
+1, ln
, err
, p_show
, show
);
566 #endif /* VG_STORE_H */