void RunBackend(oid_t thread_id) { auto txn_count = state.transaction_count; auto update_ratio = state.update_ratio; UniformGenerator generator; Timer<> timer; // Start timer timer.Reset(); timer.Start(); // Run these many transactions for (oid_t txn_itr = 0; txn_itr < txn_count; txn_itr++) { auto rng_val = generator.GetSample(); if (rng_val < update_ratio) { RunUpdate(); } else { RunRead(); } } // Stop timer timer.Stop(); // Set duration durations[thread_id] = timer.GetDuration(); }
void RunBackend(oid_t thread_id) { auto txn_count = state.transaction_count; UniformGenerator generator; Timer<> timer; // Start timer timer.Reset(); timer.Start(); // Run these many transactions for (oid_t txn_itr = 0; txn_itr < txn_count; txn_itr++) { auto rng_val = generator.GetSample(); if (rng_val <= 0.04) { RunStockLevel(); } else if (rng_val <= 0.08) { RunDelivery(); } else if (rng_val <= 0.12) { RunOrderStatus(); } else if (rng_val <= 0.55) { RunPayment(); } else { RunNewOrder(); } } // Stop timer timer.Stop(); // Set duration durations[thread_id] = timer.GetDuration(); }
void RunBackend(oid_t thread_id) { auto update_ratio = state.update_ratio; UniformGenerator generator; oid_t &execution_count_ref = abort_counts[thread_id]; oid_t &transaction_count_ref = commit_counts[thread_id]; // Run these many transactions while (true) { if (is_running == false) { break; } auto rng_val = generator.GetSample(); if (rng_val < update_ratio) { while (RunUpdate() == false) { execution_count_ref++; } } else { while (RunRead() == false) { execution_count_ref++; } } transaction_count_ref++; } }
void RunBackend(oid_t thread_id) { UniformGenerator generator; oid_t &execution_count_ref = abort_counts[thread_id]; oid_t &transaction_count_ref = commit_counts[thread_id]; // Run these many transactions while (true) { if (is_running == false) { break; } auto rng_val = generator.GetSample(); if (rng_val <= 0.04) { while (RunStockLevel() == false) { execution_count_ref++; } } else if (rng_val <= 0.08) { while (RunDelivery() == false) { execution_count_ref++; } } else if (rng_val <= 0.12) { while (RunOrderStatus() == false) { execution_count_ref++; } } else if (rng_val <= 0.55) { while (RunPayment() == false) { execution_count_ref++; } } else { while (RunNewOrder() == false) { execution_count_ref++; } } transaction_count_ref++; } }
TEST_F(LayoutTunerTests, BasicTest) { const int tuple_count = TESTS_TUPLES_PER_TILEGROUP; std::string db_name = "test_db"; TestingExecutorUtil::InitializeDatabase(db_name); auto data_table = TestingExecutorUtil::CreateTableUpdateCatalog(tuple_count, db_name); // Create a table and populate it auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto txn = txn_manager.BeginTransaction(); TestingExecutorUtil::PopulateTable(data_table, tuple_count, false, false, true, txn); txn_manager.CommitTransaction(txn); // Check column count oid_t column_count = data_table->GetSchema()->GetColumnCount(); EXPECT_EQ(column_count, 4); // Layout tuner tuning::LayoutTuner &layout_tuner = tuning::LayoutTuner::GetInstance(); // Attach table to index tuner layout_tuner.AddTable(data_table); // Check old default tile group layout auto old_default_layout = data_table->GetDefaultLayout(); LOG_INFO("Layout: %s", old_default_layout->GetColumnMapInfo().c_str()); // Start layout tuner layout_tuner.Start(); std::vector<double> columns_accessed(column_count, 0); double sample_weight; // initialize a uniform distribution between 0 and 1 UniformGenerator generator; for (int sample_itr = 0; sample_itr < 10000; sample_itr++) { auto rng_val = generator.GetSample(); if (rng_val < 0.9) { columns_accessed = {0, 1, 2}; sample_weight = 100; } else { columns_accessed = {3}; sample_weight = 10; } // Create a table access sample // Indicates the columns accessed (bitmap), and query weight tuning::Sample sample(columns_accessed, sample_weight); // Collect layout sample in table data_table->RecordLayoutSample(sample); // Periodically sleep a bit // Layout tuner thread will process the layout samples periodically, // derive the new table layout, and // transform the layout of existing tile groups in the table if(sample_itr % 100 == 0 ){ std::this_thread::sleep_for(std::chrono::microseconds(1000)); } } // Stop layout tuner layout_tuner.Stop(); // Detach all tables from layout tuner layout_tuner.ClearTables(); // Check new default tile group layout auto new_default_layout = data_table->GetDefaultLayout(); LOG_INFO("Layout: %s", new_default_layout->GetColumnMapInfo().c_str()); // Ensure that the layout has been changed EXPECT_NE(*new_default_layout, *old_default_layout); // Check the new default table layout column_count = new_default_layout->GetColumnCount(); EXPECT_EQ(column_count, 4); // Check the tile corresponding to each column. EXPECT_EQ(new_default_layout->GetTileIdFromColumnId(0), 0); EXPECT_EQ(new_default_layout->GetTileIdFromColumnId(1), 0); EXPECT_EQ(new_default_layout->GetTileIdFromColumnId(2), 0); EXPECT_EQ(new_default_layout->GetTileIdFromColumnId(3), 1); // Check the per tile stats of the new layout // The layout must contain 2 tiles with the following stats // 0 -> 3 // 1 -> 1 auto layout_stats = new_default_layout->GetLayoutStats(); EXPECT_EQ(layout_stats[0], 3); EXPECT_EQ(layout_stats[1], 1); TestingExecutorUtil::DeleteDatabase(db_name); }
TEST_F(IndexTunerTests, BasicTest) { const int tuple_count = TESTS_TUPLES_PER_TILEGROUP; // Create a table and populate it auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto txn = txn_manager.BeginTransaction(); std::unique_ptr<storage::DataTable> data_table( TestingExecutorUtil::CreateTable(tuple_count, false)); TestingExecutorUtil::PopulateTable(data_table.get(), tuple_count, false, false, true, txn); txn_manager.CommitTransaction(txn); // Check column count oid_t column_count = data_table->GetSchema()->GetColumnCount(); EXPECT_EQ(column_count, 4); // Index tuner tuning::IndexTuner &index_tuner = tuning::IndexTuner::GetInstance(); // Attach table to index tuner index_tuner.AddTable(data_table.get()); // Check old index count auto old_index_count = data_table->GetIndexCount(); EXPECT_TRUE(old_index_count == 0); LOG_INFO("Index Count: %u", old_index_count); // Start index tuner index_tuner.Start(); std::vector<double> columns_accessed(column_count, 0); double sample_weight; UniformGenerator generator; for (int sample_itr = 0; sample_itr < 10000; sample_itr++) { auto rng_val = generator.GetSample(); if (rng_val < 0.6) { columns_accessed = {0, 1, 2}; sample_weight = 100; } else if (rng_val < 0.9) { columns_accessed = {0, 2}; sample_weight = 10; } else { columns_accessed = {0, 1}; sample_weight = 10; } // Create a table access sample // Indicates the columns present in predicate, query weight, and selectivity tuning::Sample sample(columns_accessed, sample_weight, tuning::SampleType::ACCESS); // Collect index sample in table data_table->RecordIndexSample(sample); // Periodically sleep a bit // Index tuner thread will process the index samples periodically, // and materialize the appropriate ad-hoc indexes if(sample_itr % 100 == 0 ){ std::this_thread::sleep_for(std::chrono::microseconds(10000)); } } // Wait for tuner to build indexes sleep(5); // Stop index tuner index_tuner.Stop(); // Detach all tables from index tuner index_tuner.ClearTables(); // Check new index count auto new_index_count = data_table->GetIndexCount(); LOG_INFO("Index Count: %u", new_index_count); EXPECT_TRUE(new_index_count != old_index_count); EXPECT_TRUE(new_index_count == 3); // Check candidate indices to ensure that // all the ad-hoc indexes are materialized std::vector<std::set<oid_t>> candidate_indices; candidate_indices.push_back({0, 1, 2}); candidate_indices.push_back({0, 2}); candidate_indices.push_back({0, 1}); for (auto candidate_index : candidate_indices) { bool candidate_index_found = false; oid_t index_itr; for (index_itr = 0; index_itr < new_index_count; index_itr++) { // Check attributes auto index_attrs = data_table->GetIndexAttrs(index_itr); if (index_attrs != candidate_index) { continue; } // Exact match candidate_index_found = true; break; } EXPECT_TRUE(candidate_index_found); } }