Beispiel #1
0
w_rc_t prepare_test(ss_m* ssm, test_volume_t *test_volume, StoreID &stid, PageID &root_pid) {
    W_DO(x_btree_create_index(ssm, test_volume, stid, root_pid));

    // very large records to cause splits
    const int recsize = SM_PAGESIZE / 6;
    char datastr[recsize];
    ::memset (datastr, 'a', recsize);
    vec_t data;
    data.set(datastr, recsize);

    W_DO(ssm->begin_xct());
    w_keystr_t key;
    char keystr[5] = "";
    memset(keystr, '\0', 5);
    keystr[0] = 'k';
    keystr[1] = 'e';
    keystr[2] = 'y';
    for (int i = 0; i < 20; ++i) {
        keystr[3] = ('0' + (i / 10));
        keystr[4] = ('0' + (i % 10));
        key.construct_regularkey(keystr, 5);
        W_DO(ssm->create_assoc(stid, key, data));
    }
    W_DO(ssm->commit_xct());
    W_DO(x_btree_verify(ssm, stid));
    smlevel_0::bf->getPageCleaner()->wakeup(true);
    W_DO(ssm->checkpoint());
    return RCOK;
}
Beispiel #2
0
w_rc_t pipeline_many(ss_m* ssm, test_volume_t *test_volume) {
    StoreID stid;
    PageID root_pid;
    W_DO(x_btree_create_index(ssm, test_volume, stid, root_pid));

    char keystr[7];
    keystr[0] = 'k';
    keystr[1] = 'e';
    keystr[2] = 'y';
    keystr[6] = '\0';

    // because of flush pipeline, this should be quick
    timeval start,stop,result;
    ::gettimeofday(&start,nullptr);
    W_DO(test_env->begin_xct());
    for (int i = 0; i < 500; ++i) {
        keystr[3] = '0' + (i / 100);
        keystr[4] = '0' + ((i / 10) % 10);
        keystr[5] = '0' + (i % 10);
        W_DO(test_env->btree_insert (stid, keystr, "data"));
        W_DO(ss_m::chain_xct(true));
    }
    W_DO(test_env->commit_xct());
    ::gettimeofday(&stop,nullptr);
    timersub(&stop, &start,&result);
    cout << "flush pipeline of 500 chain (lazy) commits: " << (result.tv_sec + result.tv_usec/1000000.0) << " sec" << endl;

    x_btree_scan_result s;
    W_DO(test_env->btree_scan(stid, s));
    EXPECT_EQ (500, s.rownum);
    EXPECT_EQ (std::string("key000"), s.minkey);
    EXPECT_EQ (std::string("key499"), s.maxkey);

    ::gettimeofday(&start,nullptr);
    W_DO(test_env->begin_xct());
    for (int i = 500; i < 510; ++i) {
        keystr[3] = '0' + (i / 100);
        keystr[4] = '0' + ((i / 10) % 10);
        keystr[5] = '0' + (i % 10);
        W_DO(test_env->btree_insert (stid, keystr, "data"));
        W_DO(ss_m::chain_xct(false));
    }
    W_DO(test_env->commit_xct());
    ::gettimeofday(&stop,nullptr);
    timersub(&stop, &start,&result);
    cout << "flush pipeline of 10 chain (non-lazy) commits: " << (result.tv_sec + result.tv_usec/1000000.0) << " sec" << endl;

    W_DO(test_env->btree_scan(stid, s));
    EXPECT_EQ (510, s.rownum);
    EXPECT_EQ (std::string("key000"), s.minkey);
    EXPECT_EQ (std::string("key509"), s.maxkey);
    return RCOK;
}
w_rc_t dosome(ss_m* ssm, test_volume_t *test_volume) {
    StoreID stid;
    PageID root_pid;
    W_DO(x_btree_create_index(ssm, test_volume, stid, root_pid));

    w_keystr_t key;

    // XXXX should move the following out to a separate DataGen class
    typedef unsigned int size_t;
    size_t const domain = 100000;
    size_t const records = 100000;
    size_t produced = 0; // produced output records
    int ibuffer; // hold the random int

    ::srand(12345); // use fixed seed for repeatability and easier debugging
    W_DO(ssm->begin_xct());
    test_env->set_xct_query_lock();
    while ( produced < records )
    {
       std::stringstream buffer, buffer2;
       ibuffer = rand () % domain;
       buffer << ibuffer;
       key.construct_regularkey(buffer.str().data(), buffer.str().size());
       ibuffer = rand () % domain;
       buffer2 << ibuffer;
       vec_t data;
       data.set(buffer2.str().data(),buffer2.str().size());


       rc_t rc = ssm->create_assoc(stid, key, data);
       if (rc.is_error()) {
          if (rc.err_num() != eDUPLICATE) {
                cerr << "unexpected error";
                return rc;
          }
       }


       if (produced%500  == 1)
        {
          W_DO(ssm->commit_xct());
          W_DO(ssm->begin_xct());
          test_env->set_xct_query_lock();
          printf("Processed %d keys\n",produced);
        }

       produced++;
    }
    W_DO(ssm->commit_xct());
    return RCOK;
}
Beispiel #4
0
rc_t populateBtree(ss_m* ssm, test_volume_t *test_volume, int count)
{
    W_DO(x_btree_create_index(ssm, test_volume, stid, root_pid));

    std::stringstream ss("key");

    W_DO(test_env->begin_xct());
    for (int i = 0; i < count; i++) {
        ss.seekp(3);
        ss << i;
        W_DO(test_env->btree_insert(stid, ss.str().c_str(), HUNDRED_BYTES));
    }
    W_DO(test_env->commit_xct());
    return RCOK;
}
Beispiel #5
0
w_rc_t parallel_appends(ss_m *ssm, test_volume_t *volume) {
    StoreID stid;
    PageID root_pid;
    W_DO(x_btree_create_index(ssm, volume, stid, root_pid));

    append_worker_t workers[THREAD_COUNT];
    for (int i = 0; i < THREAD_COUNT; ++i) {
        workers[i].ssm = ssm;
        workers[i].volume = volume;
        workers[i].stid = stid;
        workers[i].root_pid = root_pid;
        W_DO(workers[i].fork());
    }

    for (int i = 0; i < THREAD_COUNT; ++i) {
        W_DO(workers[i].join());
        EXPECT_FALSE(workers[i]._running) << i;
        EXPECT_FALSE(workers[i]._rc.is_error()) << i;
    }
    return RCOK;
}
Beispiel #6
0
w_rc_t insert_twice(ss_m* ssm, test_volume_t *test_volume) {
    StoreID stid;
    PageID root_pid;
    W_DO(x_btree_create_index(ssm, test_volume, stid, root_pid));

    W_DO(test_env->begin_xct());
    W_DO(test_env->btree_insert (stid, "key004", "data4"));
    W_DO(ss_m::chain_xct(true));
    W_DO(test_env->btree_insert (stid, "key005", "data5"));
    W_DO(ss_m::chain_xct(false));
    W_DO(test_env->btree_insert (stid, "key006", "data6"));
    W_DO(test_env->commit_xct());

    x_btree_scan_result s;
    W_DO(test_env->btree_scan(stid, s));
    EXPECT_EQ (3, s.rownum);
    EXPECT_EQ (std::string("key004"), s.minkey);
    EXPECT_EQ (std::string("key006"), s.maxkey);

    return RCOK;
}
Beispiel #7
0
w_rc_t btree_page(ss_m* ssm, test_volume_t *test_volume) {
    StoreID stid;
    PageID root_pid;
    W_DO(x_btree_create_index(ssm, test_volume, stid, root_pid));

    W_DO(x_btree_verify(ssm, stid));

    W_DO(ssm->begin_xct());
    {
        char keystr[4], datastr[4];
        keystr[3] = '\0';
        datastr[3] = '\0';
        for (int i = 0; i < 100; ++i) {
            keystr[0] = datastr[0] = '0' + (i / 100);
            keystr[1] = datastr[1] = '0' + ((i / 10) % 10);
            keystr[2] = datastr[2] = '0' + (i % 10);
            W_DO(x_btree_insert(ssm, stid, keystr, datastr));
        }
    }
    W_DO(ssm->commit_xct());
    W_DO(x_btree_verify(ssm, stid));

    w_keystr_t neginf;
    neginf.construct_neginfkey();

    // get the left most page
    uint32_t correct_checksum;
    PageID leaf_pid;
    W_DO(ssm->begin_xct());
    {
        btree_page_h leaf;
        W_DO (btree_impl::_ux_traverse(stid, neginf, btree_impl::t_fence_low_match, LATCH_SH, leaf));
        EXPECT_TRUE (leaf.is_fixed());
        EXPECT_TRUE (leaf.is_leaf());
        leaf_pid = leaf.pid();

        generic_page dummy_p;
        ::memset (&dummy_p, 0, sizeof (generic_page));
        correct_checksum = leaf.get_generic_page()->calculate_checksum();
        EXPECT_NE (correct_checksum, dummy_p.calculate_checksum());
    }
    W_DO(ssm->commit_xct());

    // write out the page to set checksum by bufferpool
    smlevel_0::bf->wakeupPageCleaner();

    // check it again
    W_DO(ssm->begin_xct());
    {
        btree_page_h leaf;
        leaf.fix_direct(leaf_pid, LATCH_SH);
        W_DO (smlevel_0::vol->read_page(leaf_pid, leaf.get_generic_page()));
        EXPECT_TRUE (leaf.is_fixed());
        EXPECT_TRUE (leaf.is_leaf());
        EXPECT_FALSE (leaf.is_dirty());

        EXPECT_EQ (correct_checksum, leaf.get_generic_page()->calculate_checksum())
            << "page content has changed?";
        EXPECT_EQ (correct_checksum, leaf.get_generic_page()->checksum)
            << "checksum hasn't been updated on write?";
    }
    W_DO(ssm->commit_xct());

    return RCOK;
}