LMMS
Loading...
Searching...
No Matches
btree.c
Go to the documentation of this file.
1/*
2 Copyright 2011-2014 David Robillard <http://drobilla.net>
3
4 Permission to use, copy, modify, and/or distribute this software for any
5 purpose with or without fee is hereby granted, provided that the above
6 copyright notice and this permission notice appear in all copies.
7
8 THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15*/
16
17#include <assert.h>
18#include <stdint.h>
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22
23#include "zix/btree.h"
24
25// #define ZIX_BTREE_DEBUG 1
26
27#define ZIX_BTREE_PAGE_SIZE 4096
28#define ZIX_BTREE_NODE_SPACE (ZIX_BTREE_PAGE_SIZE - 2 * sizeof(uint16_t))
29#define ZIX_BTREE_LEAF_VALS ((ZIX_BTREE_NODE_SPACE / sizeof(void*)) - 1)
30#define ZIX_BTREE_INODE_VALS (ZIX_BTREE_LEAF_VALS / 2)
31
32struct ZixBTreeImpl {
36 void* cmp_data;
37 size_t size;
38 unsigned height;
39};
40
41struct ZixBTreeNodeImpl {
44 // On 64-bit we rely on some padding here to get page-sized nodes
45 void* vals[ZIX_BTREE_INODE_VALS]; // ZIX_BTREE_LEAF_VALS for leaves
46 ZixBTreeNode* children[ZIX_BTREE_INODE_VALS + 1]; // Nonexistent for leaves
47};
48
49typedef struct {
50 ZixBTreeNode* node;
51 unsigned index;
53
54struct ZixBTreeIterImpl {
55 unsigned level;
56 ZixBTreeIterFrame stack[];
57};
58
59#ifdef ZIX_BTREE_DEBUG
60
61ZIX_PRIVATE void
62print_node(const ZixBTreeNode* n, const char* prefix)
63{
64 printf("%s[", prefix);
65 for (uint16_t v = 0; v < n->n_vals; ++v) {
66 printf(" %lu", (uintptr_t)n->vals[v]);
67 }
68 printf(" ]\n");
69}
70
71ZIX_PRIVATE void
72print_tree(const ZixBTreeNode* parent, const ZixBTreeNode* node, int level)
73{
74 if (node) {
75 if (!parent) {
76 printf("TREE {\n");
77 }
78 for (int i = 0; i < level + 1; ++i) {
79 printf(" ");
80 }
81 print_node(node, "");
82 if (!node->is_leaf) {
83 for (uint16_t i = 0; i < node->n_vals + 1; ++i) {
84 print_tree(node, node->children[i], level + 1);
85 }
86 }
87 if (!parent) {
88 printf("}\n");
89 }
90 }
91}
92
93#endif // ZIX_BTREE_DEBUG
94
95ZIX_PRIVATE ZixBTreeNode*
96zix_btree_node_new(const bool leaf)
97{
100 if (node) {
101 node->is_leaf = leaf;
102 node->n_vals = 0;
103 }
104 return node;
105}
106
107ZIX_API ZixBTree*
109 void* const cmp_data,
110 const ZixDestroyFunc destroy)
111{
112 ZixBTree* t = (ZixBTree*)malloc(sizeof(ZixBTree));
113 if (t) {
114 t->root = zix_btree_node_new(true);
115 t->destroy = destroy;
116 t->cmp = cmp;
117 t->cmp_data = cmp_data;
118 t->size = 0;
119 t->height = 1;
120 if (!t->root) {
121 free(t);
122 return NULL;
123 }
124 }
125 return t;
126}
127
128ZIX_PRIVATE void
130{
131 if (n) {
132 if (t->destroy) {
133 for (uint16_t i = 0; i < n->n_vals; ++i) {
134 t->destroy(n->vals[i]);
135 }
136 }
137 if (!n->is_leaf) {
138 for (uint16_t i = 0; i < n->n_vals + 1; ++i) {
139 zix_btree_free_rec(t, n->children[i]);
140 }
141 }
142 free(n);
143 }
144}
145
146ZIX_API void
148{
149 if (t) {
150 zix_btree_free_rec(t, t->root);
151 free(t);
152 }
153}
154
155ZIX_API size_t
157{
158 return t->size;
159}
160
161ZIX_PRIVATE uint16_t
163{
165}
166
167ZIX_PRIVATE uint16_t
169{
170 return ((zix_btree_max_vals(node) + 1) / 2) - 1;
171}
172
174ZIX_PRIVATE void
175zix_btree_ainsert(void** const array,
176 const uint16_t n,
177 const uint16_t i,
178 void* const e)
179{
180 memmove(array + i + 1, array + i, (n - i) * sizeof(e));
181 array[i] = e;
182}
183
185ZIX_PRIVATE void*
186zix_btree_aerase(void** const array, const uint16_t n, const uint16_t i)
187{
188 void* const ret = array[i];
189 memmove(array + i, array + i + 1, (n - i) * sizeof(ret));
190 return ret;
191}
192
194ZIX_PRIVATE ZixBTreeNode*
196 const uint16_t i,
197 ZixBTreeNode* const lhs)
198{
199 assert(lhs->n_vals == zix_btree_max_vals(lhs));
200 assert(n->n_vals < ZIX_BTREE_INODE_VALS);
201 assert(i < n->n_vals + 1);
202 assert(n->children[i] == lhs);
203
204 const uint16_t max_n_vals = zix_btree_max_vals(lhs);
206 if (!rhs) {
207 return NULL;
208 }
209
210 // LHS and RHS get roughly half, less the middle value which moves up
211 lhs->n_vals = max_n_vals / 2;
212 rhs->n_vals = max_n_vals - lhs->n_vals - 1;
213
214 // Copy large half of values from LHS to new RHS node
215 memcpy(rhs->vals,
216 lhs->vals + lhs->n_vals + 1,
217 rhs->n_vals * sizeof(void*));
218
219 // Copy large half of children from LHS to new RHS node
220 if (!lhs->is_leaf) {
221 memcpy(rhs->children,
222 lhs->children + lhs->n_vals + 1,
223 (rhs->n_vals + 1) * sizeof(ZixBTreeNode*));
224 }
225
226 // Move middle value up to parent
227 zix_btree_ainsert(n->vals, n->n_vals, i, lhs->vals[lhs->n_vals]);
228
229 // Insert new RHS node in parent at position i
230 zix_btree_ainsert((void**)n->children, ++n->n_vals, i + 1, rhs);
231
232 return rhs;
233}
234
236ZIX_PRIVATE uint16_t
238 const ZixBTreeNode* const n,
239 const void* const e,
240 bool* const equal)
241{
242 uint16_t first = 0;
243 uint16_t len = n->n_vals;
244 while (len > 0) {
245 const uint16_t half = len >> 1;
246 const uint16_t i = first + half;
247 const int cmp = t->cmp(n->vals[i], e, t->cmp_data);
248 if (cmp == 0) {
249 *equal = true;
250 len = half; // Keep searching for wildcard matches
251 } else if (cmp < 0) {
252 const uint16_t chop = half + 1;
253 first += chop;
254 len -= chop;
255 } else {
256 len = half;
257 }
258 }
259 assert(!*equal || t->cmp(n->vals[first], e, t->cmp_data) == 0);
260 return first;
261}
262
263ZIX_API ZixStatus
264zix_btree_insert(ZixBTree* const t, void* const e)
265{
266 ZixBTreeNode* parent = NULL; // Parent of n
267 ZixBTreeNode* n = t->root; // Current node
268 uint16_t i = 0; // Index of n in parent
269 while (n) {
270 if (n->n_vals == zix_btree_max_vals(n)) {
271 // Node is full, split to ensure there is space for a leaf split
272 if (!parent) {
273 // Root is full, grow tree upwards
274 if (!(parent = zix_btree_node_new(false))) {
275 return ZIX_STATUS_NO_MEM;
276 }
277 t->root = parent;
278 parent->children[0] = n;
279 ++t->height;
280 }
281
283 if (!rhs) {
284 return ZIX_STATUS_NO_MEM;
285 }
286
287 const int cmp = t->cmp(parent->vals[i], e, t->cmp_data);
288 if (cmp == 0) {
289 return ZIX_STATUS_EXISTS;
290 } else if (cmp < 0) {
291 // Move to new RHS
292 n = rhs;
293 ++i;
294 }
295 }
296
297 assert(!parent || parent->children[i] == n);
298
299 bool equal = false;
300 i = zix_btree_node_find(t, n, e, &equal);
301 if (equal) {
302 return ZIX_STATUS_EXISTS;
303 } else if (!n->is_leaf) {
304 // Descend to child node left of value
305 parent = n;
306 n = n->children[i];
307 } else {
308 // Insert into internal node
309 zix_btree_ainsert(n->vals, n->n_vals++, i, e);
310 break;
311 }
312 }
313
314 ++t->size;
315
316 return ZIX_STATUS_SUCCESS;
317}
318
319ZIX_PRIVATE ZixBTreeIter*
321{
322 const size_t s = t->height * sizeof(ZixBTreeIterFrame);
323 ZixBTreeIter* const i = (ZixBTreeIter*)malloc(sizeof(ZixBTreeIter) + s);
324 if (i) {
325 i->level = 0;
326 }
327 return i;
328}
329
330ZIX_PRIVATE void
332 ZixBTreeNode* const n,
333 const uint16_t i)
334{
335 if (ti) {
336 ti->stack[ti->level].node = n;
337 ti->stack[ti->level].index = i;
338 }
339}
340
341ZIX_PRIVATE bool
343{
344 assert(n->n_vals >= zix_btree_min_vals(n));
345 return n->n_vals == zix_btree_min_vals(n);
346}
347
349ZIX_PRIVATE ZixBTreeNode*
351{
352 ZixBTreeNode* const lhs = parent->children[i];
353 ZixBTreeNode* const rhs = parent->children[i + 1];
354
355 // Move parent value to end of LHS
356 lhs->vals[lhs->n_vals++] = parent->vals[i];
357
358 // Move first child pointer from RHS to end of LHS
359 if (!lhs->is_leaf) {
361 (void**)rhs->children, rhs->n_vals, 0);
362 }
363
364 // Move first value in RHS to parent
365 parent->vals[i] = zix_btree_aerase(rhs->vals, --rhs->n_vals, 0);
366
367 return lhs;
368}
369
371ZIX_PRIVATE ZixBTreeNode*
373{
374 ZixBTreeNode* const lhs = parent->children[i - 1];
375 ZixBTreeNode* const rhs = parent->children[i];
376
377 // Prepend parent value to RHS
378 zix_btree_ainsert(rhs->vals, rhs->n_vals++, 0, parent->vals[i - 1]);
379
380 // Move last child pointer from LHS and prepend to RHS
381 if (!lhs->is_leaf) {
382 zix_btree_ainsert((void**)rhs->children,
383 rhs->n_vals,
384 0,
385 lhs->children[lhs->n_vals]);
386 }
387
388 // Move last value from LHS to parent
389 parent->vals[i - 1] = lhs->vals[--lhs->n_vals];
390
391 return rhs;
392}
393
395ZIX_PRIVATE ZixBTreeNode*
397{
398 ZixBTreeNode* const lhs = n->children[i];
399 ZixBTreeNode* const rhs = n->children[i + 1];
400
401 assert(zix_btree_node_is_minimal(n->children[i]));
402 assert(lhs->n_vals + rhs->n_vals < zix_btree_max_vals(lhs));
403
404 // Move parent value to end of LHS
405 lhs->vals[lhs->n_vals++] = zix_btree_aerase(n->vals, n->n_vals, i);
406
407 // Erase corresponding child pointer (to RHS) in parent
408 zix_btree_aerase((void**)n->children, n->n_vals, i + 1);
409
410 // Add everything from RHS to end of LHS
411 memcpy(lhs->vals + lhs->n_vals, rhs->vals, rhs->n_vals * sizeof(void*));
412 if (!lhs->is_leaf) {
413 memcpy(lhs->children + lhs->n_vals,
414 rhs->children,
415 (rhs->n_vals + 1) * sizeof(void*));
416 }
417 lhs->n_vals += rhs->n_vals;
418
419 if (--n->n_vals == 0) {
420 // Root is now empty, replace it with its only child
421 assert(n == t->root);
422 t->root = lhs;
423 free(n);
424 }
425
426 free(rhs);
427 return lhs;
428}
429
431ZIX_PRIVATE void*
433{
434 while (!n->is_leaf) {
435 if (zix_btree_node_is_minimal(n->children[0])) {
436 // Leftmost child is minimal, must expand
437 if (!zix_btree_node_is_minimal(n->children[1])) {
438 // Child's right sibling has at least one key to steal
440 } else {
441 // Both child and right sibling are minimal, merge
442 n = zix_btree_merge(t, n, 0);
443 }
444 } else {
445 n = n->children[0];
446 }
447 }
448
449 return zix_btree_aerase(n->vals, --n->n_vals, 0);
450}
451
453ZIX_PRIVATE void*
455{
456 while (!n->is_leaf) {
457 if (zix_btree_node_is_minimal(n->children[n->n_vals])) {
458 // Leftmost child is minimal, must expand
459 if (!zix_btree_node_is_minimal(n->children[n->n_vals - 1])) {
460 // Child's left sibling has at least one key to steal
461 n = zix_btree_rotate_right(n, n->n_vals);
462 } else {
463 // Both child and left sibling are minimal, merge
464 n = zix_btree_merge(t, n, n->n_vals - 1);
465 }
466 } else {
467 n = n->children[n->n_vals];
468 }
469 }
470
471 return n->vals[--n->n_vals];
472}
473
474ZIX_API ZixStatus
476 const void* const e,
477 void** const out,
478 ZixBTreeIter** const next)
479{
480 ZixBTreeNode* n = t->root;
481 ZixBTreeIter* ti = NULL;
482 const bool user_iter = next && *next;
483 if (next) {
484 if (!*next && !(*next = zix_btree_iter_new(t))) {
485 return ZIX_STATUS_NO_MEM;
486 }
487 ti = *next;
488 ti->level = 0;
489 }
490
491 while (true) {
492 /* To remove in a single walk down, the tree is adjusted along the way
493 so that the current node always has at least one more value than the
494 minimum required in general. Thus, there is always room to remove
495 without adjusting on the way back up. */
496 assert(n == t->root || !zix_btree_node_is_minimal(n));
497
498 bool equal = false;
499 const uint16_t i = zix_btree_node_find(t, n, e, &equal);
501 if (n->is_leaf) {
502 if (equal) {
503 // Found in leaf node
504 *out = zix_btree_aerase(n->vals, --n->n_vals, i);
505 if (ti && i == n->n_vals) {
506 if (i == 0) {
507 ti->stack[ti->level = 0].node = NULL;
508 } else {
509 --ti->stack[ti->level].index;
511 }
512 }
513 --t->size;
514 return ZIX_STATUS_SUCCESS;
515 } else {
516 // Not found in leaf node, or tree
517 if (ti && !user_iter) {
519 *next = NULL;
520 }
522 }
523 } else if (equal) {
524 // Found in internal node
525 if (!zix_btree_node_is_minimal(n->children[i])) {
526 // Left child can remove without merge
527 *out = n->vals[i];
528 n->vals[i] = zix_btree_remove_max(t, n->children[i]);
529 --t->size;
530 return ZIX_STATUS_SUCCESS;
531 } else if (!zix_btree_node_is_minimal(n->children[i + 1])) {
532 // Right child can remove without merge
533 *out = n->vals[i];
534 n->vals[i] = zix_btree_remove_min(t, n->children[i + 1]);
535 --t->size;
536 return ZIX_STATUS_SUCCESS;
537 } else {
538 // Both preceding and succeeding child are minimal
539 n = zix_btree_merge(t, n, i);
540 }
541 } else {
542 // Not found in internal node, key is in/under children[i]
543 if (zix_btree_node_is_minimal(n->children[i])) {
544 if (i > 0 && !zix_btree_node_is_minimal(n->children[i - 1])) {
545 // Steal a key from child's left sibling
547 } else if (i < n->n_vals &&
548 !zix_btree_node_is_minimal(n->children[i + 1])) {
549 // Steal a key from child's right sibling
551 } else {
552 // Both child's siblings are minimal, merge them
553 if (i < n->n_vals) {
554 n = zix_btree_merge(t, n, i);
555 } else {
556 n = zix_btree_merge(t, n, i - 1);
557 if (ti) {
558 --ti->stack[ti->level].index;
559 }
560 }
561 }
562 } else {
563 n = n->children[i];
564 }
565 }
566 if (ti) {
567 ++ti->level;
568 }
569 }
570
571 assert(false); // Not reached
572 return ZIX_STATUS_ERROR;
573}
574
575ZIX_API ZixStatus
577 const void* const e,
578 ZixBTreeIter** const ti)
579{
580 ZixBTreeNode* n = t->root;
581 if (!(*ti = zix_btree_iter_new(t))) {
582 return ZIX_STATUS_NO_MEM;
583 }
584
585 while (n) {
586 bool equal = false;
587 const uint16_t i = zix_btree_node_find(t, n, e, &equal);
588
590
591 if (equal) {
592 return ZIX_STATUS_SUCCESS;
593 } else if (n->is_leaf) {
594 break;
595 } else {
596 ++(*ti)->level;
597 n = n->children[i];
598 }
599 }
600
602 *ti = NULL;
604}
605
606ZIX_API ZixStatus
608 const void* const e,
609 ZixBTreeIter** const ti)
610{
611 if (!t) {
612 *ti = NULL;
613 return ZIX_STATUS_BAD_ARG;
614 }
615
616 ZixBTreeNode* n = t->root;
617 bool found = false;
618 unsigned found_level = 0;
619 if (!(*ti = zix_btree_iter_new(t))) {
620 return ZIX_STATUS_NO_MEM;
621 }
622
623 while (n) {
624 bool equal = false;
625 const uint16_t i = zix_btree_node_find(t, n, e, &equal);
626
628
629 if (equal) {
630 found_level = (*ti)->level;
631 found = true;
632 }
633
634 if (n->is_leaf) {
635 break;
636 } else {
637 ++(*ti)->level;
638 n = n->children[i];
639 assert(n);
640 }
641 }
642
643 const ZixBTreeIterFrame* const frame = &(*ti)->stack[(*ti)->level];
644 if (frame->index == frame->node->n_vals) {
645 if (found) {
646 // Found on a previous level but went too far
647 (*ti)->level = found_level;
648 } else {
649 // Reached end (key is greater than everything in tree)
650 (*ti)->stack[0].node = NULL;
651 }
652 }
653
654 return ZIX_STATUS_SUCCESS;
655}
656
657ZIX_API void*
659{
660 const ZixBTreeIterFrame* const frame = &ti->stack[ti->level];
661 assert(frame->index < frame->node->n_vals);
662 return frame->node->vals[frame->index];
663}
664
665ZIX_API ZixBTreeIter*
667{
669 if (!i) {
670 return NULL;
671 } else if (t->size == 0) {
672 i->stack[0].node = NULL;
673 } else {
674 ZixBTreeNode* n = t->root;
675 i->stack[0].node = n;
676 i->stack[0].index = 0;
677 while (!n->is_leaf) {
678 n = n->children[0];
679 ++i->level;
680 i->stack[i->level].node = n;
681 i->stack[i->level].index = 0;
682 }
683 }
684 return i;
685}
686
687ZIX_API bool
689{
690 return !i || i->stack[0].node == NULL;
691}
692
693ZIX_API void
695{
696 ZixBTreeIterFrame* f = &i->stack[i->level];
697 if (f->node->is_leaf) {
698 // Leaf, move right
699 assert(f->index < f->node->n_vals);
700 if (++f->index == f->node->n_vals) {
701 // Reached end of leaf, move up
702 f = &i->stack[i->level];
703 while (i->level > 0 && f->index == f->node->n_vals) {
704 f = &i->stack[--i->level];
705 assert(f->index <= f->node->n_vals);
706 }
707
708 if (f->index == f->node->n_vals) {
709 // Reached end of tree
710 assert(i->level == 0);
711 f->node = NULL;
712 f->index = 0;
713 }
714 }
715 } else {
716 // Internal node, move down to next child
717 assert(f->index < f->node->n_vals);
718 ZixBTreeNode* child = f->node->children[++f->index];
719
720 f = &i->stack[++i->level];
721 f->node = child;
722 f->index = 0;
723
724 // Move down and left until we hit a leaf
725 while (!f->node->is_leaf) {
726 child = f->node->children[0];
727 f = &i->stack[++i->level];
728 f->node = child;
729 f->index = 0;
730 }
731 }
732}
733
734ZIX_API void
736{
737 free(i);
738}
#define NULL
Definition CarlaBridgeFormat.cpp:30
assert(0)
* e
Definition inflate.c:1404
struct huft * t
Definition inflate.c:943
unsigned v[N_MAX]
Definition inflate.c:1584
register unsigned i
Definition inflate.c:1575
unsigned s
Definition inflate.c:1555
unsigned f
Definition inflate.c:1572
static uintptr_t parent
Definition pugl.h:1644
void(* ZixDestroyFunc)(void *ptr)
Definition common.h:128
size_t zix_btree_size(const ZixBTree *const t)
Definition btree.c:200
ZixBTree * zix_btree_new(const ZixComparator cmp, const void *const cmp_data, const ZixDestroyFunc destroy)
Definition btree.c:144
void zix_btree_iter_increment(ZixBTreeIter *const i)
Definition btree.c:892
ZixStatus zix_btree_lower_bound(const ZixBTree *const t, const void *const e, ZixBTreeIter **const ti)
Definition btree.c:752
struct ZixBTreeImpl ZixBTree
Definition btree.h:39
ZixBTreeIter * zix_btree_begin(const ZixBTree *const t)
Definition btree.c:819
bool zix_btree_iter_is_end(const ZixBTreeIter *const i)
Definition btree.c:867
void zix_btree_free(ZixBTree *const t)
Definition btree.c:191
struct ZixBTreeIterImpl ZixBTreeIter
Definition btree.h:52
ZixStatus zix_btree_remove(ZixBTree *const t, const void *const e, void **const out, ZixBTreeIter **const next)
Definition btree.c:597
ZixStatus
Definition common.h:81
void * zix_btree_get(const ZixBTreeIter *const ti)
Definition btree.c:810
struct ZixBTreeNodeImpl ZixBTreeNode
Definition btree.h:44
ZixStatus zix_btree_find(const ZixBTree *const t, const void *const e, ZixBTreeIter **const ti)
Definition btree.c:719
ZixStatus zix_btree_insert(ZixBTree *const t, void *const e)
Definition btree.c:345
int(* ZixComparator)(const void *a, const void *b, const void *user_data)
Definition common.h:116
void zix_btree_iter_free(ZixBTreeIter *const i)
Definition btree.c:933
@ ZIX_STATUS_EXISTS
Definition common.h:86
@ ZIX_STATUS_BAD_ARG
Definition common.h:87
@ ZIX_STATUS_NOT_FOUND
Definition common.h:85
@ ZIX_STATUS_ERROR
Definition common.h:83
@ ZIX_STATUS_NO_MEM
Definition common.h:84
@ ZIX_STATUS_SUCCESS
Definition common.h:82
static ZixBTreeNode * zix_btree_rotate_left(ZixBTreeNode *const parent, const unsigned i)
Definition btree.c:436
static void * zix_btree_remove_max(ZixBTree *const t, ZixBTreeNode *n)
Definition btree.c:576
static void zix_btree_free_rec(ZixBTree *const t, ZixBTreeNode *const n)
Definition btree.c:165
#define ZIX_BTREE_LEAF_VALS
Definition btree.c:32
#define ZIX_BTREE_INODE_VALS
Definition btree.c:33
static ZixBTreeIter * zix_btree_iter_new(const ZixBTree *const t)
Definition btree.c:405
static ZixBTreeNode * zix_btree_node_new(const bool leaf)
Definition btree.c:113
static ZixBTreeNode * zix_btree_split_child(ZixBTreeNode *const n, const unsigned i, ZixBTreeNode *const lhs)
Definition btree.c:239
static ZixBTreeNode * zix_btree_merge(ZixBTree *const t, ZixBTreeNode *const n, const unsigned i)
Definition btree.c:504
static void zix_btree_ainsert(void **const array, const unsigned n, const unsigned i, void *const e)
Definition btree.c:219
static unsigned zix_btree_node_find(const ZixBTree *const t, const ZixBTreeNode *const n, const void *const e, bool *const equal)
Definition btree.c:313
static uint16_t zix_btree_max_vals(const ZixBTreeNode *const node)
Definition btree.c:206
#define ZIX_BTREE_PAGE_SIZE
Definition btree.c:28
static uint16_t zix_btree_min_vals(const ZixBTreeNode *const node)
Definition btree.c:212
static void * zix_btree_remove_min(ZixBTree *const t, ZixBTreeNode *n)
Definition btree.c:554
static bool zix_btree_node_is_minimal(ZixBTreeNode *const n)
Definition btree.c:428
static ZixBTreeNode * zix_btree_rotate_right(ZixBTreeNode *const parent, const unsigned i)
Definition btree.c:470
static void zix_btree_iter_set_frame(ZixBTreeIter *const ti, ZixBTreeNode *const n, const unsigned i)
Definition btree.c:417
static void * zix_btree_aerase(void **const array, const unsigned n, const unsigned i)
Definition btree.c:230
float out
Definition lilv_test.c:1461
unsigned short uint16_t
Definition mid.cpp:99
Definition btree.c:35
unsigned height
Number of levels, i.e. root only has height 1.
Definition btree.c:41
const void * cmp_data
Definition btree.c:39
ZixDestroyFunc destroy
Definition btree.c:37
ZixBTreeNode * root
Definition btree.c:36
ZixComparator cmp
Definition btree.c:38
size_t size
Definition btree.c:40
Definition btree.c:65
unsigned index
Definition btree.c:67
ZixBTreeNode * node
Definition btree.c:66
Definition btree.c:70
unsigned level
Current level in stack.
Definition btree.c:72
ZixBTreeIterFrame stack[]
Position stack.
Definition btree.c:73
Definition btree.c:44
void * vals[ZIX_BTREE_LEAF_VALS]
Definition btree.c:50
ZixBTreeNode * children[ZIX_BTREE_INODE_VALS+1]
Definition btree.c:55
uint16_t n_vals
Definition btree.c:46
uint16_t is_leaf
Definition btree.c:45
int n
Definition crypt.c:458
memcpy(hh, h, RAND_HEAD_LEN)
char * malloc()