Untitled
unknown
c_cpp
2 years ago
7.4 kB
5
Indexable
//===----------------------------------------------------------------------===// // // BusTub // // seq_scan_executor.cpp // // Identification: src/execution/seq_scan_executor.cpp // // Copyright (c) 2015-2021, Carnegie Mellon University Database Group // //===----------------------------------------------------------------------===// #include "execution/executors/seq_scan_executor.h" // #include <_types/_uint32_t.h> // #include <sys/_types/_int64_t.h> #include <cstddef> #include <memory> #include <utility> #include "catalog/column.h" #include "common/config.h" #include "concurrency/transaction.h" #include "concurrency/transaction_manager.h" #include "storage/table/table_iterator.h" #include "storage/table/tuple.h" #include "type/type.h" namespace bustub { SeqScanExecutor::SeqScanExecutor(ExecutorContext *exec_ctx, const SeqScanPlanNode *plan) : AbstractExecutor(exec_ctx), plan_(plan) { table_info_ = exec_ctx->GetCatalog()->GetTable(plan_->GetTableOid()); } void SeqScanExecutor::Init() { /* need to get the table heap iterator, then iterate over the table one by one. When return from next, need to set the rid and the tuple */ // unique pointer to the table heap // auto table_heap_ = table_info_->table_; // std::cout << "IN INIT ~~~~~~~~~~~~~" << std::endl; table_iterator_ = std::make_unique<TableIterator>(table_info_->table_->MakeIterator()); } auto SeqScanExecutor::Next(Tuple *tuple, RID *rid) -> bool { // std::cout << "IN NEXT ==========" << std::endl; while (!table_iterator_->IsEnd()) { auto tmp_tuple_pair = table_iterator_->GetTuple(); *rid = table_iterator_->GetRID(); ++*table_iterator_; // skip tuples that don't satisfy the predicate if (plan_->filter_predicate_ != nullptr && !plan_->filter_predicate_->Evaluate(&tmp_tuple_pair.second, table_info_->schema_).GetAs<bool>()) { continue; } // std::cout << "=== tuple = " << tmp_tuple_pair.second.ToString(&plan_->OutputSchema()) << std::endl; // new if (IsMostRecentVersion(tmp_tuple_pair.first.ts_)) { // case 1: tuple in the heap is latest *tuple = tmp_tuple_pair.second; std::cout << "case 1" << std::endl; if (tmp_tuple_pair.first.is_deleted_) { continue; } return true; } if (IsTemporaryModify(tmp_tuple_pair.first.ts_)) { // case 2 // *tuple = RecoverPastVersion(tmp_tuple_pair.first.ts_, *rid); std::cout << "case 2" << std::endl; if (tmp_tuple_pair.first.is_deleted_) { continue; } *tuple = tmp_tuple_pair.second; return true; } auto p = IterateVersionChain(tmp_tuple_pair, *rid); if (p.second) { *tuple = p.first; std::cout << "case 3" << std::endl; // std::cout << p.first.ToString(&plan_->OutputSchema()); return true; } std::cout << "case 4" << std::endl; } std::cout << "return false ~~~~~~~~~~" << std::endl; return false; } auto SeqScanExecutor::IsMostRecentVersion(const timestamp_t ×tamp) -> bool { // std::cout << "heap current timestamp = " << static_cast<int64_t>(timestamp) << std::endl; // std::cout << "transaction read timestamp = " << exec_ctx_->GetTransaction()->GetReadTs() << std::endl; return timestamp <= exec_ctx_->GetTransaction()->GetReadTs(); } auto SeqScanExecutor::IsTemporaryModify(const timestamp_t ×tamp) -> bool { // auto mask = 0x8000000000000000; // std::cout << "***************" << std::endl; // std::cout << exec_ctx_->GetTransaction()->GetTransactionTempTs() << std::endl; // std::cout << exec_ctx_->GetTransaction()->GetReadTs() << std::endl; // std::cout << timestamp << std::endl; // std::cout << "&&&&&&&&&&&" << std::endl; return (exec_ctx_->GetTransaction()->GetTransactionTempTs() == timestamp); // return (timestamp & mask) != 0; } auto SeqScanExecutor::RecoverPastVersion(const timestamp_t ×tamp, RID rid) -> Tuple { TransactionManager *txn_manager = exec_ctx_->GetTransactionManager(); auto undo_link = txn_manager->GetUndoLink(rid); if (undo_link.has_value()) { auto undo_link_value = undo_link.value(); auto undo_log = txn_manager->GetUndoLog(undo_link_value); Tuple new_tuple = undo_log.tuple_; return new_tuple; } return Tuple{}; } auto SeqScanExecutor::IterateVersionChain(const std::pair<TupleMeta, Tuple> &p, RID rid) -> std::pair<Tuple, bool> { Tuple base_tuple = p.second; std::vector<Value> values; for (uint32_t i = 0; i < plan_->OutputSchema().GetColumnCount(); i++) { values.push_back(base_tuple.GetValue(&plan_->OutputSchema(), i)); } bool deleted = p.first.is_deleted_; auto undo_link_optional = exec_ctx_->GetTransactionManager()->GetUndoLink(rid); if (undo_link_optional.has_value()) { auto undo_link = undo_link_optional.value(); Tuple latest_tuple; bool found = false; while (undo_link.IsValid()) { auto undo_log_optional = exec_ctx_->GetTransactionManager()->GetUndoLogOptional(undo_link); if (undo_log_optional.has_value()) { // std::cout << "undo log optional has value" << std::endl; auto undo_log = undo_log_optional.value(); deleted = undo_log.is_deleted_; // std::cout << "[[[[[[[]]]]]]]] undo_log.ts = " << undo_log.ts_ << std::endl; int index = 0; auto modified = undo_log.modified_fields_; auto modified_tuple_data = undo_log.tuple_; int count_modified = 0; std::vector<Column> partial_column; for (uint32_t i = 0; i < modified.size(); i++) { if (modified[i]) { count_modified++; partial_column.push_back(plan_->OutputSchema().GetColumn(i)); } } Schema partial_schema(partial_column); std::vector<Value> modified_values(count_modified); for (int i = 0; i < count_modified; i++) { modified_values[i] = modified_tuple_data.GetValue(&partial_schema, i); } // std::cout << "[[[[[[[]]]]]]] undo_log.tuple = " << undo_log.tuple_.ToString(&partial_schema) << std::endl; for (uint32_t i = 0; i < modified.size(); i++) { if (modified[i]) { values[i] = modified_values[index]; index++; } } undo_link = undo_log.prev_version_; // if(exec_ctx_->GetTransaction()->GetReadTs() <= undo_log.ts_){ if (undo_log.ts_ <= exec_ctx_->GetTransaction()->GetReadTs()) { // std::cout << "txn read ts = " << exec_ctx_->GetTransaction()->GetReadTs() << std::endl; // std::cout << "undo_log.ts = " << undo_log.ts_ << std::endl; found = true; // ??? break; } } else { return std::make_pair(Tuple{}, false); } } if (deleted) { return std::make_pair(Tuple{}, false); } // std::cout << "found = " << found << std::endl; if (!found) { // std::cout << "not found at all" << std::endl; return std::make_pair(Tuple{}, false); } Tuple new_tuple(values, &plan_->OutputSchema()); return std::make_pair(new_tuple, true); } return std::make_pair(Tuple{}, false); } } // namespace bustub
Editor is loading...
Leave a Comment