-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Cleans up existing code and adds an execution engine to the system. Students are expected to implement the executors.
- Loading branch information
Showing
42 changed files
with
2,645 additions
and
378 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
#include "catalog/table_generator.h" | ||
|
||
#include <algorithm> | ||
#include <random> | ||
#include <vector> | ||
|
||
namespace bustub { | ||
|
||
template <typename CppType> | ||
std::vector<Value> TableGenerator::GenNumericValues(ColumnInsertMeta *col_meta, uint32_t count) { | ||
std::vector<Value> values; | ||
if (col_meta->dist_ == Dist::Serial) { | ||
for (uint32_t i = 0; i < count; i++) { | ||
values.emplace_back(Value(col_meta->type_, static_cast<CppType>(col_meta->serial_counter_))); | ||
col_meta->serial_counter_ += 1; | ||
} | ||
return values; | ||
} | ||
std::default_random_engine generator; | ||
// TODO(Amadou): Break up in two branches if this is too weird. | ||
std::conditional_t<std::is_integral_v<CppType>, std::uniform_int_distribution<CppType>, | ||
std::uniform_real_distribution<CppType>> | ||
distribution(static_cast<CppType>(col_meta->min_), static_cast<CppType>(col_meta->max_)); | ||
for (uint32_t i = 0; i < count; i++) { | ||
values.emplace_back(Value(col_meta->type_, distribution(generator))); | ||
} | ||
return values; | ||
} | ||
|
||
std::vector<Value> TableGenerator::MakeValues(ColumnInsertMeta *col_meta, uint32_t count) { | ||
std::vector<Value> values; | ||
switch (col_meta->type_) { | ||
case TypeId::TINYINT: | ||
return GenNumericValues<int8_t>(col_meta, count); | ||
case TypeId::SMALLINT: | ||
return GenNumericValues<int16_t>(col_meta, count); | ||
case TypeId::INTEGER: | ||
return GenNumericValues<int32_t>(col_meta, count); | ||
case TypeId::BIGINT: | ||
return GenNumericValues<int64_t>(col_meta, count); | ||
case TypeId::DECIMAL: | ||
return GenNumericValues<double>(col_meta, count); | ||
default: | ||
UNREACHABLE("Not yet implemented"); | ||
} | ||
} | ||
|
||
void TableGenerator::FillTable(TableMetadata *info, TableInsertMeta *table_meta) { | ||
uint32_t num_inserted = 0; | ||
uint32_t batch_size = 128; | ||
while (num_inserted < table_meta->num_rows_) { | ||
std::vector<std::vector<Value>> values; | ||
uint32_t num_values = std::min(batch_size, table_meta->num_rows_ - num_inserted); | ||
for (auto &col_meta : table_meta->col_meta_) { | ||
values.emplace_back(MakeValues(&col_meta, num_values)); | ||
} | ||
for (uint32_t i = 0; i < num_values; i++) { | ||
std::vector<Value> entry; | ||
entry.reserve(values.size()); | ||
for (const auto &col : values) { | ||
entry.emplace_back(col[i]); | ||
} | ||
RID rid; | ||
bool inserted = info->table_->InsertTuple(Tuple(entry, &info->schema_), &rid, exec_ctx_->GetTransaction()); | ||
BUSTUB_ASSERT(inserted, "Sequential insertion cannot fail"); | ||
num_inserted++; | ||
} | ||
// exec_ctx_->GetBufferPoolManager()->FlushAllPages(); | ||
} | ||
LOG_INFO("Wrote %d tuples to table %s.", num_inserted, table_meta->name_); | ||
} | ||
|
||
void TableGenerator::GenerateTestTables() { | ||
/** | ||
* This array configures each of the test tables. Each able is configured | ||
* with a name, size, and schema. We also configure the columns of the table. If | ||
* you add a new table, set it up here. | ||
*/ | ||
std::vector<TableInsertMeta> insert_meta{ | ||
// The empty table | ||
{"empty_table", 0, {{"colA", TypeId::INTEGER, false, Dist::Serial, 0, 0}}}, | ||
|
||
// Table 1 | ||
{"test_1", | ||
TEST1_SIZE, | ||
{{"colA", TypeId::INTEGER, false, Dist::Serial, 0, 0}, | ||
{"colB", TypeId::INTEGER, false, Dist::Uniform, 0, 9}, | ||
{"colC", TypeId::INTEGER, false, Dist::Uniform, 0, 9999}, | ||
{"colD", TypeId::INTEGER, false, Dist::Uniform, 0, 99999}}}, | ||
|
||
// Table 2 | ||
{"test_2", | ||
TEST2_SIZE, | ||
{{"col1", TypeId::SMALLINT, false, Dist::Serial, 0, 0}, | ||
{"col2", TypeId::INTEGER, true, Dist::Uniform, 0, 9}, | ||
{"col3", TypeId::BIGINT, false, Dist::Uniform, 0, 1024}, | ||
{"col4", TypeId::INTEGER, true, Dist::Uniform, 0, 2048}}}, | ||
|
||
// Empty table with two columns | ||
{"empty_table2", | ||
0, | ||
{{"colA", TypeId::INTEGER, false, Dist::Serial, 0, 0}, {"colB", TypeId::INTEGER, false, Dist::Uniform, 0, 9}}}, | ||
|
||
// Empty table with two columns | ||
{"empty_table3", | ||
0, | ||
{{"outA", TypeId::INTEGER, false, Dist::Serial, 0, 0}, {"outB", TypeId::INTEGER, false, Dist::Uniform, 0, 9}}}, | ||
}; | ||
|
||
for (auto &table_meta : insert_meta) { | ||
// Create Schema | ||
std::vector<Column> cols{}; | ||
cols.reserve(table_meta.col_meta_.size()); | ||
for (const auto &col_meta : table_meta.col_meta_) { | ||
if (col_meta.type_ != TypeId::VARCHAR) { | ||
cols.emplace_back(col_meta.name_, col_meta.type_); | ||
} else { | ||
cols.emplace_back(col_meta.name_, col_meta.type_, TEST_VARLEN_SIZE); | ||
} | ||
} | ||
Schema schema(cols); | ||
auto info = exec_ctx_->GetCatalog()->CreateTable(exec_ctx_->GetTransaction(), table_meta.name_, schema); | ||
FillTable(info, &table_meta); | ||
} | ||
} | ||
} // namespace bustub |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// BusTub | ||
// | ||
// executor_factory.cpp | ||
// | ||
// Identification: src/execution/executor_factory.cpp | ||
// | ||
// Copyright (c) 2015-2019, Carnegie Mellon University Database Group | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "execution/executor_factory.h" | ||
|
||
#include <memory> | ||
#include <utility> | ||
|
||
#include "execution/executors/abstract_executor.h" | ||
#include "execution/executors/aggregation_executor.h" | ||
#include "execution/executors/hash_join_executor.h" | ||
#include "execution/executors/insert_executor.h" | ||
#include "execution/executors/seq_scan_executor.h" | ||
|
||
namespace bustub { | ||
std::unique_ptr<AbstractExecutor> ExecutorFactory::CreateExecutor(ExecutorContext *exec_ctx, | ||
const AbstractPlanNode *plan) { | ||
switch (plan->GetType()) { | ||
// Create a new sequential scan executor. | ||
case PlanType::SeqScan: { | ||
return std::make_unique<SeqScanExecutor>(exec_ctx, dynamic_cast<const SeqScanPlanNode *>(plan)); | ||
} | ||
|
||
// Create a new insert executor. | ||
case PlanType::Insert: { | ||
auto insert_plan = dynamic_cast<const InsertPlanNode *>(plan); | ||
auto child_executor = | ||
insert_plan->IsRawInsert() ? nullptr : ExecutorFactory::CreateExecutor(exec_ctx, insert_plan->GetChildPlan()); | ||
return std::make_unique<InsertExecutor>(exec_ctx, insert_plan, std::move(child_executor)); | ||
} | ||
|
||
// Create a new hash join executor. | ||
case PlanType::HashJoin: { | ||
auto join_plan = dynamic_cast<const HashJoinPlanNode *>(plan); | ||
auto left_executor = ExecutorFactory::CreateExecutor(exec_ctx, join_plan->GetLeftPlan()); | ||
auto right_executor = ExecutorFactory::CreateExecutor(exec_ctx, join_plan->GetRightPlan()); | ||
return std::make_unique<HashJoinExecutor>(exec_ctx, join_plan, std::move(left_executor), | ||
std::move(right_executor)); | ||
} | ||
|
||
// Create a new aggregation executor. | ||
case PlanType::Aggregation: { | ||
auto agg_plan = dynamic_cast<const AggregationPlanNode *>(plan); | ||
auto child_executor = ExecutorFactory::CreateExecutor(exec_ctx, agg_plan->GetChildPlan()); | ||
return std::make_unique<AggregationExecutor>(exec_ctx, agg_plan, std::move(child_executor)); | ||
} | ||
|
||
default: { | ||
BUSTUB_ASSERT(false, "Unsupported plan type."); | ||
} | ||
} | ||
} | ||
} // namespace bustub |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
#pragma once | ||
|
||
#include <memory> | ||
#include <string> | ||
#include <unordered_map> | ||
#include <utility> | ||
|
||
#include "buffer/buffer_pool_manager.h" | ||
#include "catalog/schema.h" | ||
#include "storage/index/index.h" | ||
#include "storage/table/table_heap.h" | ||
|
||
namespace bustub { | ||
|
||
/** | ||
* Typedefs | ||
*/ | ||
using table_oid_t = uint32_t; | ||
using column_oid_t = uint32_t; | ||
|
||
/** | ||
* Metadata about a table. | ||
*/ | ||
struct TableMetadata { | ||
TableMetadata(Schema schema, std::string name, std::unique_ptr<TableHeap> &&table, table_oid_t oid) | ||
: schema_(std::move(schema)), name_(std::move(name)), table_(std::move(table)), oid_(oid) {} | ||
Schema schema_; | ||
std::string name_; | ||
std::unique_ptr<TableHeap> table_; | ||
table_oid_t oid_; | ||
}; | ||
|
||
/** | ||
* SimpleCatalog is a non-persistent catalog that is designed for the executor to use. | ||
* It handles table creation and table lookup. | ||
*/ | ||
class SimpleCatalog { | ||
public: | ||
/** | ||
* Creates a new catalog object. | ||
* @param bpm the buffer pool manager backing tables created by this catalog | ||
* @param lock_manager the lock manager in use by the system | ||
* @param log_manager the log manager in use by the system | ||
*/ | ||
SimpleCatalog(BufferPoolManager *bpm, LockManager *lock_manager, LogManager *log_manager) | ||
: bpm_{bpm}, lock_manager_{lock_manager}, log_manager_{log_manager} {} | ||
|
||
/** | ||
* Create a new table and return its metadata. | ||
* @param txn the transaction in which the table is being created | ||
* @param table_name the name of the new table | ||
* @param schema the schema of the new table | ||
* @return a pointer to the metadata of the new table | ||
*/ | ||
TableMetadata *CreateTable(Transaction *txn, const std::string &table_name, const Schema &schema) { | ||
BUSTUB_ASSERT(names_.count(table_name) == 0, "Table names should be unique!"); | ||
return nullptr; | ||
} | ||
|
||
/** @return table metadata by name */ | ||
TableMetadata *GetTable(const std::string &table_name) { return nullptr; } | ||
|
||
/** @return table metadata by oid */ | ||
TableMetadata *GetTable(table_oid_t table_oid) { return nullptr; } | ||
|
||
private: | ||
[[maybe_unused]] BufferPoolManager *bpm_; | ||
[[maybe_unused]] LockManager *lock_manager_; | ||
[[maybe_unused]] LogManager *log_manager_; | ||
|
||
/** tables_ : table identifiers -> table metadata. Note that tables_ owns all table metadata. */ | ||
std::unordered_map<table_oid_t, std::unique_ptr<TableMetadata>> tables_; | ||
/** names_ : table names -> table identifiers */ | ||
std::unordered_map<std::string, table_oid_t> names_; | ||
/** The next table identifier to be used. */ | ||
std::atomic<table_oid_t> next_table_oid_{0}; | ||
}; | ||
} // namespace bustub |
Oops, something went wrong.