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* Nde::split_insert(Elem& element) { #ifndef QT_NO_DEBUG int existing_p_nodes = 0; if(mp_parent){ existing_p_nodes = mp_parent->m_total_nodes; } #endif // split_insert should only be called if node is full if (m_count != m_vector.size()-1) throw "bad m_count in split_insert"; vector_insert_for_split (element); unsigned int split_point = m_count/2; if (2*split_point < m_count) {split_point++;}// "ceiling" // new node receives the rightmost half of elements in *this node Nde* new_node = new Node(m_root); //One for upward node int nodes_removed=0; if (element.mp_subtree){ m_total_nodes += element.mp_subtree->m_total_nodes; } //Ripping out the upward element from the node... Elem upward_element = m_vector[split_point]; //ONLY it's CHILDREN go to new_node if (upward_element.mp_subtree){ nodes_removed += upward_element.mp_subtree->m_total_nodes; } new_node->insert_zeroth_subtree (upward_element.mp_subtree); upward_element.mp_subtree = new_node; // element that gets added to new_node for (unsigned int i=1; i<m_count-split_point; i++){ new_node->vector_insert(m_vector[split_point+i]); //Count nodes *removed* nodes_removed ++; if (m_vector[split_point+i].mp_subtree){ nodes_removed += m_vector[split_point+i].mp_subtree->m_total_nodes; } } new_node->m_count = m_count-split_point; new_node->mp_parent = mp_parent; m_count = split_point; m_total_nodes -= nodes_removed; // int n_total = new_node->m_total_nodes + m_total_nodes; // int d; // Elem* dd=0; // testTreeStructure(d, dd); // dd = 0; // new_node->testTreeStructure(d, dd); // now insert the new node into the parent, splitting it if necessary if (mp_parent ){ mp_parent->m_total_nodes -= nodes_removed; if(mp_parent->vector_insert(upward_element)){ mp_parent->node_size(); // dd = 0; // mp_parent->testTreeStructure(d,dd); return mp_parent; } Nde* res = mp_parent->split_insert(upward_element); // dd =0; // mp_parent->testTreeStructure(d, dd); return res; } else { // this node was the root Nde* new_root = new Node(m_root); new_root->insert_zeroth_subtree(this); this->mp_parent = new_root; new_node->mp_parent = new_root; new_root->vector_insert (upward_element); m_root.set_root (m_root.get_root(), new_root); new_root->mp_parent = 0; new_root->adjust_parent_totals(); // dd =0; // new_root->testTreeStructure(d, dd); return new_root; } Q_ASSERT(false); return 0; }