indexes WIP
This commit is contained in:
153
table.cpp
153
table.cpp
@@ -19,9 +19,10 @@ Table::Table(const Table &other) {
|
||||
m_name = other.m_name;
|
||||
m_col_defs = other.m_col_defs;
|
||||
m_rows.reserve(other.m_rows.size());
|
||||
for(const Row& orig_row : other.m_rows) {
|
||||
commit_copy_of_row(orig_row);
|
||||
}
|
||||
|
||||
for(const Row& orig_row : other.m_rows)
|
||||
if (orig_row.is_visible())
|
||||
commit_copy_of_row((Row&)orig_row);
|
||||
}
|
||||
|
||||
ColDefNode Table::get_column_def(const std::string &col_name) {
|
||||
@@ -44,30 +45,39 @@ ColDefNode Table::get_column_def(int col_index) {
|
||||
}
|
||||
|
||||
Row& Table::create_empty_row() {
|
||||
m_rows.emplace_back(columns_count());
|
||||
m_rows.emplace_back(columns_count(), false);
|
||||
return m_rows.back();
|
||||
}
|
||||
|
||||
std::string Table::csv_string() {
|
||||
// header
|
||||
const size_t row_size_est = m_col_defs.size() * 16;
|
||||
|
||||
std::string out_string;
|
||||
out_string.reserve(m_rows.size() * row_size_est);
|
||||
// TODO improve it here https://www.cplusplus.com/reference/string/string/reserve/
|
||||
|
||||
// header
|
||||
for(int i = 0; i < m_col_defs.size(); i++) {
|
||||
if (i > 0) out_string += ",";
|
||||
out_string += m_col_defs[i].name;
|
||||
}
|
||||
|
||||
// rows
|
||||
for (auto & m_row : m_rows) {
|
||||
std::string csv_line{"\n"};
|
||||
for(int i = 0; i < m_col_defs.size(); i++) {
|
||||
if (i > 0) csv_line += ",";
|
||||
for (auto & row : m_rows) {
|
||||
if (row.is_visible()) {
|
||||
std::string csv_line{"\n"};
|
||||
csv_line.reserve(row_size_est);
|
||||
|
||||
auto & col = m_row[i];
|
||||
if (!col.isNull()) {
|
||||
csv_line += col.getStringValue(); // TODO handle enclosing commas etc
|
||||
for (int i = 0; i < m_col_defs.size(); i++) {
|
||||
if (i > 0) csv_line += ",";
|
||||
|
||||
auto &col = row[i];
|
||||
if (!col.isNull()) {
|
||||
csv_line += col.getStringValue(); // TODO handle enclosing commas etc
|
||||
}
|
||||
}
|
||||
out_string += csv_line;
|
||||
}
|
||||
out_string += csv_line;
|
||||
}
|
||||
|
||||
return out_string;
|
||||
@@ -89,18 +99,18 @@ int Table::load_csv_file(const std::string &filename) {
|
||||
int line_size = 128;
|
||||
|
||||
std::ifstream in(filename, std::ifstream::ate | std::ifstream::binary);
|
||||
auto file_size = in.tellg();
|
||||
auto file_size = in.tellg();
|
||||
|
||||
std::ifstream infile(filename);
|
||||
if (infile.good()) {
|
||||
std::string sLine;
|
||||
std::getline(infile, sLine);
|
||||
line_size = (int)sLine.size();
|
||||
line_size = (int)sLine.size() + 1;
|
||||
}
|
||||
infile.close();
|
||||
|
||||
if (file_size > 0) {
|
||||
auto new_size = m_rows.size() + int(file_size / line_size * 1.20);
|
||||
auto new_size = m_rows.size() + int((file_size / line_size) * 1.20);
|
||||
m_rows.reserve(new_size);
|
||||
}
|
||||
|
||||
@@ -116,7 +126,7 @@ void Table::create_row_from_vector(const std::vector<ColDefNode> &colDefs, const
|
||||
Row& new_row = create_empty_row();
|
||||
|
||||
// copy values
|
||||
for (int i = 0; i < std::min<int>(columns_count(), csv_line.size()); i++) {
|
||||
for (size_t i = 0; i < std::min<size_t>(columns_count(), csv_line.size()); i++) {
|
||||
const ColDefNode & col_def = colDefs[i];
|
||||
|
||||
if (csv_line[i].empty()) {
|
||||
@@ -181,16 +191,23 @@ void Table::print() {
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void Table::commit_row(const Row &row) {
|
||||
size_t Table::get_rowid(const Row &row) const {
|
||||
const Row* row_addr = (Row*)&row;
|
||||
const Row* begin_addr = &(*m_rows.begin());
|
||||
|
||||
return row_addr - begin_addr;
|
||||
}
|
||||
|
||||
void Table::commit_row(Row &row) {
|
||||
try {
|
||||
validate_row(row);
|
||||
index_row(row);
|
||||
} catch (Exception &e) {
|
||||
m_rows.erase(m_rows.end() - 1);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
void Table::commit_copy_of_row(const Row &row) {
|
||||
void Table::commit_copy_of_row(Row &row) {
|
||||
Row& new_row = create_empty_row();
|
||||
|
||||
for(int i = 0; i < m_col_defs.size(); i++) {
|
||||
@@ -215,6 +232,7 @@ void Table::commit_copy_of_row(const Row &row) {
|
||||
}
|
||||
|
||||
validate_row(new_row);
|
||||
index_row(row);
|
||||
}
|
||||
|
||||
void Table::validate_column(const ColDefNode *col_def, ValueNode *col_val) {
|
||||
@@ -235,26 +253,35 @@ void Table::validate_column(const ColDefNode *col_def, ColValue &col_val) {
|
||||
}
|
||||
}
|
||||
|
||||
void Table::validate_row(const Row &row) {
|
||||
void Table::validate_row(Row &row) {
|
||||
for(int i = 0; i < m_col_defs.size(); i++) {
|
||||
ColDefNode col_def = m_col_defs[i];
|
||||
ColValue &col_val = row[i];
|
||||
|
||||
validate_column(&col_def, col_val);
|
||||
}
|
||||
row.set_visible();
|
||||
}
|
||||
|
||||
void Table::create_index(const Index<IndexValue>& index) {
|
||||
m_indexes.push_back(index);
|
||||
}
|
||||
|
||||
void Table::drop_index(const std::string &column) {
|
||||
throw Exception("implement me! Table::drop_index(const std::string &column)");
|
||||
bool Table::drop_index(const std::string &index_name) {
|
||||
auto it = std::find_if(m_indexes.begin(), m_indexes.end(),
|
||||
[&index_name](const Index<IndexValue> &idx) {
|
||||
return idx.get_index_name() == index_name;
|
||||
});
|
||||
|
||||
if (it != m_indexes.end()) {
|
||||
m_indexes.erase(it);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Table::index_row(Index<IndexValue> &index, const Row &row, const size_t rowid) {
|
||||
ColDefNode col_def = get_column_def(index.get_column_name());
|
||||
|
||||
void Table::index_row(Index<IndexValue> &index, const ColDefNode &col_def, const Row &row, const size_t rowid) {
|
||||
if (col_def.type==ColumnType::integer_type) {
|
||||
index.insert(row[col_def.order].getIntValue(), rowid);
|
||||
} else if (col_def.type==ColumnType::varchar_type) {
|
||||
@@ -264,22 +291,65 @@ void Table::index_row(Index<IndexValue> &index, const Row &row, const size_t row
|
||||
}
|
||||
}
|
||||
|
||||
void Table::index_row(const Row &row, const size_t rowid) {
|
||||
for (auto &i : m_indexes) {
|
||||
index_row(i, row, rowid);
|
||||
void Table::unindex_row(Index<IndexValue> &index, const ColDefNode &col_def, const Row &row, const size_t rowid) {
|
||||
if (col_def.type==ColumnType::integer_type) {
|
||||
index.remove(row[col_def.order].getIntValue(), rowid);
|
||||
} else if (col_def.type==ColumnType::varchar_type) {
|
||||
index.remove(row[col_def.order].getStringValue(), rowid);
|
||||
} else {
|
||||
throw Exception("implement me! Table::index_row(const Row &row)");
|
||||
}
|
||||
}
|
||||
|
||||
void Table::reindex_row(Index<IndexValue> &index, const ColDefNode &col_def, const Row &old_row, const Row &new_row, size_t rowid) {
|
||||
unindex_row(index, col_def, old_row, rowid);
|
||||
index_row(index, col_def, new_row, rowid);
|
||||
}
|
||||
|
||||
|
||||
void Table::index_row(const Row &row) {
|
||||
if (!m_indexes.empty()) {
|
||||
const size_t rowid = get_rowid(row);
|
||||
for (auto &idx : m_indexes) {
|
||||
ColDefNode cDef = get_column_def(idx.get_column_name());
|
||||
index_row(idx, cDef, row, rowid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Table::unindex_row(const Row &row) {
|
||||
if (!m_indexes.empty()) {
|
||||
const size_t rowid = get_rowid(row);
|
||||
for (auto &idx : m_indexes) {
|
||||
ColDefNode cDef = get_column_def(idx.get_column_name());
|
||||
unindex_row(idx, cDef, row, rowid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Table::reindex_row(const Row &old_row, const Row &new_row) {
|
||||
if (!m_indexes.empty()) {
|
||||
const size_t rowid = get_rowid(new_row);
|
||||
for (auto &idx : m_indexes) {
|
||||
ColDefNode cDef = get_column_def(idx.get_column_name());
|
||||
reindex_row(idx, cDef, old_row, new_row, rowid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Table::index_rows(const std::string &index_name) {
|
||||
auto index = get_index(index_name);
|
||||
// TODO handle null pointer
|
||||
|
||||
ColDefNode cDef = get_column_def(index->get_column_name());
|
||||
size_t rowid = 0;
|
||||
for(const Row& r : m_rows) {
|
||||
index_row(*index, r, rowid);
|
||||
index_row(*index, cDef, r, rowid);
|
||||
rowid++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Index<IndexValue> * Table::get_index(const std::string &index_name) {
|
||||
auto it = std::find_if(m_indexes.begin(), m_indexes.end(),
|
||||
[&index_name](const Index<IndexValue> &idx) {
|
||||
@@ -303,4 +373,27 @@ Index<IndexValue> * Table::get_index_for_column(const std::string &col_name) {
|
||||
}
|
||||
|
||||
|
||||
Row *Table::rows_scanner::next() {
|
||||
if (m_use_rowids) {
|
||||
while (m_rowids_idx < m_rowids.size()) {
|
||||
auto row_ptr = &m_table->m_rows[m_rowids[m_rowids_idx]];
|
||||
if (row_ptr->is_visible()) {
|
||||
m_rowids_idx++;
|
||||
return row_ptr;
|
||||
}
|
||||
m_rowids_idx++;
|
||||
}
|
||||
} else {
|
||||
while (m_fscan_itr != m_table->m_rows.end()) {
|
||||
if (m_fscan_itr->is_visible()) {
|
||||
auto i = m_fscan_itr;
|
||||
m_fscan_itr++;
|
||||
return &(*i);
|
||||
}
|
||||
m_fscan_itr++;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user