diff --git a/src/execution/executor_fakeblocknestedloop_join.h b/src/execution/executor_fakeblocknestedloop_join.h index a00f997590c012f0d22fbbaaad421030ed85ad21..78c01bba7a996529fe687cb0ac4ceab6e1083c92 100644 --- a/src/execution/executor_fakeblocknestedloop_join.h +++ b/src/execution/executor_fakeblocknestedloop_join.h @@ -25,64 +25,34 @@ See the Mulan PSL v2 for more details. */ #include "executor_abstract.h" #include "system/sm_meta.h" +#include "execution/executor_utils.hpp" + class BlockNestedLoopJoinExecutor : public AbstractExecutor { private: std::unique_ptr<AbstractExecutor> left_; std::unique_ptr<AbstractExecutor> right_; size_t len_, left_len, right_len; - std::vector<ColMeta> cols_; // joinåŽèŽ·å¾—çš„è®°å½•çš„å—æ®µ - - int64_t current_buffer_pos; // pos in the vector -1 means not exist - static constexpr int MAX_BUFFER_SIZE = 2048; // block join buffer size - std::vector<std::unique_ptr<RmRecord>> buffer_vec_;// block join buffer + std::vector<ColMeta> cols_; - std::map< - std::pair<std::string, std::string>, - std::pair<bool, std::vector<ColMeta>::const_iterator> - > table_col_table; + static constexpr int MAX_BUFFER_SIZE = 2048; + bool left_isend = false; + size_t left_ptr = 0, left_size = 0; + std::array<std::unique_ptr<RmRecord>, MAX_BUFFER_SIZE> left_buffer; - bool is_join; std::vector<Condition> fed_conds_; - std::unique_ptr<RmRecord> current_; - - std::pair<bool, std::vector<ColMeta>::const_iterator> findByColMeta(const ColMeta &meta) { - return table_col_table[{meta.tab_name, meta.name}]; - } - - void getNextBlockBuffer() { - buffer_vec_.clear(); - for (size_t i = 0; i < MAX_BUFFER_SIZE && !left_->is_end(); i++, left_->nextTuple()) { - buffer_vec_.emplace_back(left_->Next()); - } - } - bool checkCondition(const std::unique_ptr<RmRecord> &left, const std::unique_ptr<RmRecord> &right) { - for (auto &cond: fed_conds_) { - auto lcol = get_col(cols_, cond.lhs_col); - Value lval; - lval.type = lcol->type; - lval.load_raw(lcol->len, left->data + lcol->offset); - - Value rval; - if (cond.is_rhs_val) { - rval = cond.rhs_val; - } else { - auto [_, rcol] = findByColMeta({cond.rhs_col.tab_name, cond.rhs_col.col_name}); - rval.type = rcol->type; - rval.load_raw(rcol->len, right->data + rcol->offset); - } - - if (!binop(cond.op, lval, rval)) - return false; + void load_left_buffer() { + left_ptr = 0; + left_isend = left_->is_end(); + for (left_size = 0; !left_->is_end() && left_size < MAX_BUFFER_SIZE; left_->nextTuple()) { + left_buffer[left_size++] = std::move(left_->Next()); } - return true; } public: - BlockNestedLoopJoinExecutor(std::unique_ptr<AbstractExecutor> left, std::unique_ptr<AbstractExecutor> right, - std::vector<Condition> conds) { + BlockNestedLoopJoinExecutor(std::unique_ptr<AbstractExecutor> left, std::unique_ptr<AbstractExecutor> right, std::vector<Condition> conds) { left_ = std::move(left); right_ = std::move(right); @@ -98,17 +68,6 @@ public: cols_.insert(cols_.end(), right_cols.begin(), right_cols.end()); fed_conds_ = std::move(conds); - is_join = (fed_conds_.size() > 0); - - for (size_t i = 0; i < left_->cols().size(); i++) { - const auto &vec = left_->cols(); - table_col_table[{vec[i].tab_name, vec[i].name}] = {true, left_->cols().begin() + i}; - } - for (size_t i = 0; i < right_->cols().size(); i++) { - const auto &vec = right_->cols(); - table_col_table[{vec[i].tab_name, vec[i].name}] = {false, right_->cols().begin() + i}; - } - current_buffer_pos = -2; } void beginTuple() override { @@ -118,58 +77,48 @@ public: right_->beginTuple(); if (right_->is_end()) return; - getNextBlockBuffer(); + load_left_buffer(); nextTuple(); } void nextTuple() override { - while (!(left_->is_end() && right_->is_end())) { - bool next = 0; - if (current_buffer_pos < 0) { - if (current_buffer_pos == -1) { - right_->nextTuple(); - if (right_->is_end() && left_->is_end()) { - return; - } - } + while (!left_isend || !right_->is_end()) { + if (left_ptr == left_size) { + right_->nextTuple(); + if (right_->is_end() && left_->is_end()) + return; if (right_->is_end()) { right_->beginTuple(); - getNextBlockBuffer(); + load_left_buffer(); } - current_buffer_pos = 0; } - for (; current_buffer_pos < buffer_vec_.size(); current_buffer_pos++) { - auto &left_rec = buffer_vec_[current_buffer_pos]; - auto right_rec = right_->Next(); - if (checkCondition(left_rec, right_rec)) { - current_ = std::make_unique<RmRecord>(len_); - for (auto col: cols_) { - auto [is_left, it] = table_col_table[{col.tab_name, col.name}]; - if (is_left) { - memcpy(current_->data + col.offset, left_rec->data + it->offset, it->len); - } else { - memcpy(current_->data + col.offset, right_rec->data + it->offset, it->len); - } - } - next = true; - break; - } + bool next = false; + for (; left_ptr < left_size; left_ptr += 1) { + if (!executor_utils::checkConds(this->Next(), fed_conds_, cols_)) + continue; + next = true; + break; } if (next) { - current_buffer_pos++; + left_ptr += 1; break; - } else { - current_buffer_pos = -1; } } } + virtual std::unique_ptr<RmRecord> Next() override { + auto current_record = std::make_unique<RmRecord>(len_); + std::copy_n(left_buffer[left_ptr]->data, left_len, current_record->data); + auto right_record = right_->Next(); + std::copy_n(right_record->data, right_len, current_record->data + left_len); + + return current_record; + } + bool is_end() const override { return left_->is_end() && right_->is_end(); } const std::vector<ColMeta> &cols() const override { return cols_; } - std::unique_ptr<RmRecord> Next() override { return std::make_unique<RmRecord>(*current_); } - size_t tupleLen() const override { return len_; } std::string getType() override { return "NestedLoopJoinExecutor"; };