Branch data Line data Source code
1 : : #include <mutable/IR/PlanTable.hpp> 2 : : 3 : : #include <algorithm> 4 : : #include <cmath> 5 : : #include <iomanip> 6 : : #include <ios> 7 : : #include <mutable/catalog/Catalog.hpp> 8 : : #include <vector> 9 : : 10 : : 11 : : using namespace m; 12 : : 13 : : 14 : : /*---------------------------------------------------------------------------------------------------------------------- 15 : : * PlanTableSmallOrDense 16 : : *--------------------------------------------------------------------------------------------------------------------*/ 17 : : 18 : : M_LCOV_EXCL_START 19 : : std::ostream & m::operator<<(std::ostream &out, const PlanTableSmallOrDense &PT) 20 : : { 21 : : using std::setw; 22 : : 23 : : auto &C = Catalog::Get(); 24 : : auto &DB = C.get_database_in_use(); 25 : : auto &CE = DB.cardinality_estimator(); 26 : : 27 : : std::size_t num_sources = PT.num_sources(); 28 : : std::size_t n = 1UL << num_sources; 29 : : 30 : : /* Compute max length of columns. */ 31 : : auto &entry = PT.get_final(); 32 : : const uint64_t size_len = std::max<uint64_t>( 33 : : entry.model ? std::ceil(std::log10(CE.predict_cardinality(*entry.model))) : 0, 34 : : 4 35 : : ); 36 : : const uint64_t cost_len = std::isinf(entry.cost) 37 : : ? 3 // infinity will print as "inf", hence strlen("inf") 38 : : : std::max<uint64_t>(std::ceil(std::log10(entry.cost)), 4); 39 : : const uint64_t sub_len = std::max<uint64_t>(num_sources, 5); 40 : : 41 : : out << std::left << "Plan Table:\n" 42 : : << std::setw(num_sources) << "Sub" << " " 43 : : << std::setw(size_len) << "Size" << " " 44 : : << std::setw(cost_len) << "Cost" << " " 45 : : << std::setw(sub_len) << "Left" << " " 46 : : << std::setw(sub_len) << "Right" << '\n' << std::right; 47 : : 48 : : for (std::size_t i = 1; i < n; ++i) { 49 : : Subproblem sub(i); 50 : : sub.print_fixed_length(out, num_sources); 51 : : out << " ";; 52 : : if (PT.has_plan(sub)) { 53 : : if (PT.at(sub).model) 54 : : out << std::setw(size_len) << CE.predict_cardinality(*PT.at(sub).model); 55 : : else 56 : : out << std::setw(size_len) << '-'; 57 : : out << " " 58 : : << std::setw(cost_len) << PT.at(sub).cost << " " 59 : : << std::setw(sub_len) << uint64_t(PT.at(sub).left) << " " 60 : : << std::setw(sub_len) << uint64_t(PT.at(sub).right) << '\n'; 61 : : } else { 62 : : out << std::setw(size_len) << '-' << " " 63 : : << std::setw(cost_len) << '-' << " " 64 : : << std::setw(sub_len) << '-' << " " 65 : : << std::setw(sub_len) << '-' << '\n'; 66 : : } 67 : : } 68 : : return out; 69 : : } 70 : : 71 : : void PlanTableSmallOrDense::dump(std::ostream &out) const { out << *this; out.flush(); } 72 : : void PlanTableSmallOrDense::dump() const { dump(std::cerr); } 73 : : M_LCOV_EXCL_STOP 74 : 1 : 75 : : 76 : : /*---------------------------------------------------------------------------------------------------------------------- 77 : : * PlanTableLargeAndSparse 78 : : *--------------------------------------------------------------------------------------------------------------------*/ 79 : : 80 : : M_LCOV_EXCL_START 81 : : std::ostream & m::operator<<(std::ostream &out, const PlanTableLargeAndSparse &PT) 82 : : { 83 : : using std::setw; 84 : : 85 : : auto &C = Catalog::Get(); 86 : : auto &DB = C.get_database_in_use(); 87 : : auto &CE = DB.cardinality_estimator(); 88 : : 89 : : std::size_t num_sources = PT.num_sources(); 90 : : uint64_t n = 1UL << num_sources; 91 : : 92 : : /* Compute max length of columns. */ 93 : : auto &entry = PT.get_final(); 94 : : const uint64_t size_len = std::max<uint64_t>( 95 : : entry.model ? std::ceil(std::log10(CE.predict_cardinality(*entry.model))) : 0, 96 : : 4 97 : : ); 98 : : const uint64_t cost_len = std::max<uint64_t>(std::ceil(std::log10(entry.cost)), 4); 99 : : const uint64_t sub_len = std::max<uint64_t>(num_sources, 5); 100 : : 101 : : out << std::left << "Plan Table:\n" 102 : : << std::setw(num_sources) << "Sub" << " " 103 : : << std::setw(size_len) << "Size" << " " 104 : : << std::setw(cost_len) << "Cost" << " " 105 : : << std::setw(sub_len) << "Left" << " " 106 : : << std::setw(sub_len) << "Right" << '\n' << std::right; 107 : : 108 : : std::vector<std::pair<Subproblem, const PlanTableEntry*>> sorted_entries; 109 : : sorted_entries.reserve(PT.table_.size()); 110 : : 111 : : for (auto &e : PT.table_) { 112 : : if (uint64_t(e.first) > n) 113 : : continue; // skip additional entries 114 : : 115 : : auto pos = std::upper_bound(sorted_entries.begin(), sorted_entries.end(), e.first, 116 : : [](Subproblem s, const std::pair<Subproblem, const PlanTableEntry*> &elem) { 117 : : return uint64_t(s) < uint64_t(elem.first); 118 : : }); 119 : : sorted_entries.emplace(pos, e.first, &e.second); 120 : : } 121 : : 122 : : for (auto &elem : sorted_entries) { 123 : : Subproblem sub(elem.first); 124 : : sub.print_fixed_length(out, num_sources); 125 : : out << " ";; 126 : : if (PT.has_plan(sub)) { 127 : : if (elem.second->model) 128 : : out << std::setw(size_len) << CE.predict_cardinality(*(elem.second->model)); 129 : : else 130 : : out << std::setw(size_len) << '-'; 131 : : out << " " 132 : : << std::setw(cost_len) << elem.second->cost << " " 133 : : << std::setw(sub_len) << uint64_t(elem.second->left) << " " 134 : : << std::setw(sub_len) << uint64_t(elem.second->right) << '\n'; 135 : : } else { 136 : : out << std::setw(size_len) << '-' << " " 137 : : << std::setw(cost_len) << '-' << " " 138 : : << std::setw(sub_len) << '-' << " " 139 : : << std::setw(sub_len) << '-' << '\n'; 140 : : } 141 : : } 142 : : return out; 143 : : } 144 : : 145 : : void PlanTableLargeAndSparse::dump(std::ostream &out) const { out << *this; out.flush(); } 146 : : void PlanTableLargeAndSparse::dump() const { dump(std::cerr); } 147 : : M_LCOV_EXCL_STOP