mutable
A Database System for Research and Fast Prototyping
Loading...
Searching...
No Matches
DataLayout.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4#include <functional>
5#include <memory>
6#include <mutable/mutable-config.hpp>
10#include <vector>
11
12
13namespace m {
14
15// forward declarations
16struct Schema;
17struct Type;
18
19namespace storage {
20
21/*======================================================================================================================
22 * DataLayout
23 *====================================================================================================================*/
24
25struct ConstDataLayoutVisitor;
26
28struct M_EXPORT DataLayout
29{
30 /*----- Types ----------------------------------------------------------------------------------------------------*/
31 using size_type = std::size_t;
32
33 struct Leaf;
34 struct INode;
35
37 struct M_EXPORT leaf_info_t
38 {
39 const Leaf &leaf;
42 };
43
45 struct M_EXPORT level_info_t
46 {
51 };
52
53 using level_info_stack_t = std::vector<level_info_t>;
54
55 using callback_leaves_t = std::function<void(const std::vector<leaf_info_t> &leaves,
56 const level_info_stack_t &levels,
57 uint64_t inode_offset_in_bits)>;
58
60 struct M_EXPORT Node
61 {
62 virtual ~Node() = 0;
63
65 virtual size_type num_tuples() const = 0;
66
67 virtual void accept(ConstDataLayoutVisitor &v) const = 0;
68 };
69
72 struct M_EXPORT Leaf : Node
73 {
74 friend struct DataLayout;
75 friend struct INode;
76
77 private:
79 const m::Type *type_;
82
83 Leaf(const m::Type *type, size_type idx) : type_(type), idx_(idx) { }
84
85 public:
87 const m::Type * type() const { return type_; }
89 size_type index() const { return idx_; }
90
91 size_type num_tuples() const override { return 1; }
92
93 void accept(ConstDataLayoutVisitor &v) const override;
94 };
95
98 struct M_EXPORT INode : Node
99 {
100 friend struct DataLayout;
101
103 struct child_t
104 {
105 std::unique_ptr<Node> ptr;
108 };
109
111 {
112 private:
115
116 public:
117 const_iterator(const INode &the_inode, size_type idx = 0)
118 : the_inode_(the_inode)
119 , idx_(idx)
120 { }
121
122 bool operator==(const_iterator other) const {
123 M_insist(&this->the_inode_ == &other.the_inode_, "comparing iterators to different INodes");
124 return this->idx_ == other.idx_;
125 }
126 bool operator!=(const_iterator other) const { return not operator==(other); }
127
129 M_insist(idx_ < the_inode_.num_children(), "index out of bounds");
130 ++idx_;
131 return *this;
132 }
133
134 const_iterator operator++(int) { const_iterator old = *this; this->operator++(); return old; }
135
136 const child_t & operator*() { return the_inode_[idx_]; }
137 const child_t & operator->() { return the_inode_[idx_]; }
138 };
139
140 private:
142 std::vector<child_t> children_;
145
146 INode(size_type num_tuples) : num_tuples_(num_tuples) { }
147
148 INode(INode&&) = default;
149
150 INode & operator=(INode&&) = default;
151
152 public:
153 size_type num_tuples() const override { return num_tuples_; }
155 size_type num_children() const { return children_.size(); }
156
159 Leaf & add_leaf(const m::Type *type, size_type idx, uint64_t offset_in_bits, uint64_t stride_in_bits);
162 INode & add_inode(size_type num_tuples, uint64_t offset_in_bits, uint64_t stride_in_bits);
163
165 const child_t & operator[](size_type idx) const {
166 M_insist(idx < children_.size(), "index out of bounds");
167 return children_[idx];
168 }
170 const child_t & at(size_type idx) const {
171 if (idx >= children_.size()) throw m::invalid_argument("index out of bounds");
172 return children_[idx];
173 }
174
175 const_iterator begin() const { return const_iterator(*this); }
176 const_iterator end() const { return const_iterator(*this, this->num_children()); }
177 const_iterator cbegin() const { return begin(); }
178 const_iterator cend() const { return end(); }
179
180 void accept(ConstDataLayoutVisitor &v) const override;
181
182 void for_sibling_leaves(level_info_stack_t &level_info_stack, uint64_t inode_offset_in_bits,
183 const callback_leaves_t &callback) const;
184
185 void print(std::ostream &out, unsigned indentation = 0) const;
186 };
187
188 /*----- Fields ---------------------------------------------------------------------------------------------------*/
189 private:
192
193 /*----- Methods --------------------------------------------------------------------------------------------------*/
194 public:
197 DataLayout(size_type num_tuples = 0) : inode_(num_tuples) { }
198
200 bool is_finite() const { return inode_.num_tuples() != 0; }
203 M_insist(is_finite(), "infinite data layouts have no number of tuples");
204 return inode_.num_tuples();
205 }
207 uint64_t stride_in_bits() const { M_insist(bool(*this), "no child set"); return inode_[0].stride_in_bits; }
209 const Node & child() const { M_insist(bool(*this), "no child set"); return *inode_[0].ptr; }
210
212 operator bool() const { return inode_.num_children() == 1; }
214 explicit operator const INode&() const { return inode_; }
215
218 Leaf & add_leaf(const m::Type *type, size_type idx, uint64_t stride_in_bits);
222 INode & add_inode(size_type num_tuples, uint64_t stride_in_bits);
223
224 void accept(ConstDataLayoutVisitor &v) const;
225 void for_sibling_leaves(callback_leaves_t callback) const;
226
228 friend std::ostream & operator<<(std::ostream &out, const DataLayout &layout) {
229 if (layout.is_finite())
230 out << "DataLayout of " << layout.num_tuples() << " tuple(s)";
231 else
232 out << "DataLayout of infinite tuples";
233 layout.inode_.print(out);
234 return out;
235 };
236
237 void dump() const { dump(std::cerr); }
238 void dump(std::ostream &out) const { out << *this << std::endl; }
240};
241
242#define M_DATA_LAYOUT_CLASSES(X) \
243 X(DataLayout::INode) \
244 X(DataLayout::Leaf) \
245 X(DataLayout)
246
248
249/*======================================================================================================================
250 * Helper functions for SIMD support
251 *====================================================================================================================*/
252
253
255bool supports_simd(const DataLayout &layout, const Schema &layout_schema, const Schema &tuple_schema);
256
259std::size_t get_num_simd_lanes(const DataLayout &layout, const Schema &layout_schema, const Schema &tuple_schema);
260
261}
262
263}
#define M_DATA_LAYOUT_CLASSES(X)
Definition: DataLayout.hpp:242
#define M_DECLARE_VISITOR(VISITOR_NAME, BASE_CLASS, CLASS_LIST)
Defines a visitor VISITOR_NAME to visit the class hierarchy rooted in BASE_CLASS and with subclasses ...
Definition: Visitor.hpp:181
#define M_insist(...)
Definition: macro.hpp:129
const Schema const Schema & tuple_schema
Definition: DataLayout.hpp:255
std::size_t get_num_simd_lanes(const DataLayout &layout, const Schema &layout_schema, const Schema &tuple_schema)
Returns the number of SIMD lanes used for accessing tuples of schema tuple_schema in SIMDfied manner ...
Definition: DataLayout.cpp:244
const Schema & layout_schema
Definition: DataLayout.hpp:255
‍mutable namespace
Definition: Backend.hpp:10
const Type
Definition: Type.hpp:498
STL namespace.
A Schema represents a sequence of identifiers, optionally with a prefix, and their associated types.
Definition: Schema.hpp:39
This class represents types in the SQL type system.
Definition: Type.hpp:46
Signals that an argument to a function of method was invalid.
Definition: exception.hpp:37
‍a child Node and its relative offset and stride within the containing INode
Definition: DataLayout.hpp:104
bool operator==(const_iterator other) const
Definition: DataLayout.hpp:122
const_iterator(const INode &the_inode, size_type idx=0)
Definition: DataLayout.hpp:117
bool operator!=(const_iterator other) const
Definition: DataLayout.hpp:126
An internal node of the recursive data layout model.
Definition: DataLayout.hpp:99
std::vector< child_t > children_
‍the child Nodes of this INode
Definition: DataLayout.hpp:142
const child_t & at(size_type idx) const
‍returns a reference to the idx -th child; throws m::invalid_argument if idx is out of bounds
Definition: DataLayout.hpp:170
const_iterator cend() const
Definition: DataLayout.hpp:178
void print(std::ostream &out, unsigned indentation=0) const
Definition: DataLayout.cpp:108
const_iterator end() const
Definition: DataLayout.hpp:176
const_iterator cbegin() const
Definition: DataLayout.hpp:177
size_type num_tuples() const override
‍returns the number of tuples represented by an instance of this node
Definition: DataLayout.hpp:153
const child_t & operator[](size_type idx) const
‍returns a reference to the idx -th child
Definition: DataLayout.hpp:165
INode & operator=(INode &&)=default
INode(size_type num_tuples)
Definition: DataLayout.hpp:146
const_iterator begin() const
Definition: DataLayout.hpp:175
size_type num_tuples_
‍the number of tuples that fit into one instance of this INode
Definition: DataLayout.hpp:144
size_type num_children() const
‍returns the number of child Nodes of this INode
Definition: DataLayout.hpp:155
The Leaf represents exactly one attribue.
Definition: DataLayout.hpp:73
size_type num_tuples() const override
‍returns the number of tuples represented by an instance of this node
Definition: DataLayout.hpp:91
size_type idx_
‍an index that must be unique within the entire DataLayout
Definition: DataLayout.hpp:81
size_type index() const
Returns the index assigned to this Leaf.
Definition: DataLayout.hpp:89
Leaf(const m::Type *type, size_type idx)
Definition: DataLayout.hpp:83
const m::Type * type() const
Returns the Type of this Leaf.
Definition: DataLayout.hpp:87
const m::Type * type_
‍the Type of the attribute represented by this Leaf
Definition: DataLayout.hpp:79
‍an abstract node in the recursive data layout model
Definition: DataLayout.hpp:61
virtual size_type num_tuples() const =0
‍returns the number of tuples represented by an instance of this node
virtual void accept(ConstDataLayoutVisitor &v) const =0
‍combines information of a single leaf for for_sibling_leaves()
Definition: DataLayout.hpp:38
‍combines information of a single internal level inside the DataLayout, used by for_sibling_leaves()
Definition: DataLayout.hpp:46
uint64_t stride_in_bits
‍the stride of instances of this level
Definition: DataLayout.hpp:48
size_type num_tuples
‍number of tuples that fit into an instance of this level
Definition: DataLayout.hpp:50
Models how data is laid out in a linear address space.
Definition: DataLayout.hpp:29
bool is_finite() const
‍returns true iff this DataLayout lays out a finite sequence of tuples
Definition: DataLayout.hpp:200
INode inode_
‍use an INode to store a single child, allowing us to exploit INode abstractions within DataLayout
Definition: DataLayout.hpp:191
uint64_t stride_in_bits() const
‍return the stride (in bits) of the single child of the DataLayout
Definition: DataLayout.hpp:207
const Node & child() const
‍returns a reference to the single child of this DataLayout
Definition: DataLayout.hpp:209
size_type num_tuples() const
‍returns the number of tuples laid out by this DataLayout; must not be called when not is_finite()
Definition: DataLayout.hpp:202
std::vector< level_info_t > level_info_stack_t
Definition: DataLayout.hpp:53
void dump(std::ostream &out) const
Definition: DataLayout.hpp:238
M_LCOV_EXCL_START friend std::ostream & operator<<(std::ostream &out, const DataLayout &layout)
Definition: DataLayout.hpp:228
DataLayout(size_type num_tuples=0)
Create a new DataLayout for laying out num_tuples many tuples in linear memory.
Definition: DataLayout.hpp:197
std::function< void(const std::vector< leaf_info_t > &leaves, const level_info_stack_t &levels, uint64_t inode_offset_in_bits)> callback_leaves_t
Definition: DataLayout.hpp:57