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; }
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; }
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; }
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; }
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; }
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; }