void jnx_btree_add(jnx_btree *tree, void *key, void *value) { JNXCHECK(tree); JNXCHECK(key); JNXCHECK(value); if ( tree == NULL) { return; } record *r = malloc(sizeof(record)); r->key = key; r->value = value; if ( is_node_full(tree, tree->root) ) { jnx_btree_node *temp = tree->root; tree->root = new_node(tree->order, 0); tree->root->children[0] = temp; split_child_at_index(tree, tree->root, 0); } insert_into_tree_at_node(tree, tree->root, r); }
/* * To guarantee that leaf node is never full, we split any full * node on the way down the tree, find the appropriate subtree * to traverse, and insert the node jnx_int32o the subtree. * * The only special case is if the root is a leaf node. We handle * this in jnx_btree_add API function. */ void insert_into_tree_at_node(jnx_btree *tree, jnx_btree_node *node, record *r) { if ( node->is_leaf ) { add_record_to_non_full_leaf(tree, node, r); return; } jnx_int32 i = find_index_for_record(tree, node, r); if ( i < node->count ) { if ( tree->compare_function(node->records[i]->key, r->key) == 0 ) { // Same key so just replace the old record with the new one free(node->records[i]); node->records[i] = r; return; } } if ( is_node_full(tree, node->children[i]) ) { split_child_at_index(tree, node, i); if ( tree->compare_function(node->records[i]->key, r->key) == 0 ) { // Case when the node that moved up is actually the node we want to insert free(node->records[i]); node->records[i] = r; return; } if ( tree->compare_function(node->records[i]->key, r->key) < 0 ) { // We're going to the right of the record that moved up i++; } } // Recurse down jnx_int32o the appropriate subtree insert_into_tree_at_node(tree, node->children[i], r); }
bool search::is_bucket_full() const { if (short_list_in_bucket() >= BUCKET_SIZE) return true; return is_node_full(); }