Beispiel #1
0
/* Delete a sub-tree rooted at [addr].
 * 
 * Recursive decent through the tree. Remove the leaves and perform
 * the user-defined "data_release" function for all data. Deallocate all
 * internal nodes. 
 */
void oc_bpt_utl_delete_subtree_b(
    struct Oc_wu *wu_p,
    struct Oc_bpt_state *s_p,
    Oc_bpt_node *node_p)
{
    int fs_refcnt = s_p->cfg_p->fs_get_refcount(wu_p, node_p->disk_addr);

    oc_utl_debugassert(fs_refcnt > 0);

    if (1 == fs_refcnt) {
        /* If this node is referenced from a single snapshot only, 
         * Then recurse down and then delete it on the way back up.
         */
        if (!oc_bpt_nd_is_leaf(s_p, node_p)) {
            // An index node, recurse through its children
            int i;
            int num_entries = oc_bpt_nd_num_entries(s_p, node_p);
            Oc_bpt_node *child_node_p;
            struct Oc_bpt_key *dummy_key_p;
            uint64 child_addr;
            
            for (i=0; i< num_entries; i++) {
                oc_bpt_nd_index_get_kth(s_p, node_p, i,
                                        &dummy_key_p,
                                        &child_addr);
                child_node_p = oc_bpt_nd_get_for_read(wu_p, s_p, child_addr);
                oc_bpt_utl_delete_subtree_b(wu_p, s_p, child_node_p);
            }
        }
    }
    
    // reduce the ref-count on this node
    oc_bpt_nd_delete(wu_p, s_p, node_p);
}
Beispiel #2
0
/* Delete all the key-value pairs in the tree. 
 * Leave the root node empty but do not delete it. 
 */
void oc_bpt_utl_delete_all_b(
    struct Oc_wu *wu_p,
    struct Oc_bpt_state *s_p)
{
    int num_entries = oc_bpt_nd_num_entries(s_p, s_p->root_node_p);

    if (!oc_bpt_nd_is_leaf(s_p, s_p->root_node_p)) {
        // This is a full fledged tree. Remove all the sub-trees. 
        int i;
        Oc_bpt_node *child_node_p;
        struct Oc_bpt_key *dummy_key_p;
        uint64 child_addr;
        
        for (i=0; i< num_entries; i++) {
            oc_bpt_nd_index_get_kth(s_p, s_p->root_node_p, i,
                                    &dummy_key_p,
                                    &child_addr);
            child_node_p = oc_bpt_nd_get_for_read(wu_p, s_p, child_addr);
            oc_bpt_utl_delete_subtree_b(wu_p, s_p, child_node_p);
        }
    }

    // Remove all the entries from the root node
    oc_bpt_nd_remove_range(wu_p, s_p,
                           s_p->root_node_p,
                           0, num_entries - 1);
}
Beispiel #3
0
void oc_bpt_delete_b(
    struct Oc_wu *wu_p,
    struct Oc_bpt_state *s_p)
{
    oc_bpt_trace_wu_lvl(2, OC_EV_BPT_DELETE, wu_p, "tid=%Lu", s_p->tid);
    oc_utl_debugassert(s_p->cfg_p->initialized);
    
    oc_utl_trk_crt_lock_write(wu_p, &s_p->lock);

    /* We need to upgrade the root-lock to a shared-lock
     * because the delete-code unlocks all the pages after
     * deleting them. This means that the root cannot remain
     * unlocked, as usual. 
     */
    oc_utl_trk_crt_lock_read(wu_p, &s_p->root_node_p->lock);
    oc_bpt_utl_delete_subtree_b(wu_p, s_p, s_p->root_node_p);

    s_p->root_node_p = NULL;
    oc_utl_trk_crt_unlock(wu_p, &s_p->lock);
}