/* take a _node_t, value, and depth (zero means root) */ _node_t *_find(_node_t *o, uint32_t v, size_t d) { if (_is_leaf(o)) { return VALUE(o) == v ? o : NULL; } if (!_has_children(o)) { return NULL; } return _find(_children(o) + _idx8(v, d), v, d + 1); }
static int _weight_recursive(_node_t *o) { if (_is_leaf(o)) { return 1; } if (!_has_children(o)) { return 0; } int acc = 0; for (size_t i = 0; i != 8; ++i) { acc += _weight_recursive(_children(o) + i); } return acc; }
static int _depth_recursive(_node_t *o) { SPIT(std::cout << std::endl); if (_is_leaf(o)) return 0; if (!_has_children(o)) return 0; int acc = 0; for (size_t i = 0; i != 8; ++i) { acc = _imax(acc, _depth_recursive(_children(o) + i)); } return 1 + acc; }
void _split(bp_node * p, bp_node * & n1, bp_node * & n2) { n1 = p; n2 = new bp_node; n2->key[0] = p->key[2]; n2->key[1] = p->key[3]; n1->n = n2->n = 2; if (_is_leaf(p)) { n2->next = n1->next; n1->next = n2; } else { n2->ptr[0] = n1->ptr[2]; n2->ptr[1] = n1->ptr[3]; n2->ptr[0]->parent = n2->ptr[1]->parent = n2; } }
void _bp_print(bp_node * root) { for (int i = 0; i < root->n; ++i) { std::cout << root->key[i]; if (i < root->n - 1) { std::cout << '|'; } } if (!_is_leaf(root)) { std::cout << '('; for (int i = 0; i < root->n - 1; ++i) { _bp_print(root->ptr[i]); std::cout << ','; } _bp_print(root->ptr[root->n-1]); std::cout << ')'; } }
bool _find(bp_node * root, int k, bp_node * & q, int & i) { bp_node * p = root; int j = 0; while (true) { for (j = 0; j < p->n; ++j) { if (p->key[j] >= k) { break; } } if (_is_leaf(p)) { break; } else { p = p->ptr[j]; } } q = p; i = j; return q->key[i] == k; }
/* take a _node_t, value, and depth (zero means root) */ _node_t *_insert(_node_t *o, uint32_t v, size_t d) { /* at level 0, shift 21 bits */ /* at level 7, shift 0 bits */ if (_has_children(o)) { SPIT(std::cout); return _insert(CHILDREN(o) + _idx8(v, d), v, d + 1); } if (!_is_leaf(o)) { /* unused _node_t */ _leaf_set(o); _value_set(o, v); return o; } /* else occupied leaf */ if (UINT24(v) == VALUE(o)) { /* same value */ return o; } /* else different value */ _leaf_clear(o); uint32_t w = VALUE(o); // save old value VALUE(o) = 0; // clear value CHILDREN(o) = _children_new(); for (size_t i = 0; i < 8; ++i) { (CHILDREN(o) + i)->parent_ = o; } /* insert old value */ _insert(_children(o) + _idx8(w, d), w, d + 1); /* recurse with given value */ return _insert(_children(o) + _idx8(v, d), v, d + 1); }
void _process_weak_node(bp_tree * tree, bp_node * p) { int i = _index_of_child(p); bp_node * parent = p->parent; if (i < parent->n - 1) { // has right sibling bp_node * rsib = parent->ptr[i+1]; if (rsib->n == 3) { // right sibling has enough children // move right sibling's left child to p p->key[1] = rsib->key[0]; p->ptr[1] = rsib->ptr[0]; if (p->ptr[1]) { p->ptr[1]->parent = p; } ++p->n; // update p's max key in parent int old_max = p->key[0], new_max = p->key[1]; _update_key(parent, old_max, new_max); // fill blank location in rsib rsib->key[0] = rsib->key[1]; rsib->key[1] = rsib->key[2]; rsib->ptr[0] = rsib->ptr[1]; rsib->ptr[1] = rsib->ptr[2]; --rsib->n; } else { // no enough children in right sibling // move data in p to right sibling for (int j = rsib->n; j > 0; --j) { rsib->key[j] = rsib->key[j-1]; rsib->ptr[j] = rsib->ptr[j-1]; } rsib->key[0] = p->key[0]; rsib->ptr[0] = p->ptr[0]; if (rsib->ptr[0]) { rsib->ptr[0]->parent = rsib; } ++rsib->n; // remove p then update key in parent, and don't forget leaf links if (_is_leaf(p)) { bp_node ** handle = _get_handle(tree, p); *handle = rsib; } delete p; for (int j = i + 1; j < parent->n; ++j) { parent->key[j-1] = parent->key[j]; parent->ptr[j-1] = parent->ptr[j]; } --parent->n; } } else { // p has no right sibling, just left bp_node * Lsib = parent->ptr[i-1]; if (Lsib->n == 3) { // left sibling has enouph children // move left sibling's right child to p p->key[1] = p->key[0]; p->ptr[1] = p->ptr[0]; p->key[0] = Lsib->key[Lsib->n-1]; p->ptr[0] = Lsib->ptr[Lsib->n-1]; if (p->ptr[0]) { p->ptr[0]->parent = p; } ++p->n; // update left sibling int old_max = Lsib->key[Lsib->n-1]; int new_max = Lsib->key[Lsib->n-2]; _update_key(parent, old_max, new_max); --Lsib->n; } else { // no enough children in left sibling // move data in p to left sibling Lsib->key[Lsib->n] = p->key[0]; Lsib->ptr[Lsib->n] = p->ptr[0]; if (p->ptr[0]) { p->ptr[0]->parent = Lsib; } ++Lsib->n; // update key of left sibling in parent int old_key = Lsib->key[Lsib->n-2]; int new_key = Lsib->key[Lsib->n-1]; _update_key(parent, old_key, new_key); // drop p then update key in parent, and don't forget leaf links if (_is_leaf(p)) { Lsib->next = p->next; } delete p; for (int j = i + 1; j < parent->n; ++j) { parent->key[j-1] = parent->key[j]; parent->ptr[j-1] = parent->ptr[j]; } --parent->n; } } }