int split_insert (PBTREE btree, int node_idx, PBTREE_ELEMENT element) { int i; int split_point; int new_node_idx; BTREE_ELEMENT upward_element; // split_insert should only be called if node is full if (btree->nodes[node_idx].element_count != BTREE_MAX_ELEMENTS-1) return 0; vector_insert_for_split (btree, node_idx, element); split_point = btree->nodes[node_idx].element_count/2; if (2*split_point < btree->nodes[node_idx].element_count) // perform the "ceiling function" split_point++; // new node receives the rightmost half of elements in *this node new_node_idx = get_free_node(btree); if (!BTREE_IS_VALID_NODE_IDX(new_node_idx)) return 0; memcpy(&upward_element, &btree->nodes[node_idx].elements[split_point], sizeof(BTREE_ELEMENT)); insert_zeroth_subtree (btree, new_node_idx, upward_element.subtree_node_idx); upward_element.subtree_node_idx = new_node_idx; // element that gets added to the parent of this node for (i=1; i<btree->nodes[node_idx].element_count-split_point; i++) vector_insert(btree, new_node_idx, &btree->nodes[node_idx].elements[split_point+i]); btree->nodes[new_node_idx].element_count = btree->nodes[node_idx].element_count-split_point; btree->nodes[node_idx].element_count = split_point; btree->nodes[new_node_idx].parent_node_idx = btree->nodes[node_idx].parent_node_idx; // now insert the new node into the parent, splitting it if necessary if (BTREE_IS_VALID_NODE_IDX(btree->nodes[node_idx].parent_node_idx) && vector_insert(btree, btree->nodes[node_idx].parent_node_idx, &upward_element)) return 1; else if (BTREE_IS_VALID_NODE_IDX(btree->nodes[node_idx].parent_node_idx) && split_insert(btree, btree->nodes[node_idx].parent_node_idx, &upward_element)) return 1; else if (!BTREE_IS_VALID_NODE_IDX(btree->nodes[node_idx].parent_node_idx)) { // this node was the root int new_root = get_free_node(btree); insert_zeroth_subtree(btree, new_root, node_idx); btree->nodes[node_idx].parent_node_idx = new_root; btree->nodes[new_node_idx].parent_node_idx = new_root; vector_insert (btree, new_root, &upward_element); btree->root_node_idx = new_root; btree->nodes[new_root].parent_node_idx = BTREE_INVALID_NODE_IDX; } return 1; }
template<class KEY, class VALUE> Nde::Node(RootTracker<KEY, VALUE>& root_track) : m_root(root_track) { // limit the size of the vector to 4 kilobytes max and 200 entries max. int num_elements = max_elements*sizeof(Elem)<=max_array_bytes ? max_elements : max_array_bytes/sizeof(Elem); // in case key or payload is really huge if (num_elements < 6){ num_elements = 6;} m_vector.resize (num_elements); m_count = 0; m_total_nodes = 0; mp_parent = 0; insert_zeroth_subtree (0); }
int btree_insert (PBTREE btree, PBTREE_ELEMENT element) { int last_visited_node_idx; if (!BTREE_IS_VALID_NODE_IDX(btree->root_node_idx)) { int node_idx = get_free_node(btree); if (!BTREE_IS_VALID_NODE_IDX(node_idx)) return 0; else { set_root(btree, node_idx); insert_zeroth_subtree (btree, node_idx, BTREE_INVALID_NODE_IDX); } } last_visited_node_idx = btree->root_node_idx; if (btree_search_ex(btree, &last_visited_node_idx, element->key)) // element already in tree return 0; if (vector_insert(btree, last_visited_node_idx, element)) return 1; return split_insert(btree, last_visited_node_idx, element); }