-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
922 additions
and
0 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,27 @@ | ||
#include "abstract_operator.hpp" | ||
|
||
namespace opossum { | ||
|
||
AbstractOperator::AbstractOperator(const std::shared_ptr<const AbstractOperator> left, | ||
const std::shared_ptr<const AbstractOperator> right) | ||
: _left_input(left), _right_input(right) {} | ||
|
||
void AbstractOperator::execute() { | ||
_output = _on_execute(); | ||
} | ||
|
||
std::shared_ptr<const Table> AbstractOperator::get_output() const { | ||
// TODO(student): You should place some meaningful checks here | ||
|
||
return _output; | ||
} | ||
|
||
std::shared_ptr<const Table> AbstractOperator::_left_input_table() const { | ||
return _left_input->get_output(); | ||
} | ||
|
||
std::shared_ptr<const Table> AbstractOperator::_right_input_table() const { | ||
return _right_input->get_output(); | ||
} | ||
|
||
} // namespace opossum |
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,59 @@ | ||
#pragma once | ||
|
||
#include <memory> | ||
|
||
#include "types.hpp" | ||
|
||
namespace opossum { | ||
|
||
class Table; | ||
|
||
// AbstractOperator is the abstract super class for all operators. All operators have up to two input tables and one | ||
// output table. Their lifecycle has three phases: | ||
// 1. The operator is constructed. Previous operators are not guaranteed to have already executed, so operators must not | ||
// call get_output in their execute method | ||
// 2. The execute method is called from the outside (usually by the scheduler). This is where the heavy lifting is done. | ||
// By now, the input operators have already executed. | ||
// 3. The consumer (usually another operator) calls get_output. This should be very cheap. It is only guaranteed to | ||
// succeed if execute was called before. Otherwise, a nullptr or an empty table could be returned. | ||
// | ||
// Operators shall not be executed twice. | ||
|
||
class AbstractOperator : private Noncopyable { | ||
public: | ||
AbstractOperator(const std::shared_ptr<const AbstractOperator> left = nullptr, | ||
const std::shared_ptr<const AbstractOperator> right = nullptr); | ||
|
||
virtual ~AbstractOperator() = default; | ||
|
||
// We need to explicitly set the move constructor to default when we overwrite the copy constructor. | ||
AbstractOperator(AbstractOperator&&) = default; | ||
AbstractOperator& operator=(AbstractOperator&&) = default; | ||
|
||
void execute(); | ||
|
||
// Returns the result of the operator. | ||
std::shared_ptr<const Table> get_output() const; | ||
|
||
// Get the input operators. | ||
std::shared_ptr<const AbstractOperator> left_input() const; | ||
std::shared_ptr<const AbstractOperator> right_input() const; | ||
|
||
protected: | ||
// Abstract method to actually execute the operator execute and get_output are split into two methods to allow for | ||
// easier asynchronous execution. | ||
virtual std::shared_ptr<const Table> _on_execute() = 0; | ||
|
||
std::shared_ptr<const Table> _left_input_table() const; | ||
std::shared_ptr<const Table> _right_input_table() const; | ||
|
||
// Shared pointers to input operators. Can be nullptr, for example, if an operator is the leaf operator in the query | ||
// plan or if the operator has only one input operator. | ||
std::shared_ptr<const AbstractOperator> _left_input; | ||
std::shared_ptr<const AbstractOperator> _right_input; | ||
|
||
// Is nullptr until the operator is executed. | ||
std::shared_ptr<const Table> _output; | ||
}; | ||
|
||
} // namespace opossum |
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,27 @@ | ||
#pragma once | ||
|
||
#include "abstract_operator.hpp" | ||
#include "utils/assert.hpp" | ||
|
||
namespace opossum { | ||
|
||
// Operator to retrieve a table from the StorageManager by specifying its name. | ||
class GetTable : public AbstractOperator { | ||
public: | ||
explicit GetTable(const std::string& name) { | ||
// TODO(student) implement it in a source file and change this to a declaration. | ||
} | ||
|
||
const std::string& table_name() const { | ||
// TODO(student) implement it in a source file and change this to a declaration. | ||
Fail("Implementation missing."); | ||
} | ||
|
||
protected: | ||
std::shared_ptr<const Table> _on_execute() override { | ||
// TODO(student) implement it in a source file and change this to a declaration. | ||
Fail("Implementation missing."); | ||
} | ||
}; | ||
|
||
} // namespace opossum |
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,110 @@ | ||
#include "print.hpp" | ||
|
||
#include <iomanip> | ||
|
||
#include "operators/table_wrapper.hpp" | ||
#include "storage/abstract_segment.hpp" | ||
#include "storage/table.hpp" | ||
#include "type_cast.hpp" | ||
|
||
namespace { | ||
|
||
using namespace opossum; // NOLINT(build/namespaces) | ||
|
||
std::string print_column_type(const std::shared_ptr<const Table>& table, const ColumnID column_id) { | ||
auto stream = std::stringstream{}; | ||
stream << table->column_type(column_id); | ||
if (table->column_nullable(column_id)) { | ||
stream << "_null"; | ||
} | ||
|
||
return stream.str(); | ||
} | ||
|
||
} // namespace | ||
|
||
namespace opossum { | ||
|
||
Print::Print(const std::shared_ptr<const AbstractOperator> in, std::ostream& out) : AbstractOperator(in), _out(out) {} | ||
|
||
void Print::print(std::shared_ptr<const Table>& table, std::ostream& out) { | ||
auto table_wrapper = std::make_shared<TableWrapper>(table); | ||
table_wrapper->execute(); | ||
Print(table_wrapper, out).execute(); | ||
} | ||
|
||
std::shared_ptr<const Table> Print::_on_execute() { | ||
auto widths = _column_string_widths(8, 20, _left_input_table()); | ||
|
||
// Print column headers. | ||
_out << "=== Columns" << std::endl; | ||
const auto left_column_count = _left_input_table()->column_count(); | ||
for (auto column_id = ColumnID{0}; column_id < left_column_count; ++column_id) { | ||
_out << "|" << std::setw(widths[column_id]) << _left_input_table()->column_name(column_id) << std::setw(0); | ||
} | ||
_out << "|" << std::endl; | ||
for (auto column_id = ColumnID{0}; column_id < left_column_count; ++column_id) { | ||
_out << "|" << std::setw(widths[column_id]) << print_column_type(_left_input_table(), column_id) << std::setw(0); | ||
} | ||
_out << "|" << std::endl; | ||
|
||
// print each chunk | ||
const auto left_chunk_count = _left_input_table()->chunk_count(); | ||
for (auto chunk_id = ChunkID{0}; chunk_id < left_chunk_count; ++chunk_id) { | ||
const auto chunk = _left_input_table()->get_chunk(chunk_id); | ||
|
||
_out << "=== Chunk " << chunk_id << " === " << std::endl; | ||
|
||
if (chunk->size() == 0) { | ||
_out << "Empty chunk." << std::endl; | ||
continue; | ||
} | ||
|
||
// Print the rows in the chunk. | ||
const auto chunk_size = chunk->size(); | ||
for (size_t row = 0; row < chunk_size; ++row) { | ||
_out << "|"; | ||
const auto column_count = chunk->column_count(); | ||
for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { | ||
// Yes, we use AbstractSegment::operator[] here, but since Print is not an operation that should be part of a | ||
// regular query plan, let's keep things simple here. | ||
_out << std::setw(widths[column_id]) << (*chunk->get_segment(column_id))[row] << "|" << std::setw(0); | ||
} | ||
|
||
_out << std::endl; | ||
} | ||
} | ||
|
||
return _left_input_table(); | ||
} | ||
|
||
// In order to print the table as an actual table, with columns being aligned, we need to calculate the number of | ||
// characters in the printed representation of each column `min` and `max` can be used to limit the width of the | ||
// columns - however, every column fits at least the column's name. | ||
std::vector<uint16_t> Print::_column_string_widths(uint16_t min, uint16_t max, | ||
const std::shared_ptr<const Table>& table) const { | ||
auto widths = std::vector<uint16_t>(table->column_count()); | ||
// Calculate the length of the column name. | ||
const auto column_count = table->column_count(); | ||
for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { | ||
widths[column_id] = std::max(min, static_cast<uint16_t>(table->column_name(column_id).size())); | ||
} | ||
|
||
// Go over all rows and find the maximum length of the printed representation of a value, up to max. | ||
const auto left_chunk_count = _left_input_table()->chunk_count(); | ||
for (auto chunk_id = ChunkID{0}; chunk_id < left_chunk_count; ++chunk_id) { | ||
auto chunk = _left_input_table()->get_chunk(chunk_id); | ||
|
||
const auto column_count = chunk->column_count(); | ||
for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { | ||
for (auto row = size_t{0}; row < chunk->size(); ++row) { | ||
auto cell_length = | ||
static_cast<uint16_t>(boost::lexical_cast<std::string>((*chunk->get_segment(column_id))[row]).size()); | ||
widths[column_id] = std::max({min, widths[column_id], std::min(max, cell_length)}); | ||
} | ||
} | ||
} | ||
return widths; | ||
} | ||
|
||
} // namespace opossum |
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,24 @@ | ||
#pragma once | ||
|
||
#include "abstract_operator.hpp" | ||
|
||
namespace opossum { | ||
|
||
/** | ||
* operator to print the table with its data | ||
*/ | ||
class Print : public AbstractOperator { | ||
public: | ||
explicit Print(const std::shared_ptr<const AbstractOperator> in, std::ostream& out = std::cout); | ||
|
||
static void print(std::shared_ptr<const Table>& table, std::ostream& out = std::cout); | ||
|
||
protected: | ||
std::vector<uint16_t> _column_string_widths(uint16_t min, uint16_t max, | ||
const std::shared_ptr<const Table>& table) const; | ||
std::shared_ptr<const Table> _on_execute() override; | ||
|
||
// stream to print the result | ||
std::ostream& _out; | ||
}; | ||
} // namespace opossum |
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,37 @@ | ||
#pragma once | ||
|
||
#include "abstract_operator.hpp" | ||
#include "utils/assert.hpp" | ||
|
||
namespace opossum { | ||
|
||
class TableScan : public AbstractOperator { | ||
public: | ||
TableScan(const std::shared_ptr<const AbstractOperator>& in, const ColumnID column_id, const ScanType scan_type, | ||
const AllTypeVariant search_value) { | ||
// TODO(student) implement it in a source file and change this to a declaration. | ||
} | ||
|
||
ColumnID column_id() const { | ||
// TODO(student) implement it in a source file and change this to a declaration. | ||
Fail("Implementation missing."); | ||
} | ||
|
||
ScanType scan_type() const { | ||
// TODO(student) implement it in a source file and change this to a declaration. | ||
Fail("Implementation missing."); | ||
} | ||
|
||
const AllTypeVariant& search_value() const { | ||
// TODO(student) implement it in a source file and change this to a declaration. | ||
Fail("Implementation missing."); | ||
} | ||
|
||
protected: | ||
std::shared_ptr<const Table> _on_execute() override { | ||
// TODO(student) implement it in a source file and change this to a declaration. | ||
Fail("Implementation missing."); | ||
} | ||
}; | ||
|
||
} // namespace opossum |
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,10 @@ | ||
#include "table_wrapper.hpp" | ||
|
||
namespace opossum { | ||
|
||
TableWrapper::TableWrapper(const std::shared_ptr<const Table>& table) : _table(table) {} | ||
|
||
std::shared_ptr<const Table> TableWrapper::_on_execute() { | ||
return _table; | ||
} | ||
} // namespace opossum |
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,21 @@ | ||
#pragma once | ||
|
||
#include "abstract_operator.hpp" | ||
#include "utils/assert.hpp" | ||
|
||
namespace opossum { | ||
|
||
/** | ||
* Operator that wraps a table. | ||
*/ | ||
class TableWrapper : public AbstractOperator { | ||
public: | ||
explicit TableWrapper(const std::shared_ptr<const Table>& table); | ||
|
||
protected: | ||
std::shared_ptr<const Table> _on_execute() override; | ||
|
||
// Table to retrieve | ||
const std::shared_ptr<const Table> _table; | ||
}; | ||
} // namespace opossum |
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,43 @@ | ||
#include "reference_segment.hpp" | ||
|
||
#include "storage/table.hpp" | ||
#include "utils/assert.hpp" | ||
|
||
namespace opossum { | ||
|
||
ReferenceSegment::ReferenceSegment(const std::shared_ptr<const Table>& referenced_table, | ||
const ColumnID referenced_column_id, const std::shared_ptr<const PosList>& pos) { | ||
// Implementation goes here | ||
} | ||
|
||
AllTypeVariant ReferenceSegment::operator[](const ChunkOffset chunk_offset) const { | ||
// Implementation goes here | ||
Fail("Implementation is missing."); | ||
} | ||
|
||
ChunkOffset ReferenceSegment::size() const { | ||
// Implementation goes here | ||
Fail("Implementation is missing."); | ||
} | ||
|
||
const std::shared_ptr<const PosList>& ReferenceSegment::pos_list() const { | ||
// Implementation goes here | ||
Fail("Implementation is missing."); | ||
} | ||
|
||
const std::shared_ptr<const Table>& ReferenceSegment::referenced_table() const { | ||
// Implementation goes here | ||
Fail("Implementation is missing."); | ||
} | ||
|
||
ColumnID ReferenceSegment::referenced_column_id() const { | ||
// Implementation goes here | ||
Fail("Implementation is missing."); | ||
} | ||
|
||
size_t ReferenceSegment::estimate_memory_usage() const { | ||
// Implementation goes here | ||
Fail("Implementation is missing."); | ||
} | ||
|
||
} // namespace opossum |
Oops, something went wrong.