void BPlusTree::btree_insert_nonfull(btree_node *node, int target) { if(true == node->is_leaf) { int pos = node->num; while(pos >= 1 && target < node->k[pos-1]) { node->k[pos] = node->k[pos-1]; pos--; } node->k[pos] = target; node->num += 1; btree_node_num+=1; } else { int pos = node->num; while(pos > 0 && target < node->k[pos-1]) { pos--; } if(2 * M -1 == node->p[pos]->num) { btree_split_child(node, pos, node->p[pos]); if(target > node->k[pos]) { pos++; } } btree_insert_nonfull(node->p[pos], target); } }
//往一颗B树插入一个关键字elem btree_node* btree_insert(btree_node *btree, int elem) { //如果root结点是一个满结点 if (btree->num == 2 * T - 1) { //创建一个新结点,作为新root结点 btree_node *new_root = NULL; new_root = malloc(sizeof(btree_node)); if (new_root == NULL) { fprintf(stderr, "Error:Can't allocate neccessary space!"); exit(1); } new_root->is_leaf = 0; new_root->num = 0; new_root->ptr[0] = btree; //对旧root结点进行分裂 btree_split_child(new_root, 0, btree); btree_insert_nonfull(new_root, elem); return new_root; } else { btree_insert_nonfull(btree, elem); return btree; } }
btree_node* btree_insert(btree_node *root, int target) { if(NULL == root) { return NULL; } if(2 * M - 1 == root->num) { btree_node *node = btree_node_new(); if(NULL == node) { return root; } node->is_leaf = 0; node->p[0] = root; btree_split_child(node, 0, root); btree_insert_nonfull(node, target); return node; } else { btree_insert_nonfull(root, target); return root; } }
/** * btree_insert_non_full * @access private * @param btree struct * @param btree node * @param key * @param data index * @return void * * inserts the node into the btree - either immediately if it's a leaf or find the branch, split * the child and call this recursively until a leaf is found */ static void btree_insert_non_full(btree_tree *t, btree_node *node, uint64_t key, uint32_t data_idx) { uint32_t i; btree_node *tmp_node; i = node->nr_of_keys; if (node->leaf) { while (i > 0 && key < node->keys[i - 1].key) { node->keys[i] = node->keys[i - 1]; i--; } node->keys[i].key = key; node->nr_of_keys++; /* Fetch data index, and set it to the idx element here too */ node->keys[i].idx = data_idx; /* Do administrative jobs */ dr_set_add(&(t->freelist), data_idx); t->header->item_count++; } else { tmp_node = btree_find_branch(t, node, key, &i); if (tmp_node->nr_of_keys == BTREE_T2(t) - 1) { btree_split_child(t, node, i, tmp_node); if (key > node->keys[i].key) { i++; } } btree_insert_non_full(t, btree_get_node(t, node->branch[i]), key, data_idx); } }
/** * btree_insert_internal * @access private * @param btree struct * @param key * @param data index * @return void * * does the actual insert of the new node - depending on which side of the tree * it needs to go on this can include a split, or just a call to insert_non_full */ static void btree_insert_internal(btree_tree *t, uint64_t key, uint32_t data_idx) { btree_node *r = t->root; if (r->nr_of_keys == BTREE_T2(t) - 1) { btree_node *tmp_node; tmp_node = btree_allocate_node(t); t->root = tmp_node; t->header->root_node_idx = tmp_node->idx; tmp_node->leaf = 0; tmp_node->nr_of_keys = 0; tmp_node->branch[0] = r->idx; btree_split_child(t, tmp_node, 0, r); btree_insert_non_full(t, tmp_node, key, data_idx); } else { btree_insert_non_full(t, r, key, data_idx); } }
void btree_insert( BTreeNode *& root, Key k ) { BTreeNode * r = root; BTreeNode * s; int d = root->min_degree; if( r->n == 2*d - 1 ) { s = new BTreeNode( d ); root = s; s->leaf = false; s->n = 0; s->children[0] = r; btree_split_child( s, 0 ); btree_insert_nonfull( s, k ); } else { btree_insert_nonfull( r, k ); } }
/** * Function used to insert node into a B-Tree * @param root Root of the B-Tree * @param node The node to be inserted * @param compare Function used to compare the two nodes of the tree * @return success or failure */ int btree_insert_key(btree * btree, bt_key_val * key_val) { bt_node * rnode; rnode = btree->root; if(rnode->nr_active == (2*btree->order - 1)) { bt_node * new_root; new_root = allocate_btree_node(btree->order); new_root->level = btree->root->level + 1; btree->root = new_root; new_root->leaf = false; new_root->nr_active = 0; new_root->children[0] = rnode; btree_split_child(btree,new_root,0,rnode); btree_insert_nonfull(btree,new_root,key_val); } else btree_insert_nonfull(btree,rnode,key_val); return 0; }
//往一个非满结点 nonfull_node中插入一个关键字elem void btree_insert_nonfull(btree_node *nonfull_node, int elem) { //获取该结点的key值个数 int key_idx = nonfull_node->num - 1; //如果待插入的非满结点为叶子结点,将关键字直接插入 if (nonfull_node->is_leaf == 1) { //根据结点关键字大小的顺序,定位要插入关键字的位置 while(key_idx>=0 && nonfull_node->key[key_idx]>elem) { nonfull_node->key[key_idx+1] = nonfull_node->key[key_idx]; key_idx--; } nonfull_node->key[key_idx+1] = elem; nonfull_node->num += 1; } else //如果待插入非满结点为内结点,则一直查找到一个叶子结点为止 { while(key_idx>=0 && nonfull_node->key[key_idx]>elem) key_idx--; key_idx = key_idx+1; //沿着B树结点下移到子结点 btree_node *child_node = nonfull_node->ptr[key_idx]; //如果子结点是满的,则先进行分裂 if (child_node->num == 2*T-1) { //按照结点的中间位置(T-1)进行分裂 btree_split_child(nonfull_node, key_idx, child_node); //分裂后nonfull_node产生两个新的子节点,需确定往哪个子节点递归 if (nonfull_node->key[key_idx] < elem) key_idx = key_idx + 1; } btree_insert_nonfull(nonfull_node->ptr[key_idx], elem); } }
static void btree_insert_nonfull (btree * btree, bt_node * parent_node, bt_key_val * key_val) { int i; bt_node * child; bt_node * node = parent_node; insert: i = node->nr_active - 1; if(node->leaf) { while(i >= 0 && btree->compare(key_val->key,node->key_vals[i]->key)<0) { node->key_vals[i + 1] = node->key_vals[i]; i--; } node->key_vals[i + 1] = key_val; node->nr_active++; } else { while (i >= 0 && btree->compare(key_val->key,node->key_vals[i]->key)<0) { i--; } i++; child = node->children[i]; if(child->nr_active == 2*btree->order - 1) { btree_split_child(btree,node,i,child); if(btree->compare(key_val->key,node->key_vals[i]->key)>0) i++; } node = node->children[i]; goto insert; } }
void btree_insert_nonfull( BTreeNode * node, Key k ) { int i = node->n - 1; if( node->leaf ) { for( int j = 0; j < node->n; ++j ) if( node->keys[j] == k ) return; for( ; i >= 0 && k < node->keys[i]; --i ) { node->keys[i+1] = node->keys[i]; } node->keys[i+1] = k; ++node->n; } else { for( ; i >= 0 && k < node->keys[i]; --i ); ++i; if( node->children[i]->n == 2*node->min_degree - 1 ) { btree_split_child( node, i ); if( k > node->keys[i] ) ++i; } btree_insert_nonfull( node->children[i], k ); } }