Beispiel #1
0
void oc_bpt_utl_iter_b(
    struct Oc_wu *wu_p,
    struct Oc_bpt_state *s_p,
    void (*iter_f)(struct Oc_wu *, Oc_bpt_node*),
    Oc_bpt_node *node_p)
{
    iter_f(wu_p, node_p);

    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_iter_b(wu_p, s_p, iter_f, child_node_p);
            oc_bpt_nd_release(wu_p, s_p, child_node_p);
        }
    }
}
Beispiel #2
0
static bool lookup_b(
    struct Oc_wu *wu_p,
    struct Oc_bpt_state *s_p,
    struct Oc_bpt_key *key_p,
    struct Oc_bpt_data *data_po)
{
    Oc_bpt_node *father_p, *child_p;
    uint64 addr;
    bool rc;
    int idx;
    
    oc_bpt_nd_get_for_read(wu_p, s_p, s_p->root_node_p->disk_addr);

    // 1. base case, this is the root node and the root is a leaf
    if (oc_bpt_nd_is_leaf(s_p, s_p->root_node_p))
    {
        rc = lookup_in_leaf(wu_p, s_p, s_p->root_node_p, key_p, data_po);
        oc_bpt_nd_release(wu_p, s_p, s_p->root_node_p);
        return rc;
    }
        
    // 2. this is the root, and it isn't a leaf node:
    //    look for the correct child and get it
    addr = oc_bpt_nd_index_lookup_key(wu_p, s_p, s_p->root_node_p, key_p,
                                      NULL, &idx);
    if (0 == addr) {
        oc_bpt_nd_release(wu_p, s_p, s_p->root_node_p);
        return FALSE;
    }
    child_p = oc_bpt_nd_get_for_read(wu_p, s_p, addr);
    father_p = s_p->root_node_p;
    
    // 3. regular case: child, with a father, both are locked for read.
    //    if the child is a leaf node, then do a local lookup.
    //    else, release the father, get the child's son. 
    while (1) {

        if (oc_bpt_nd_is_leaf(s_p, child_p)) {
            rc = lookup_in_leaf(wu_p, s_p, child_p, key_p, data_po);
            oc_bpt_nd_release(wu_p, s_p, father_p);
            oc_bpt_nd_release(wu_p, s_p, child_p);
            return rc;
        }
        else {
            // release the father
            oc_bpt_nd_release(wu_p, s_p, father_p);

            // switch places between father and son.
            father_p = child_p;
            
            addr = oc_bpt_nd_index_lookup_key(wu_p, s_p, father_p, key_p,
                                              NULL, &idx);
            if (0 == addr) {
                oc_bpt_nd_release(wu_p, s_p, father_p);                
                return FALSE;
            }
            child_p = oc_bpt_nd_get_for_read(wu_p, s_p, addr);
        }
    }
}
Beispiel #3
0
void oc_bpt_cow_root_and_update_b(
    struct Oc_wu *wu_p,
    struct Oc_bpt_state *s_p,
    struct Oc_bpt_data *father_data_p,
    int size)
{
    // Old disk-addr stored as data in father
    uint64 prev_addr = *((uint64*)father_data_p); 
    Oc_bpt_node *node_p;   
    int fs_refcnt;
    
    oc_bpt_trace_wu_lvl(2, OC_EV_BPT_COW_ROOT_AND_UPDATE, wu_p,
                        "lba of root as appers in father (before update):%llu",
                        prev_addr);
    oc_utl_assert(NULL != s_p->root_node_p);
    oc_utl_trk_crt_lock_write(wu_p, &s_p->lock);

    node_p = s_p->cfg_p->node_get_xl(wu_p, s_p->root_node_p->disk_addr);
    oc_utl_debugassert(node_p == s_p->root_node_p);

    fs_refcnt = s_p->cfg_p->fs_get_refcount(
        wu_p,
        s_p->root_node_p->disk_addr);
    s_p->cfg_p->node_mark_dirty(wu_p, s_p->root_node_p, (fs_refcnt > 1));

    if (s_p->root_node_p->disk_addr != prev_addr)
    {
        uint64 new_addr = s_p->root_node_p->disk_addr;
        memcpy((char*)father_data_p, &new_addr, size);
    }
    oc_bpt_trace_wu_lvl(2, OC_EV_BPT_COW_ROOT_AND_UPDATE, wu_p,
                        "lba of root as appers in father (AFTER update):%llu",
                        *((uint64*)father_data_p));
    
    oc_bpt_nd_release(wu_p, s_p, s_p->root_node_p);// Dalit: may not be needed
    oc_utl_trk_crt_unlock(wu_p, &s_p->lock);   // Dalit: may not be needed

}