Esempio n. 1
0
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;

}
Esempio n. 2
0
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;
}