void insert_leaf(t_node **root, m_tile tile) { /* check if the tree is empty */ if (!(*root)) { /* if true insert node as root */ t_node *node_to_insert = (t_node*)malloc(sizeof(t_node)); assert(node_to_insert != NULL); /* initialize data */ node_to_insert->left = node_to_insert->right = NULL; node_to_insert->tile = tile; /* set the root node to the new node */ *root = node_to_insert; return; } /* Check if the new tile value is less than the root tile */ if (tile->cost < (*root)->tile->cost) { /* Call recursively while there is non-NULL left leaf */ insert_leaf(&(*root)->left, tile); } /* Check if the new tile value is greater than the root tile */ else if (tile->cost > (*root)->tile->cost) { /* Call recursively while there is non-NULL right leaf */ insert_leaf(&(*root)->right, tile); } }
// color: 1 for leaf, 0 for inner static int insert_internal(rxt_node *newleaf, rxt_node *n) { // FIRST: check for common bits rxt_node *left = n->left, *right = n->right; int bits = count_common_bits(newleaf->key, left->key, rdx_min(newleaf->pos, left->pos)); int bits2 = count_common_bits(newleaf->key, right->key, rdx_min(newleaf->pos, right->pos)); if (rdx_min(bits, bits2) < n->pos) { if (bits >= bits2) return insert_leaf(newleaf, n->left, n); return insert_leaf(newleaf, n->right, n); } if (bits >= bits2) { if (left->color) return insert_leaf(newleaf, n->left, n); return insert_internal(newleaf, left); } else { if (right->color) return insert_leaf(newleaf, n->right, n); return insert_internal(newleaf, right); } return -1; // this should never happen }
CSG_Node *divide(CSG *csg, CSG_Node *state, int lprefix, CSG_Node *target) { CSG_Node *waiting = target; int waiting_lprefix = LEN_L(state) - lprefix; int is_leaf = IS_LEAF(state); //int j; /* delete */ LEN_L(state) = lprefix; if (is_leaf) { /* the leaf is converted to a node and is created a new leaf */ DEC_NLEAFS; INC_NNODES; if (target == NINDEF || LABEL(target)!=(LABEL(state) + lprefix)) { INC_NLEAFS; waiting = insert_leaf(csg, LABEL(state) + lprefix, LINDEF); } } else { INC_NNODES; if (target == NINDEF) { waiting = insert_leaf(csg, LABEL(state) + lprefix, waiting_lprefix); } LG(waiting) = (IS_INITIAL(state) ? 0 : LG(state) + LEN_L(state)); waiting->arc = state->arc; OUT(waiting) = OUT(state); OUT(state) = 0; } INS_EDGE(csg, state, waiting); return waiting; }
void build_CSG(CSG *csg, const char *s, long int size, int debug) { CSG_Node *state = INITIAL; int lprefix = 1; const char *pendent = s; CSG_Node *nextState; int offset; int cloned = FALSE; CSG_Node *node_cloned = NINDEF; int go; CSG_Node *waiting; while (*pendent != LAST_SYMBOL) { lprefix = state == INITIAL ? 1 : prefix_comu(csg, state, pendent); offset = state == INITIAL ? 0 : lprefix; if (lprefix == LEN_L(state)) { go = *(pendent + offset); nextState = NEXT(csg, state, go); pendent += offset; cloned = FALSE; if (nextState == NINDEF) { /* INSERT SUFIXES */ INC_NLEAFS; waiting = insert_leaf(csg, pendent, LINDEF); INS_EDGE(csg, state, waiting); nextState = add_suffixes(csg, state, waiting, &pendent); } else if (!GET_SOLID(csg, state, nextState) || cloned) { node_cloned = nextState; nextState = to_clone(csg, state, nextState); cloned = TRUE; } } else { if (!cloned) waiting = divide(csg, state, lprefix, NINDEF); else { waiting = divide_and_compress(csg, state , node_cloned, lprefix); cloned = FALSE; } state = arrange_link(csg, state, waiting, TRUE); offset = state == INITIAL ? 0 : lprefix; pendent += offset; INC_NLEAFS; waiting = insert_leaf(csg, pendent, LINDEF); INS_EDGE(csg, state, waiting); nextState = add_suffixes(csg, state, waiting, &pendent); } state = nextState; } // eliminate the last leaf "$" DEC_NLEAFS; }
/* * Split leaf, then insert to parent. * key: key to add after split (cursor will point leaf which is including key) * hint: hint for split * * return value: * 0 - success * < 0 - error */ static int btree_leaf_split(struct cursor *cursor, tuxkey_t key, tuxkey_t hint) { if(DEBUG_MODE_K==1) { printf("\t\t\t\t%25s[K] %25s %4d #in\n",__FILE__,__func__,__LINE__); } trace("split leaf"); struct btree *btree = cursor->btree; struct buffer_head *newbuf; newbuf = new_leaf(btree); if (IS_ERR(newbuf)) return PTR_ERR(newbuf); log_balloc(btree->sb, bufindex(newbuf), 1); struct buffer_head *leafbuf = cursor_leafbuf(cursor); tuxkey_t newkey = btree->ops->leaf_split(btree, hint, bufdata(leafbuf), bufdata(newbuf)); assert(cursor_this_key(cursor) < newkey); assert(newkey < cursor_next_key(cursor)); if (key < newkey) mark_buffer_dirty_non(newbuf); else mark_buffer_dirty_non(leafbuf); return insert_leaf(cursor, newkey, newbuf, key < newkey); }
/* Insert new leaf to next cursor position, then set cursor to new leaf */ int btree_insert_leaf(struct cursor *cursor, tuxkey_t key, struct buffer_head *leafbuf) { if(DEBUG_MODE_K==1) { printf("\t\t\t\t%25s[K] %25s %4d #in\n",__FILE__,__func__,__LINE__); } return insert_leaf(cursor, key, leafbuf, 0); }
static int insert_node (tree_s *tree, void *node, u64 key, void *rec, unint size) { FN; switch (magic(node)) { case LEAF: return insert_leaf(tree, node, key, rec, size); case BRANCH: return insert_branch(tree, node, key, rec, size); default: return qERR_BAD_BLOCK; } }
void insert_bucket (bucket_s *bucket, u32 x, u32 shift) { switch (bucket->b_type) { case EMPTY: insert_empty(bucket, x, shift); return; case NODE: insert_node(bucket, x, shift); return; case LEAF: insert_leaf(bucket, x, shift); return; default: printf("bad type %ld", bucket->b_type); return; } }
static int insert_head ( tree_s *tree, void *child, u64 key, void *rec, unint len) { FN; switch (type(child)) { case LEAF: return insert_leaf(tree, child, key, rec, len); case BRANCH: return insert_branch(tree, child, key, rec, len); default: return qERR_BAD_BLOCK; } }
/* * Split leaf, then insert to parent. * key: key to add after split (cursor will point leaf which is including key) * hint: hint for split * * return value: * 0 - success * < 0 - error */ static int btree_leaf_split(struct cursor *cursor, tuxkey_t key, tuxkey_t hint) { trace("split leaf"); struct btree *btree = cursor->btree; struct buffer_head *newbuf; newbuf = new_leaf(btree); if (IS_ERR(newbuf)) return PTR_ERR(newbuf); log_balloc(btree->sb, bufindex(newbuf), 1); struct buffer_head *leafbuf = cursor_leafbuf(cursor); tuxkey_t newkey = btree->ops->leaf_split(btree, hint, bufdata(leafbuf), bufdata(newbuf)); assert(cursor_this_key(cursor) < newkey); assert(newkey < cursor_next_key(cursor)); if (key < newkey) mark_buffer_dirty_non(newbuf); else mark_buffer_dirty_non(leafbuf); return insert_leaf(cursor, newkey, newbuf, key < newkey); }
/** * Insert or update the given value under the given key. * * The map takes ownership of the value. * * @param key The key to insert under. * @param value The value to be inserted. * * @return 0 on success, negative values on error. */ int insert(key_type key, value_type value) { auto dest_entry = root; while (dest_entry->inode != nullptr) { auto n = dest_entry->inode; dest_entry = n->entries[BIT_IS_SET(key, n->diff)]; } entry e(key, value); auto pop = nvobj::pool_by_vptr(this); nvobj::transaction::exec_tx(pop, [&] { if (dest_entry->key == 0 || dest_entry->key == key) { nvobj::delete_persistent<T>(dest_entry->value); *dest_entry = e; } else { insert_leaf(&e, find_crit_bit(dest_entry->key, key)); } }); return 0; }
static int insert_leaf(rxt_node *newleaf, rxt_node *sibling, rxt_node *parent) { int idx, bit, max_len; rxt_node *inner; max_len = rdx_min(newleaf->pos, sibling->pos); idx = count_common_bits(newleaf->key, sibling->key, max_len); bit = get_bit_at(newleaf->key, idx); if (!parent) { // insert at the root, so rotate things like so: /* /\ to /\ 1 2 /\ 3 1 2 */ parent = sibling; inner = (rxt_node *)malloc(sizeof(rxt_node)); if (!inner) return -1; inner->color = 0; inner->value = NULL; inner->parent = parent; inner->left = parent->left; inner->right = parent->right; inner->key = parent->key; inner->pos = parent->pos; parent->pos = idx; parent->left->parent = inner; parent->right->parent = inner; newleaf->parent = parent; if (bit) { parent->right = newleaf; parent->left = inner; } else { parent->right = inner; parent->left = newleaf; } return 0; } if (idx < parent->pos) { // use the parent as a sibling return insert_leaf(newleaf, parent, parent->parent); } else { // otherwise, add newleaf as a child of inner // Check for duplicates. // FIXME feels hackish; do this properly. if (newleaf->pos == sibling->pos && !strncmp(newleaf->key, sibling->key, newleaf->pos)) { free(newleaf); return -1; } inner = (rxt_node *)malloc(sizeof(rxt_node)); if (!inner) free(inner); inner->color = 0; inner->value = NULL; inner->parent = parent; inner->pos = idx; inner->key = sibling->key; newleaf->parent = inner; sibling->parent = inner; if (bit) { inner->right = newleaf; inner->left = sibling; } else { inner->right = sibling; inner->left = newleaf; } // now find out which branch of parent to assign inner if (parent->left == sibling) parent->left = inner; else if (parent->right == sibling) parent->right = inner; else { fprintf(stderr, "inappropriate child %s/%s found in parent when inserting leaf %s (expected %s)\n", parent->left->key, parent->right->key, newleaf->key, sibling->key); return -1; } } return 0; }
/* Insert new leaf to next cursor position, then set cursor to new leaf */ int btree_insert_leaf(struct cursor *cursor, tuxkey_t key, struct buffer_head *leafbuf) { return insert_leaf(cursor, key, leafbuf, 0); }