aatrees
[vg.git] / src / vg / vg_store.h
1 #ifndef VG_STORE_H
2 #define VG_STORE_H
3
4 typedef struct aatree aatree;
5 typedef struct aatree_node aatree_node;
6
7 typedef u32 aatree_ptr;
8 #define AATREE_PTR_NIL 0xffffffff
9
10 struct aatree
11 {
12 u32 offset, stride; /* distance between elements */
13 void *base;
14
15 int (*p_cmp)( void *a, void *b );
16 int (*p_cmpv)( void *a, void *v );
17 };
18
19 struct aatree_node
20 {
21 aatree_ptr left, right;
22 u32 level, count;
23 };
24
25 static void *aatree_get_data( aatree *tree, aatree_ptr t )
26 {
27 return tree->base + tree->stride*t;
28 }
29
30 static aatree_node *aatree_get_node( aatree *tree, aatree_ptr t )
31 {
32 return tree->base + tree->stride*t + tree->offset;
33 }
34
35 static void aatree_recount( aatree *tree, aatree_ptr n )
36 {
37 aatree_node *pnode = aatree_get_node( tree, n );
38 pnode->count = 1;
39
40 if( pnode->left != AATREE_PTR_NIL )
41 pnode->count += aatree_get_node( tree, pnode->left )->count;
42
43 if( pnode->right != AATREE_PTR_NIL )
44 pnode->count += aatree_get_node( tree, pnode->right )->count;
45 }
46
47 /* . .
48 * | |
49 * L <- T L -> T
50 * / \ \ -> / / \
51 * A B R A B R
52 */
53 static aatree_ptr aatree_skew( aatree *tree, u32 t )
54 {
55 if( t == AATREE_PTR_NIL ) return t;
56
57 aatree_node *ptnode = aatree_get_node( tree, t );
58 if( ptnode->left == AATREE_PTR_NIL ) return t;
59
60 aatree_node *plnode = aatree_get_node( tree, ptnode->left );
61 if( plnode->level == ptnode->level )
62 {
63 aatree_ptr l = ptnode->left;
64 ptnode->left = plnode->right;
65 plnode->right = t;
66
67 aatree_recount( tree, t );
68 aatree_recount( tree, l );
69
70 return l;
71 }
72
73 return t;
74 }
75
76 /* . .
77 * | |
78 * T -> R -> X -> R
79 * / / / \
80 * A B T X
81 * / \
82 * A B
83 */
84 static aatree_ptr aatree_split( aatree *tree, aatree_ptr t )
85 {
86 if( t == AATREE_PTR_NIL ) return t;
87
88 aatree_node *ptnode = aatree_get_node( tree, t );
89 if( ptnode->right == AATREE_PTR_NIL ) return t;
90
91 aatree_node *prnode = aatree_get_node( tree, ptnode->right );
92 if( prnode->right == AATREE_PTR_NIL ) return t;
93
94 aatree_node *prrnode = aatree_get_node( tree, prnode->right );
95 if( ptnode->level == prrnode->level )
96 {
97 aatree_ptr r = ptnode->right;
98 ptnode->right = prnode->left;
99 prnode->left = t;
100 prnode->level ++;
101
102 aatree_recount( tree, t );
103 aatree_recount( tree, r );
104
105 return r;
106 }
107
108 return t;
109 }
110
111 static aatree_ptr aatree_insert( aatree *tree, aatree_ptr t, aatree_ptr x )
112 {
113 aatree_node *pxnode = aatree_get_node( tree, x );
114
115 if( t == AATREE_PTR_NIL )
116 {
117 pxnode->left = AATREE_PTR_NIL;
118 pxnode->right = AATREE_PTR_NIL;
119 pxnode->level = 0;
120 pxnode->count = 1;
121 return x;
122 }
123
124 aatree_node *ptnode = aatree_get_node( tree, t );
125 int cmp_result = tree->p_cmp( aatree_get_data( tree, t ),
126 aatree_get_data( tree, x ) );
127
128 ptnode->count ++;
129
130 if( cmp_result <= 0 )
131 ptnode->left = aatree_insert( tree, ptnode->left, x );
132 else
133 ptnode->right = aatree_insert( tree, ptnode->right, x );
134
135 t = aatree_skew( tree, t );
136 t = aatree_split( tree, t );
137 return t;
138 }
139
140 static aatree_ptr aatree_del( aatree *tree, aatree_ptr t, aatree_ptr x )
141 {
142 if( t == AATREE_PTR_NIL ) return t;
143 return AATREE_PTR_NIL; /*TODO*/
144 }
145
146 /*
147 * Accessors
148 */
149
150 static aatree_ptr aatree_kth( aatree *tree, aatree_ptr t, u32 k )
151 {
152 u32 i = 0;
153
154 while( t != AATREE_PTR_NIL )
155 {
156 aatree_node *ptnode = aatree_get_node( tree, t );
157
158 u32 j = i;
159 if( ptnode->left != AATREE_PTR_NIL )
160 j += aatree_get_node( tree, ptnode->left )->count;
161
162 if( j < k )
163 {
164 i = j+1;
165 t = ptnode->right;
166 }
167 else
168 {
169 if( j > k )
170 {
171 t = ptnode->left;
172 }
173 else
174 {
175 return t;
176 }
177 }
178 }
179
180 return AATREE_PTR_NIL;
181 }
182
183 static aatree_ptr aatree_ptrof( aatree *tree, aatree_ptr t, void *value )
184 {
185 while( t != AATREE_PTR_NIL )
186 {
187 int cmp_result = tree->p_cmpv( aatree_get_data( tree, t ), value );
188
189 if( cmp_result == 0 )
190 return t;
191 else
192 {
193 aatree_node *ptnode = aatree_get_node( tree, t );
194
195 if( cmp_result < 0 )
196 t = ptnode->left;
197 else
198 t = ptnode->right;
199 }
200 }
201 return t;
202 }
203
204
205 /*
206 * Debugging stuff
207 * =============================================================================
208 */
209
210 static void aatree_show_r( aatree *tree, aatree_ptr t, int lvl,
211 void(*p_show)(void *data) )
212 {
213 if( t != AATREE_PTR_NIL )
214 {
215 aatree_node *ptnode = aatree_get_node( tree, t );
216 aatree_show_r( tree, ptnode->left, lvl+1, p_show );
217
218 void *data = aatree_get_data( tree, t );
219
220 for( int i=0; i<lvl; i++ )
221 {
222 printf( " " );
223 }
224 p_show( data );
225 printf( " (%d) \n", t );
226
227 aatree_show_r( tree, ptnode->right, lvl+1, p_show );
228 }
229 }
230
231 static void aatree_show( aatree *tree, aatree_ptr t, void(*p_show)(void *data))
232 {
233 if( t != AATREE_PTR_NIL )
234 {
235 aatree_node *ptnode = aatree_get_node( tree, t );
236 aatree_show( tree, ptnode->left, p_show );
237 void *data = aatree_get_data( tree, t );
238
239 for( int i=0; i<ptnode->level; i++ )
240 {
241 printf( " " );
242 }
243 p_show( data );
244 printf( " (%d) \n", t );
245
246 aatree_show( tree, ptnode->right, p_show );
247 }
248 }
249
250 static void aatree_show_counts( aatree *tree, aatree_ptr t, int lvl, int *ln,
251 void(*p_show)(void *data) )
252 {
253 if( t == AATREE_PTR_NIL ) return;
254
255 aatree_node *ptnode = aatree_get_node( tree, t );
256 void *data = aatree_get_data( tree, t );
257
258 aatree_show_counts( tree, ptnode->left, lvl+1, ln, p_show );
259
260 printf( " %03d| ", *ln );
261 *ln = *ln +1;
262
263 for( int i=0; i<lvl; i++ )
264 {
265 printf( " " );
266 }
267
268 p_show( data );
269 printf( " (%d, %d) \n", t, ptnode->count );
270
271 aatree_show_counts( tree, ptnode->right, lvl+1, ln, p_show );
272 }
273
274 #endif /* VG_STORE_H */
275
276 #if 0
277
278 #include <stdlib.h>
279 #include <stdio.h>
280 #include <stdarg.h>
281 #include <string.h>
282 #include <stddef.h>
283 #include <math.h>
284
285 #include "vg/vg_platform.h"
286 #include "vg/vg_stdint.h"
287 #include "vg/vg_store.h"
288 #include "vg/vg_io.h"
289 #include "vg/vg_m.h"
290
291 typedef struct yoyo_t yoyo_t;
292 struct yoyo_t
293 {
294 int my_data;
295 aatree_node anode;
296 };
297
298 static void yoyo_t_show( void *_data )
299 {
300 yoyo_t *data = _data;
301 printf( "%d ", data->my_data );
302 }
303
304 static int yoyo_t_cmpv( void *_a, void *_v )
305 {
306 yoyo_t *a = _a;
307 int *b = _v;
308 return *b - a->my_data;
309 }
310
311 static int yoyo_t_cmp( void *_a, void *_b )
312 {
313 yoyo_t *a = _a, *b = _b;
314 return b->my_data - a->my_data;
315 }
316
317 int main(int argc, const char *argv[])
318 {
319 yoyo_t *allsorts = malloc( sizeof(yoyo_t) * 10000 );
320
321 aatree test;
322 test.base = allsorts;
323 test.offset = offsetof( yoyo_t, anode );
324 test.stride = sizeof( yoyo_t );
325 test.p_cmp = yoyo_t_cmp;
326 test.p_cmpv = yoyo_t_cmpv;
327
328 aatree_ptr root = AATREE_PTR_NIL;
329
330 for( int i=0; i<20; i++ )
331 {
332 yoyo_t *rando = &allsorts[i];
333 rando->my_data = vg_randf() * 10.0f;
334 root = aatree_insert( &test, root, i );
335 }
336
337 int ln=0;
338 aatree_show_counts( &test, root, 0, &ln, yoyo_t_show );
339
340 int value = 3;
341 vg_info( "Ptr of %d: %u\n", value, aatree_ptrof( &test, root, &value ) );
342
343 for( int i=0; i<20; i++ )
344 {
345 yoyo_t *v = aatree_get_data(&test,aatree_kth( &test, root, i ));
346 vg_info( "Value of [%d]: %d\n", i, v->my_data );
347 }
348
349 free( allsorts );
350 return 0;
351 }
352
353 #endif