7#include <mutable/mutable-config.hpp>
11#include <unordered_map>
22 crtp_args<PlanTableSmallOrDense&, PlanTableLargeAndSparse&>::
23 args<const QueryGraph&, const CostFunction&> { };
29 using enumerate_tag::base_type::operator();
34 template<
typename PlanTable>
40template<
typename Actual>
42 , enumerate_tag::derived_type<Actual>
44 using PlanEnumerator::operator();
51 using base_type::operator();
53 template<
typename PlanTable>
61 using base_type::operator();
70 : subproblem(subproblem), neighbors(neighbors)
76 return bool(this->subproblem & other.
neighbors);
92 bool operator&(
const node &other)
const {
return can_merge_with(other); }
96 template<
typename Callback,
typename PlanTable>
101 while (begin + 1 != end) {
105 node *left =
nullptr, *right =
nullptr;
106 double least_cardinality = std::numeric_limits<double>::infinity();
107 for (
node *outer = begin; outer != end; ++outer) {
108 for (
node *inner = std::next(outer); inner != end; ++inner) {
109 if (*outer & *inner) {
110 M_insist((outer->subproblem & inner->subproblem).empty());
112 const Subproblem joined = outer->subproblem | inner->subproblem;
113 if (not PT[joined].model)
114 PT[joined].model = CE.
estimate_join(G, *PT[outer->subproblem].model,
115 *PT[inner->subproblem].model, condition);
117 if (C_joined < least_cardinality) {
118 least_cardinality = C_joined;
129 callback(left->
subproblem, right->subproblem);
136 swap(*right, *--end);
139 template<
typename PlanTable>
146 PT.update(G, CE, CF, left, right, condition);
147 }, PT, G, M, CF, CE, begin, end);
150 template<
typename PlanTable>
158 using base_type::operator();
162 template<
typename Callback,
typename PlanTable>
166 std::vector<Subproblem> worklist(std::move(subproblems));
168 std::vector<std::pair<Subproblem, Subproblem>> joins;
171 while (not worklist.empty()) {
177 double C_min = std::numeric_limits<
decltype(C_min)>::infinity();
180 if (not PT[left].model)
182 if (not PT[right].model)
196 joins.emplace_back(min_left, min_right);
198 worklist.emplace_back(min_left);
199 worklist.emplace_back(min_right);
203 for (
auto it = joins.crbegin(); it != joins.crend(); ++it)
204 callback(it->first, it->second);
207 template<
typename PlanTable>
void swap(PlanTableBase< Actual > &first, PlanTableBase< Actual > &second)
An adjacency matrix for a given query graph.
bool is_connected(SmallBitset S) const
Returns true iff the subproblem S is connected.
std::unique_ptr< DataModel > estimate_join_all(const QueryGraph &G, const PlanTable &PT, Subproblem to_join, const cnf::CNF &condition) const
Compute a DataModel for the result of joining all DataSources in to_join by condition.
virtual std::unique_ptr< DataModel > estimate_join(const QueryGraph &G, const DataModel &left, const DataModel &right, const cnf::CNF &condition) const =0
Form a new DataModel by joining two DataModels.
virtual std::size_t predict_cardinality(const DataModel &data) const =0
void partition(const AdjacencyMatrix &M, Callback &&callback, const Subproblem S) const
The query graph represents all data sources and joins in a graph structure.
std::size_t num_sources() const
Returns the number of DataSources in this graph.
Implements a small and efficient set over integers in the range of 0 to 63 (including).
bool is_singleton() const
bool empty() const
Returns true if there are no elements in this SmallBitset.
A helper class to introduce a virtual method overload per type to a class hierarchy.
A CNF represents a conjunction of cnf::Clauses.
Computes the join order using connected subgraph complement pairs (CCP).
node operator+(const node &other) const
Merges this and other.
node merge(const node &other) const
Merge two nodes.
node(Subproblem subproblem, Subproblem neighbors)
bool can_merge_with(const node &other) const
Checks whether two nodes can be merged.
bool operator&(const node &other) const
Checks whether this node node can be merged with other.
node & operator+=(const node &other)
Merges other into this node.
Greedy operator ordering.
void for_each_join(Callback &&callback, PlanTable &PT, const QueryGraph &G, const AdjacencyMatrix &M, const CostFunction &, const CardinalityEstimator &CE, node *begin, node *end) const
Enumerate the sequence of joins that yield the smallest subproblem in each step.
void compute_plan(PlanTable &PT, const QueryGraph &G, const AdjacencyMatrix &M, const CostFunction &CF, const CardinalityEstimator &CE, node *begin, node *end) const
An interface for all plan enumerators.
void operator()(const QueryGraph &G, const CostFunction &CF, PlanTable &PT) const
Enumerate subplans and fill plan table.
virtual ~PlanEnumerator()
Top-down version of greedy operator ordering.
void for_each_join(Callback &&callback, PlanTable &PT, const QueryGraph &G, const AdjacencyMatrix &M, const CostFunction &, const CardinalityEstimator &CE, std::vector< Subproblem > subproblems) const
Enumerate the sequence of graph cuts that yield the smallest subproblems in each step.