示例#1
0
shpid_t lg_tag_indirect_h::_pid(uint4_t pid_num) const
{
    FUNC(lg_tag_indirect_h::_pid);

    // get the root page
    lpid_t root_pid(stid(), _iref.indirect_root);
    lgindex_p root;
    W_IGNORE( root.fix(root_pid, LATCH_SH) ); // PAGEFIXBUG
    if (!root.is_fixed()) return 0;

    // if the tree is only 1 level, return the correct pid easily
    if (indirect_type(_page_cnt) == t_large_1) {
        return root.pids(pid_num);
    }
    w_assert9(indirect_type(_page_cnt) == t_large_2);

    // find "slot" containing pointer to page with pid_num
    w_assert9( (pid_num/lgindex_p::max_pids) < max_uint2);
    slotid_t idx = (slotid_t)(pid_num/lgindex_p::max_pids);
    lpid_t indirect_pid(stid(), root.pids(idx));
    lgindex_p indirect;
    W_IGNORE( indirect.fix(indirect_pid, LATCH_SH) ); // PAGEFIXBUG
    if (!indirect.is_fixed()) return 0;

    return indirect.pids(pid_num % lgindex_p::max_pids);
}
示例#2
0
rc_t
lg_tag_indirect_h::append(uint4_t num_pages, const lpid_t new_pages[])
{
    FUNC(lg_tag_indirect_h::append);
    const uint max_pages = 64;
    shpid_t   page_list[max_pages];
    w_assert9(num_pages <= max_pages);
    for (uint i=0; i<num_pages; i++) page_list[i]=new_pages[i].page;

    if (_iref.indirect_root == 0) {
        // allocate a root indirect page, near last page in store
        lpid_t root_pid;
        W_DO(smlevel_0::io->alloc_a_page(stid(), 
                lpid_t::eof,     // near hint
                root_pid, // npages, array for output pids
                false, // not may_realloc
                EX,         // lock on the allocated pages
                false        // do not search file for free pages
                ));
        _iref.indirect_root = root_pid.page;
        lgindex_p root;
        W_DO( root.fix(root_pid, LATCH_EX, root.t_virgin) ); 
        // perform fake read of the new page
    }

    // calculate the number of pages to append to last index page
    uint space_on_last = lgindex_p::max_pids-
                        _pages_on_last_indirect();
    uint4_t pages_on_last = MIN(num_pages, space_on_last);

    // number of pages to place on a new indirect_page
    uint4_t pages_on_new = num_pages - pages_on_last;

    // append pages to 
    lpid_t last_index_pid(stid(), _last_indirect());
    lgindex_p last_index;
    W_DO( last_index.fix(last_index_pid, LATCH_EX) );
    w_assert1(last_index.is_fixed());

    W_DO(last_index.append(pages_on_last, page_list));

    if (pages_on_new) {
        lpid_t new_pid;
        W_DO(_add_new_indirect(new_pid));
        lgindex_p last_index2;
        W_DO( last_index2.fix(new_pid, LATCH_EX) );
        w_assert1(last_index2.is_fixed());
        W_DO(last_index2.append(pages_on_new, page_list+pages_on_last));
    }

    return RCOK;
}
int main()
{
    string id;
    int count=0;
    cout<<"注意英文大寫,不需要空格,要跳出請輸入00"<<endl<<endl;
    while(1)
    {
        cout<<"------------------------------"<<endl;
        cout<<++count<<" : "<<endl;
        cout<<"輸入學號 : ";
        cin>>id;
        if(id=="00")break;//exit(1);
        Student stid(id);
        //cout<<stid.getStudentId()<<endl;
        cout<<"就讀科系 : "<<stid.getDepartment()<<endl;
        cout<<"目前身份 : "<<stid.getIdentity()<<endl;
        cout<<"入學年度 : "<<stid.getEntryYear()<<endl;
        cout<<"入學方式 : "<<stid.getEntryMethod()<<endl;
        cout<<"班級座號 : "<<stid.getNumber()<<endl<<endl;
        if(stid.getCheck())
        {
            stid.setCheck(false);
            cout<<"沒有這個人喔!!!!"<<endl;
        }
    }
    return 0;
}
示例#4
0
rc_t
lg_tag_indirect_h::_add_new_indirect(lpid_t& new_pid)
{
    FUNC(lg_tag_indirect_h::_add_new_indirect);
    // flags for new pages
    w_base_t::uint4_t flags = lgindex_p::t_virgin;

    if (indirect_type(_page_cnt) == t_large_1) {
        // must allocate a new root pid and point it to the current one
        lpid_t root_pid;
        W_DO(smlevel_0::io->alloc_a_page(stid(), 
                lpid_t::eof,  // near hint
                root_pid, // npages, array for output pids
                false, // not may_realloc 
                EX, // lock on pages
                false        // do not search file for free pages
                ));

        lgindex_p root;
        W_DO( root.fix(root_pid, LATCH_EX, flags) );
        w_assert1(root.is_fixed());
        W_DO(root.append(1, &_iref.indirect_root));
        w_assert9(root_pid.stid() == stid());
        _iref.indirect_root = root_pid.page;
    }

    // allocate a new page and point to it from the root
    W_DO(smlevel_0::io->alloc_a_page(stid(), 
                lpid_t::eof,  // near hint
                new_pid, // npages, array of output pids
                false,         // not may_realloc
                EX,        // lock on new pages
                false        // do not search file for free pages
                ));
    lgindex_p new_page;
    W_DO( new_page.fix(new_pid, LATCH_EX, flags) );  // format page

    lpid_t root_pid(stid(), _iref.indirect_root);
    lgindex_p root;
    W_DO( root.fix(root_pid, LATCH_EX) );
    w_assert1(root.is_fixed());
    W_DO(root.append(1, &new_pid.page));

    return RCOK;
}
示例#5
0
shpid_t lg_tag_indirect_h::_last_pid() const
{
    FUNC(lg_tag_indirect_h::_last_pid);

    lpid_t last_indirect_pid(stid(), _last_indirect());
    if (last_indirect_pid.page == 0) return 0;  // 0-length record
    lgindex_p last_indirect;
    W_IGNORE( last_indirect.fix(last_indirect_pid, LATCH_SH) ); // PAGEFIXBUG
    if (!last_indirect.is_fixed()) return 0;

    return last_indirect.last_pid();
}
示例#6
0
shpid_t lg_tag_indirect_h::_last_indirect()  const
{
    FUNC(lg_tag_indirect_h::_last_indirect);
    if (indirect_type(_page_cnt) == t_large_1) {
        return _iref.indirect_root;
    }

    // read the root page
    lpid_t root_pid(stid(), _iref.indirect_root);
    lgindex_p root;
    W_IGNORE( root.fix(root_pid, LATCH_SH) ); // PAGEFIXBUG
    if (!root.is_fixed()) return 0; 
    
    shpid_t* pids = (shpid_t*)root.tuple_addr(0);
    w_assert9(pids);
    return(pids[(_page_cnt-1)/lgindex_p::max_pids]);
}
示例#7
0
rc_t
lg_tag_indirect_h::update(uint4_t start_byte, const vec_t& data) const
{
    FUNC(lg_tag_indirect_h::update);
    uint4_t amount; // amount to update on page
    uint   page_to_update = start_byte/lgdata_p::data_sz; // first page
    uint4_t data_size = data.size();

    lpid_t curr_pid(stid(), 0);
    uint4_t offset = start_byte%lgdata_p::data_sz;
    uint4_t num_bytes = 0;
    while (num_bytes < data_size) {
        amount = MIN(lgdata_p::data_sz-offset, data_size-num_bytes);
        curr_pid.page = _pid(page_to_update); 
        lgdata_p lgdata;
        W_DO( lgdata.fix(curr_pid, LATCH_EX) );
        W_DO(lgdata.update(offset, data, num_bytes, amount));
        offset = 0;
        num_bytes += amount;
        page_to_update++;
    }
    w_assert9(page_to_update-1 == (start_byte+data.size()-1)/lgdata_p::data_sz);
    return RCOK;
}
示例#8
0
/* 
 * truncate() removes pages at the end of large records
 * implemented as indirect blocks 
 */
