Branch data Line data Source code
1 : : #pragma once
2 : :
3 : : #include <mutable/IR/PhysicalPlanTable.hpp>
4 : :
5 : : #include <functional>
6 : :
7 : :
8 : : namespace m {
9 : :
10 : : // forward declarations
11 : : struct ConcretePhysicalPlanTableEntry;
12 : :
13 : :
14 : : /*======================================================================================================================
15 : : * ConcretePhysicalPlanTable
16 : : *====================================================================================================================*/
17 : :
18 : : namespace detail {
19 : :
20 : : template<bool Ref, bool C>
21 : : requires (not Ref) or C // references to condition-entry pairs must be const, thus only a const iterator is allowed
22 : : struct ConcretePhysicalPlanTableIterator
23 : : : the_condition_entry_iterator<ConcretePhysicalPlanTableIterator<Ref, C>, C, ConcretePhysicalPlanTableEntry>
24 : : {
25 : : using super =
26 : : the_condition_entry_iterator<ConcretePhysicalPlanTableIterator<Ref, C>, C, ConcretePhysicalPlanTableEntry>;
27 : : using value_type = super::value_type;
28 : : using reference = super::reference;
29 : : using pointer = super::pointer;
30 : : static constexpr bool IsReference = Ref;
31 : :
32 : : private:
33 : : using iterable_entry_type = std::conditional_t<IsReference, std::reference_wrapper<const value_type>, value_type>;
34 : : using iterator_type = std::vector<iterable_entry_type>::iterator;
35 : : iterator_type current_; ///< the iterator to the current position in the iterable
36 : : #ifdef M_ENABLE_SANITY_FIELDS
37 : : iterator_type end_; ///< the end iterator of the iterable
38 : : #endif
39 : :
40 : : public:
41 : : using difference_type = iterator_type::difference_type; // to satisfy std::input_iterator for std::find_if()
42 : :
43 : 81 : ConcretePhysicalPlanTableIterator() = default;
44 : 1458 : ConcretePhysicalPlanTableIterator(const std::vector<iterable_entry_type> &iterable, std::size_t idx)
45 : 1458 : : current_(const_cast<std::vector<iterable_entry_type>&>(iterable).begin() + idx)
46 : : #ifdef M_ENABLE_SANITY_FILEDS
47 : : , end_(const_cast<std::vector<iterable_entry_type>&>(iterable).end())
48 : : #endif
49 : : {
50 : 1458 : M_insist(idx <= iterable.size(), "invalid index");
51 : 1458 : }
52 : :
53 : 972 : bool operator==(const ConcretePhysicalPlanTableIterator &other) const { return this->current_ == other.current_; }
54 : 729 : bool operator!=(const ConcretePhysicalPlanTableIterator &other) const { return not operator==(other); }
55 : :
56 : 243 : ConcretePhysicalPlanTableIterator & operator++() {
57 : : #ifdef M_ENABLE_SANITY_FILEDS
58 : : M_insist(current_ < end_, "cannot increment end iterator");
59 : : #endif
60 : 243 : ++current_;
61 : 243 : return *this;
62 : : }
63 : : ConcretePhysicalPlanTableIterator operator++(int) { auto cpy = *this; operator++(); return cpy; }
64 : :
65 : 162 : reference operator*() const {
66 : : #ifdef M_ENABLE_SANITY_FILEDS
67 : : M_insist(current_ < end_, "cannot dereference end iterator");
68 : : #endif
69 : 324 : return [&]() -> reference { // M_CONSTEXPR_COND cannot be used since it would drop reference and try to copy
70 : : if constexpr (IsReference)
71 : : return current_->get();
72 : : else
73 : 162 : return *current_;
74 : : }();
75 : : }
76 : 810 : pointer operator->() const {
77 : : #ifdef M_ENABLE_SANITY_FILEDS
78 : : M_insist(current_ < end_, "cannot dereference end iterator");
79 : : #endif
80 : 1620 : return M_CONSTEXPR_COND(IsReference, ¤t_->get(), &*current_);
81 : : }
82 : : };
83 : : template<bool C> using Condition2PPTEntryMapIterator = ConcretePhysicalPlanTableIterator<false, C>;
84 : : template<bool C> using PhysicalPlanTableEntryChildIterator = ConcretePhysicalPlanTableIterator<true, C>;
85 : :
86 : : }
87 : :
88 : : struct ConcretePhysicalPlanTableEntry
89 : : : PhysicalPlanTableEntry<ConcretePhysicalPlanTableEntry, detail::PhysicalPlanTableEntryChildIterator>
90 : : {
91 : : using super = PhysicalPlanTableEntry<ConcretePhysicalPlanTableEntry, detail::PhysicalPlanTableEntryChildIterator>;
92 : : using const_child_iterator = super::const_child_iterator;
93 : : using cost_type = super::cost_type;
94 : :
95 : 243 : friend void swap(ConcretePhysicalPlanTableEntry &first, ConcretePhysicalPlanTableEntry &second) {
96 : : using std::swap;
97 : 243 : swap(first.match_, second.match_);
98 : 243 : swap(first.children_, second.children_);
99 : 243 : swap(first.cost_, second.cost_);
100 : 243 : }
101 : :
102 : : private:
103 : : using entry_type = ConcretePhysicalPlanTableEntry;
104 : : ///> the found match; as unsharable shared pointer to share sub-matches between entries while being able to
105 : : ///> transform exclusive matches into unique pointer
106 : : unsharable_shared_ptr<MatchBase> match_;
107 : : ///> all children, i.e. condition and entry per child
108 : : std::vector<std::reference_wrapper<const detail::condition_entry_t<entry_type>>> children_;
109 : : cost_type cost_; ///< cumulative cost, i.e. cost of the physical operator itself plus costs of its children
110 : :
111 : : public:
112 : : template<typename It>
113 : : requires requires { typename detail::the_condition_entry_iterator<It, true, entry_type>; }
114 : 486 : ConcretePhysicalPlanTableEntry(std::unique_ptr<MatchBase> &&match, const std::vector<It> &children, cost_type cost)
115 : 243 : : match_(match.release()) // convert to unsharable shared pointer
116 : 243 : , cost_(cost)
117 : : {
118 [ + - ]: 243 : children_.reserve(children.size());
119 [ + + ]: 405 : for (auto &it : children)
120 [ + - + - ]: 162 : children_.emplace_back(*it);
121 : 243 : }
122 : :
123 : 243 : ConcretePhysicalPlanTableEntry() = default;
124 : 243 : ConcretePhysicalPlanTableEntry(ConcretePhysicalPlanTableEntry &&other)
125 : 243 : : ConcretePhysicalPlanTableEntry()
126 [ + - ]: 243 : { swap(*this, other); }
127 : :
128 : 0 : ConcretePhysicalPlanTableEntry & operator=(ConcretePhysicalPlanTableEntry other) {
129 : 0 : swap(*this, other);
130 : 0 : return *this;
131 : : }
132 : :
133 : : const MatchBase & match() const { return *match_; }
134 : 162 : unsharable_shared_ptr<MatchBase> share_match() const { return match_; /* copy */ }
135 : 81 : unsharable_shared_ptr<MatchBase> extract_match() { return std::move(match_); }
136 : :
137 : 243 : cost_type cost() const { return cost_; }
138 : :
139 : : const_child_iterator begin_children() const { return const_child_iterator(children_, 0); }
140 : : const_child_iterator end_children() const { return const_child_iterator(children_, children_.size()); }
141 : : const_child_iterator cbegin_children() const { return begin_children(); }
142 : : const_child_iterator cend_children() const { return end_children(); }
143 : : };
144 : :
145 : : struct ConcreteCondition2PPTEntryMap
146 : : : Condition2PPTEntryMap<
147 : : ConcreteCondition2PPTEntryMap, detail::Condition2PPTEntryMapIterator, ConcretePhysicalPlanTableEntry
148 : : >
149 : : {
150 : : using super = Condition2PPTEntryMap<
151 : : ConcreteCondition2PPTEntryMap, detail::Condition2PPTEntryMapIterator, ConcretePhysicalPlanTableEntry
152 : : >;
153 : : using iterator = super::iterator;
154 : : using const_iterator = super::const_iterator;
155 : : using entry_type = super::entry_type;
156 : :
157 : 0 : friend void swap(ConcreteCondition2PPTEntryMap &first, ConcreteCondition2PPTEntryMap &second) {
158 : : using std::swap;
159 : 0 : swap(first.map_, second.map_);
160 : 0 : }
161 : :
162 : : private:
163 : : std::vector<detail::condition_entry_t<entry_type>> map_;
164 : :
165 : : public:
166 : 243 : ConcreteCondition2PPTEntryMap() = default;
167 : 0 : ConcreteCondition2PPTEntryMap(ConcreteCondition2PPTEntryMap &&other)
168 : 0 : : ConcreteCondition2PPTEntryMap()
169 [ # # ]: 0 : { swap(*this, other); }
170 : :
171 : : ConcreteCondition2PPTEntryMap & operator=(ConcreteCondition2PPTEntryMap other) {
172 : : swap(*this, other);
173 : : return *this;
174 : : }
175 : :
176 : 81 : bool empty() const { return map_.empty(); }
177 : :
178 : 243 : void insert(ConditionSet &&condition, entry_type &&entry) {
179 : 243 : map_.emplace_back(std::move(condition), std::move(entry));
180 : 243 : }
181 : :
182 : 324 : iterator begin() { return iterator(map_, 0); }
183 : 648 : iterator end() { return iterator(map_, map_.size()); }
184 : 162 : const_iterator begin() const { return const_iterator(map_, 0); }
185 : 324 : const_iterator end() const { return const_iterator(map_, map_.size()); }
186 : 162 : const_iterator cbegin() const { return begin(); }
187 : 324 : const_iterator cend() const { return end(); }
188 : : };
189 : :
190 : : struct ConcretePhysicalPlanTable : PhysicalPlanTable<ConcretePhysicalPlanTable, ConcreteCondition2PPTEntryMap>
191 : : {
192 : : using super = PhysicalPlanTable<ConcretePhysicalPlanTable, ConcreteCondition2PPTEntryMap>;
193 : : using size_type = super::size_type;
194 : : using condition2entry_map_type = super::condition2entry_map_type;
195 : :
196 : : friend void swap(ConcretePhysicalPlanTable &first, ConcretePhysicalPlanTable &second) {
197 : : using std::swap;
198 : : swap(first.table_, second.table_);
199 : : }
200 : :
201 : : private:
202 : : std::vector<condition2entry_map_type> table_;
203 : :
204 : : public:
205 : 81 : ConcretePhysicalPlanTable() = default;
206 : : ConcretePhysicalPlanTable(ConcretePhysicalPlanTable &&other) : ConcretePhysicalPlanTable() { swap(*this, other); }
207 : :
208 : : ConcretePhysicalPlanTable & operator=(ConcretePhysicalPlanTable other) { swap(*this, other); return *this; }
209 : :
210 : 81 : void clear() { table_.clear(); }
211 : 1620 : size_type size() const { return table_.size(); }
212 : 81 : void resize(size_type size) { table_.resize(size); }
213 : :
214 : 1458 : condition2entry_map_type & operator[](size_type idx) {
215 : 1458 : M_insist(idx < size(), "invalid index");
216 : 1458 : return table_[idx];
217 : : }
218 : : const condition2entry_map_type & operator[](size_type idx) const {
219 : : return const_cast<ConcretePhysicalPlanTable*>(this)->operator[](idx);
220 : : }
221 : :
222 : 324 : condition2entry_map_type & back() { return table_.back(); }
223 : 81 : const condition2entry_map_type & back() const { return const_cast<ConcretePhysicalPlanTable*>(this)->back(); }
224 : : };
225 : :
226 : : }
|