diff --git a/src/include/storage/layout.h b/src/include/storage/layout.h index d2ec1f8072c..e05b1899e3f 100644 --- a/src/include/storage/layout.h +++ b/src/include/storage/layout.h @@ -141,4 +141,4 @@ class Layout : public Printable { }; } // namespace storage -} // namespace peloton \ No newline at end of file +} // namespace peloton diff --git a/src/include/tuning/layout_tuner.h b/src/include/tuning/layout_tuner.h index 5bcba99b6d7..14a6fe74e8d 100644 --- a/src/include/tuning/layout_tuner.h +++ b/src/include/tuning/layout_tuner.h @@ -87,8 +87,9 @@ class LayoutTuner { * Update layout of table * * @param table The table + * @return true if the update succeeds, false otherwise */ - void UpdateDefaultPartition(storage::DataTable *table); + bool UpdateDefaultPartition(storage::DataTable *table); private: /** diff --git a/src/tuning/layout_tuner.cpp b/src/tuning/layout_tuner.cpp index df64ea38bb4..a48fc64e564 100644 --- a/src/tuning/layout_tuner.cpp +++ b/src/tuning/layout_tuner.cpp @@ -76,7 +76,7 @@ Sample GetClustererSample(const Sample& sample, oid_t column_count) { return clusterer_sample; } -void LayoutTuner::UpdateDefaultPartition(storage::DataTable* table) { +bool LayoutTuner::UpdateDefaultPartition(storage::DataTable *table) { oid_t column_count = table->GetSchema()->GetColumnCount(); // Set up clusterer @@ -87,7 +87,9 @@ void LayoutTuner::UpdateDefaultPartition(storage::DataTable* table) { // Check if we have any samples if (samples.empty()) { - return; + LOG_DEBUG("Table[%u] contains no LayoutSamples. Layout not tuned.", + table->GetOid()); + return false; } for (auto sample : samples) { @@ -120,12 +122,13 @@ void LayoutTuner::UpdateDefaultPartition(storage::DataTable* table) { nullptr) { txn_manager.AbortTransaction(txn); LOG_DEBUG("Layout Update to failed."); - return; + return false; } txn_manager.CommitTransaction(txn); UNUSED_ATTRIBUTE auto layout = table->GetDefaultLayout(); LOG_TRACE("Updated Layout: %s", layout.GetInfo().c_str()); + return true; } void LayoutTuner::Tune() { @@ -142,7 +145,8 @@ void LayoutTuner::Tune() { table->TransformTileGroup(tile_group_offset, theta); // Update partitioning periodically - UpdateDefaultPartition(table); + // TODO Lin/Tianyu - Add Failure Handling/Retry logic. + UNUSED_ATTRIBUTE bool update_result = UpdateDefaultPartition(table); // Sleep a bit std::this_thread::sleep_for(std::chrono::microseconds(sleep_duration)); diff --git a/test/codegen/table_scan_translator_test.cpp b/test/codegen/table_scan_translator_test.cpp index f0373745192..3760745b48b 100644 --- a/test/codegen/table_scan_translator_test.cpp +++ b/test/codegen/table_scan_translator_test.cpp @@ -36,82 +36,10 @@ class TableScanTranslatorTest : public PelotonCodeGenTest { CreateAndLoadAllColsTable(); } - void ExecuteTileGroupTest(peloton::LayoutType layout_type) { - const int tuples_per_tilegroup = 100; - const int tile_group_count = 5; - const int tuple_count = tuples_per_tilegroup * tile_group_count; - const oid_t col_count = 100; - const bool is_inlined = true; - - ///////////////////////////////////////////////////////// - // Define the schema. - ///////////////////////////////////////////////////////// - - std::vector columns; - - for (oid_t col_itr = 0; col_itr <= col_count; col_itr++) { - auto column = catalog::Column( - type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "FIELD" + std::to_string(col_itr), is_inlined); - - columns.push_back(column); - } - - std::unique_ptr table_schema = - std::unique_ptr(new catalog::Schema(columns)); - std::string table_name("TEST_TABLE"); - - ///////////////////////////////////////////////////////// - // Create table. - ///////////////////////////////////////////////////////// - - bool is_catalog = false; - auto *catalog = catalog::Catalog::GetInstance(); - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - const bool allocate = true; - auto txn = txn_manager.BeginTransaction(); - - // Insert table in catalog - catalog->CreateTable(test_db_name, DEFAULT_SCHEMA_NAME, table_name, - std::move(table_schema), txn, is_catalog, - tuples_per_tilegroup, layout_type); - // Get table reference - auto table = catalog->GetTableWithName(test_db_name, DEFAULT_SCHEMA_NAME, - table_name, txn); - txn_manager.EndTransaction(txn); - - ///////////////////////////////////////////////////////// - // Load in the data - ///////////////////////////////////////////////////////// - - // Insert tuples into tile_group. - - txn = txn_manager.BeginTransaction(); - auto table_schema_ptr = table->GetSchema(); - auto testing_pool = TestingHarness::GetInstance().GetTestingPool(); - - for (oid_t row_id = 0; row_id < tuple_count; row_id++) { - int populate_value = row_id; - - storage::Tuple tuple(table_schema_ptr, allocate); - - for (oid_t col_id = 0; col_id <= col_count; col_id++) { - auto value = - type::ValueFactory::GetIntegerValue(populate_value + col_id); - tuple.SetValue(col_id, value, testing_pool); - } - - ItemPointer *index_entry_ptr = nullptr; - ItemPointer tuple_slot_id = - table->InsertTuple(&tuple, txn, &index_entry_ptr); - - EXPECT_TRUE(tuple_slot_id.block != INVALID_OID); - EXPECT_TRUE(tuple_slot_id.offset != INVALID_OID); - - txn_manager.PerformInsert(txn, tuple_slot_id, index_entry_ptr); - } - - txn_manager.CommitTransaction(txn); + void ScanLayoutTable(oid_t tuples_per_tilegroup, oid_t tilegroup_count, + oid_t column_count) { + auto table = GetLayoutTable(); + oid_t tuple_count = tuples_per_tilegroup * tilegroup_count; ///////////////////////////////////////////////////////// // Do a seq scan on the table with the given layout @@ -119,7 +47,7 @@ class TableScanTranslatorTest : public PelotonCodeGenTest { // Column ids to be scanned. std::vector column_ids; - for (oid_t col_id = 0; col_id < col_count; col_id++) { + for (oid_t col_id = 0; col_id < column_count; col_id++) { column_ids.push_back(col_id); } @@ -143,7 +71,7 @@ class TableScanTranslatorTest : public PelotonCodeGenTest { for (oid_t tuple_id = 0; tuple_id < tuple_count; tuple_id++) { auto &tuple = results[tuple_id]; int tuple_id_value = tuple_id; - for (oid_t col_id = 0; col_id < col_count; col_id++) { + for (oid_t col_id = 0; col_id < column_count; col_id++) { auto value = type::ValueFactory::GetIntegerValue(tuple_id_value + col_id); EXPECT_EQ(CmpBool::CmpTrue, @@ -706,7 +634,13 @@ TEST_F(TableScanTranslatorTest, ScanRowLayout) { // Creates a table with LayoutType::ROW and // invokes the TableScanTranslator // - ExecuteTileGroupTest(LayoutType::ROW); + oid_t tuples_per_tilegroup = 100; + oid_t tilegroup_count = 5; + oid_t column_count = 100; + bool is_inlined = true; + CreateAndLoadTableWithLayout(LayoutType::ROW, tuples_per_tilegroup, + tilegroup_count, column_count, is_inlined); + ScanLayoutTable(tuples_per_tilegroup, tilegroup_count, column_count); } TEST_F(TableScanTranslatorTest, ScanColumnLayout) { @@ -714,7 +648,13 @@ TEST_F(TableScanTranslatorTest, ScanColumnLayout) { // Creates a table with LayoutType::COLUMN and // invokes the TableScanTranslator // - ExecuteTileGroupTest(LayoutType::COLUMN); + oid_t tuples_per_tilegroup = 100; + oid_t tilegroup_count = 5; + oid_t column_count = 100; + bool is_inlined = true; + CreateAndLoadTableWithLayout(LayoutType::COLUMN, tuples_per_tilegroup, + tilegroup_count, column_count, is_inlined); + ScanLayoutTable(tuples_per_tilegroup, tilegroup_count, column_count); } TEST_F(TableScanTranslatorTest, MultiLayoutScan) { diff --git a/test/codegen/testing_codegen_util.cpp b/test/codegen/testing_codegen_util.cpp index dc46599010b..57231c245c7 100644 --- a/test/codegen/testing_codegen_util.cpp +++ b/test/codegen/testing_codegen_util.cpp @@ -32,7 +32,8 @@ namespace test { // PELOTON CODEGEN TEST //===----------------------------------------------------------------------===// -PelotonCodeGenTest::PelotonCodeGenTest(oid_t tuples_per_tilegroup) { +PelotonCodeGenTest::PelotonCodeGenTest(oid_t tuples_per_tilegroup, + peloton::LayoutType layout_type) { auto *catalog = catalog::Catalog::GetInstance(); auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto txn = txn_manager.BeginTransaction(); @@ -41,9 +42,10 @@ PelotonCodeGenTest::PelotonCodeGenTest(oid_t tuples_per_tilegroup) { catalog->CreateDatabase(test_db_name, txn); test_db = catalog->GetDatabaseWithName(test_db_name, txn); // Create test table - CreateTestTables(txn, tuples_per_tilegroup); + CreateTestTables(txn, tuples_per_tilegroup, layout_type); txn_manager.CommitTransaction(txn); + layout_table = nullptr; } PelotonCodeGenTest::~PelotonCodeGenTest() { @@ -103,13 +105,14 @@ std::unique_ptr PelotonCodeGenTest::CreateTestSchema( // Create all the test tables, but don't load any data void PelotonCodeGenTest::CreateTestTables(concurrency::TransactionContext *txn, - oid_t tuples_per_tilegroup) { + oid_t tuples_per_tilegroup, + peloton::LayoutType layout_type) { auto *catalog = catalog::Catalog::GetInstance(); for (int i = 0; i < 4; i++) { auto table_schema = CreateTestSchema(); catalog->CreateTable(test_db_name, DEFAULT_SCHEMA_NAME, test_table_names[i], std::move(table_schema), txn, false, - tuples_per_tilegroup); + tuples_per_tilegroup, layout_type); test_table_oids.push_back(catalog ->GetTableObject(test_db_name, DEFAULT_SCHEMA_NAME, @@ -120,7 +123,7 @@ void PelotonCodeGenTest::CreateTestTables(concurrency::TransactionContext *txn, auto table_schema = CreateTestSchema(true); catalog->CreateTable(test_db_name, DEFAULT_SCHEMA_NAME, test_table_names[i], std::move(table_schema), txn, false, - tuples_per_tilegroup); + tuples_per_tilegroup, layout_type); test_table_oids.push_back(catalog ->GetTableObject(test_db_name, DEFAULT_SCHEMA_NAME, @@ -175,6 +178,80 @@ void PelotonCodeGenTest::LoadTestTable(oid_t table_id, uint32_t num_rows, txn_manager.CommitTransaction(txn); } +void PelotonCodeGenTest::CreateAndLoadTableWithLayout( + peloton::LayoutType layout_type, oid_t tuples_per_tilegroup, + oid_t tile_group_count, oid_t column_count, bool is_inlined) { + oid_t tuple_count = tuples_per_tilegroup * tile_group_count; + ///////////////////////////////////////////////////////// + // Define the schema. + ///////////////////////////////////////////////////////// + + std::vector columns; + + for (oid_t col_itr = 0; col_itr <= column_count; col_itr++) { + auto column = catalog::Column( + type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), + "FIELD" + std::to_string(col_itr), is_inlined); + + columns.push_back(column); + } + + std::unique_ptr table_schema = + std::unique_ptr(new catalog::Schema(columns)); + std::string table_name("LAYOUT_TABLE"); + + ///////////////////////////////////////////////////////// + // Create table. + ///////////////////////////////////////////////////////// + + bool is_catalog = false; + auto *catalog = catalog::Catalog::GetInstance(); + auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); + const bool allocate = true; + auto txn = txn_manager.BeginTransaction(); + + // Insert table in catalog + catalog->CreateTable(test_db_name, DEFAULT_SCHEMA_NAME, table_name, + std::move(table_schema), txn, is_catalog, + tuples_per_tilegroup, layout_type); + // Get table reference + layout_table = catalog->GetTableWithName(test_db_name, DEFAULT_SCHEMA_NAME, + table_name, txn); + txn_manager.EndTransaction(txn); + + ///////////////////////////////////////////////////////// + // Load in the data + ///////////////////////////////////////////////////////// + + // Insert tuples into tile_group. + + txn = txn_manager.BeginTransaction(); + auto table_schema_ptr = layout_table->GetSchema(); + auto testing_pool = TestingHarness::GetInstance().GetTestingPool(); + + for (oid_t row_id = 0; row_id < tuple_count; row_id++) { + int populate_value = row_id; + + storage::Tuple tuple(table_schema_ptr, allocate); + + for (oid_t col_id = 0; col_id <= column_count; col_id++) { + auto value = type::ValueFactory::GetIntegerValue(populate_value + col_id); + tuple.SetValue(col_id, value, testing_pool); + } + + ItemPointer *index_entry_ptr = nullptr; + ItemPointer tuple_slot_id = + layout_table->InsertTuple(&tuple, txn, &index_entry_ptr); + + EXPECT_TRUE(tuple_slot_id.block != INVALID_OID); + EXPECT_TRUE(tuple_slot_id.offset != INVALID_OID); + + txn_manager.PerformInsert(txn, tuple_slot_id, index_entry_ptr); + } + + txn_manager.CommitTransaction(txn); +} + void PelotonCodeGenTest::ExecuteSync( codegen::Query &query, std::unique_ptr executor_context, diff --git a/test/include/codegen/testing_codegen_util.h b/test/include/codegen/testing_codegen_util.h index 7e5cd3ee20f..8234dfb0d2b 100644 --- a/test/include/codegen/testing_codegen_util.h +++ b/test/include/codegen/testing_codegen_util.h @@ -52,7 +52,8 @@ class PelotonCodeGenTest : public PelotonTest { "table4", "table5"}; std::vector test_table_oids; - PelotonCodeGenTest(oid_t tuples_per_tilegroup = DEFAULT_TUPLES_PER_TILEGROUP); + PelotonCodeGenTest(oid_t tuples_per_tilegroup = DEFAULT_TUPLES_PER_TILEGROUP, + peloton::LayoutType layout_type = LayoutType::ROW); virtual ~PelotonCodeGenTest(); @@ -64,6 +65,9 @@ class PelotonCodeGenTest : public PelotonTest { return *GetDatabase().GetTableWithOid(static_cast(table_id)); } + // Get the layout table + storage::DataTable *GetLayoutTable() const { return layout_table; } + // Create the schema (common among all tables) catalog::Column GetTestColumn(uint32_t col_id) const; @@ -71,14 +75,20 @@ class PelotonCodeGenTest : public PelotonTest { bool add_primary = false) const; // Create the test tables - void CreateTestTables( - concurrency::TransactionContext *txn, - oid_t tuples_per_tilegroup = DEFAULT_TUPLES_PER_TILEGROUP); + void CreateTestTables(concurrency::TransactionContext *txn, + oid_t tuples_per_tilegroup, + peloton::LayoutType layout_type); // Load the given table with the given number of rows void LoadTestTable(oid_t table_id, uint32_t num_rows, bool insert_nulls = false); + // Load tables with the specified layout + void CreateAndLoadTableWithLayout(peloton::LayoutType layout_type, + oid_t tuples_per_tilegroup, + oid_t tile_group_count, oid_t column_count, + bool is_inlined); + static void ExecuteSync( codegen::Query &query, std::unique_ptr executor_context, @@ -117,6 +127,7 @@ class PelotonCodeGenTest : public PelotonTest { private: storage::Database *test_db; + storage::DataTable *layout_table; }; //===----------------------------------------------------------------------===//