rc_t
lg_tag_indirect_h::truncate(uint4_t num_pages)
{
    FUNC(lg_tag_indirect_h::truncate);
    int         i;
    int         first_dealloc = (int)(_page_cnt-num_pages);
    int         last_dealloc = (int)(_page_cnt-1);
    recflags_t  rec_type = indirect_type(_page_cnt);

    for (i = first_dealloc; i <= last_dealloc; i++) {
        W_DO(smlevel_0::io->free_page(pid(i)));
    }

    int indirect_rm_count = 0;          // # indirect pages to remove
    int pids_rm_by_indirect = 0;  // # data pids removed
                                  // by removing indirect pages
    int pids_to_rm = 0;           // # of pids to rm from last indirect
 
    // indirect pages are only removed if t_large_2
    if (rec_type == t_large_2) {
        uint pids_on_last = _pages_on_last_indirect();
        if (pids_on_last > num_pages) {
            indirect_rm_count = 0;
        } else {
            indirect_rm_count = (num_pages-1)/lgindex_p::max_pids+1;
            pids_rm_by_indirect = pids_on_last+(indirect_rm_count-1)*lgindex_p::max_pids;
        }
    }
    pids_to_rm = num_pages-pids_rm_by_indirect;

    // remove any indirect pages we can
    if (indirect_rm_count > 0) {
        lpid_t        root_pid(stid(), _iref.indirect_root);
        lgindex_p root;
        W_DO( root.fix(root_pid, LATCH_EX) );
        w_assert1(root.is_fixed());

        // first deallocate the indirect pages
        w_assert9(root.pid_count() ==
                _page_cnt/lgindex_p::max_pids + 1);
        first_dealloc = root.pid_count()-indirect_rm_count;
        last_dealloc = root.pid_count()-1;
        for (i = first_dealloc; i <= last_dealloc; i++) {
            lpid_t pid_to_free(stid(), root.pids(i));
            W_DO(smlevel_0::io->free_page(pid_to_free));
        }

        // if will be only one indirect page left, then remember
        // the ID of this page
        /*
        shpid_t new_indirect_root;
        if (indirect_type(_page_cnt-num_pages) == t_large_1) { 
            new_indirect_root = root->pids(0);
        }
        */

        W_DO(root.truncate(indirect_rm_count));

        // if there is only one indirect page left, then switch to
        // a single level tree
        if (indirect_type(_page_cnt-num_pages) == t_large_1) { 
            w_assert9( ((_page_cnt-1)/lgindex_p::max_pids+1) -
                     indirect_rm_count == 0);
            if (root.pid_count() > 0) {
                // there is at least one page left in the record,
                // the the first page in the root becomes the new root
                _iref.indirect_root = root.pids(0);
            } else {
                // all pages have been removed, so there is no root
                _iref.indirect_root = 0;
            }
            root.unfix();
            W_DO(smlevel_0::io->free_page(root_pid));
        }
    }

    // if we have not removed all pages, we must truncate pids
    // from the last indirect page
    if (_page_cnt > num_pages) {

        // get the pid for the last indirect page before truncate point
        // temporarily lower _page_cnt
        _page_cnt -= num_pages;
        lpid_t last_index_pid(stid(), _last_indirect());
        _page_cnt += num_pages;

        lgindex_p last_index;
        W_DO( last_index.fix(last_index_pid, LATCH_EX) );
        w_assert1(last_index.is_fixed());
        W_DO(last_index.truncate(pids_to_rm));
    } else {
        w_assert9(_page_cnt == num_pages);
        // we have removed all data pages, so remove the root 
        // (assuming it is not 0 meaning it has already been removed)
        if (_iref.indirect_root != 0) {
            lpid_t root_pid(stid(), _iref.indirect_root);
            W_DO(smlevel_0::io->free_page(root_pid));
            _iref.indirect_root = 0;  // mark that there is no root
        }
    }
    return RCOK;
}