34 "only booleans and bitmaps may not be byte aligned");
36 "only booleans and bitmaps may not be byte aligned");
38 auto leaf =
new Leaf(type, idx);
40 .
ptr = std::unique_ptr<DataLayout::Node>(as<Node>(leaf)),
41 .offset_in_bits = offset_in_bits,
49 M_insist(
num_tuples != 0,
"the new INode must be large enough for at least one tuple");
52 "the number of tuples in the parent must be a whole multiple of the number of tuples of the newly created "
54 M_insist(offset_in_bits % 8 == 0,
"the offset of the newly created INode must be byte aligned");
59 .
ptr = std::unique_ptr<DataLayout::Node>(as<Node>(inode)),
60 .offset_in_bits = offset_in_bits,
71 std::vector<leaf_info_t> leaves;
72 leaves.reserve(this->num_children());
74 for (
auto &
child : *
this) {
75 if (
auto child_leaf = cast<const Leaf>(
child.ptr.get())) {
78 .offset_in_bits =
child.offset_in_bits,
79 .stride_in_bits =
child.stride_in_bits,
82 auto child_inode = as<const INode>(
child.ptr.get());
87 child_inode->for_sibling_leaves(level_info_stack, inode_offset_in_bits +
child.offset_in_bits, callback);
88 level_info_stack.pop_back();
92 if (not leaves.empty())
93 callback(leaves, level_info_stack, inode_offset_in_bits);
100std::ostream &
indent(std::ostream &out,
unsigned indentation)
102 out <<
'\n' << std::string(4 * indentation,
' ');
113 for (std::size_t i = 0; i != num_children(); ++i, ++it) {
116 indent(out, indentation) <<
"[" << std::setw(decimal_places) << i <<
"]: ";
119 if (
auto child_leaf = cast<const Leaf>(
child.ptr.get())) {
120 out <<
"Leaf " << child_leaf->index() <<
" of type " << *child_leaf->type() <<
" with bit offset "
121 <<
child.offset_in_bits <<
" and bit stride " <<
child.stride_in_bits;
123 auto child_inode = as<const INode>(
child.ptr.get());
124 out <<
"INode of " << child_inode->num_tuples() <<
" tuple(s) with bit offset " <<
child.offset_in_bits
125 <<
" and bit stride " <<
child.stride_in_bits;
126 child_inode->print(out, indentation + 1);
146 M_insist(
num_tuples != 0,
"the new INode must be large enough for at least one tuple");
152 .
ptr = std::unique_ptr<DataLayout::Node>(as<Node>(inode)),
174 const bool needs_null_bitmap = [&]() {
186 if (
auto child_inode = cast<const DataLayout::INode>(inode[0].ptr.get());
189 return rec(*child_inode, rec);
192 std::size_t num_simd_lanes = 1;
193 for (
auto &
child : inode) {
194 if (cast<const DataLayout::INode>(
child.ptr.get()))
197 auto &child_leaf = as<const DataLayout::Leaf>(*
child.ptr);
198 const uint8_t bit_stride =
child.stride_in_bits % 8;
200 if (not needs_null_bitmap)
210 if (
child.offset_in_bits % 8 != 0)
214 num_simd_lanes = std::max<std::size_t>(num_simd_lanes, 16);
219 M_insist(*tuple_it->type == *child_leaf.type());
222 if (
child.stride_in_bits != 1)
225 if (tuple_it->type->is_boolean()
and child.stride_in_bits != 8)
227 if (tuple_it->type->is_character_sequence())
231 const uint64_t size_in_bytes = (tuple_it->type->size() + 7) / 8;
232 num_simd_lanes = std::max<std::size_t>(num_simd_lanes, 16 / size_in_bytes);
236 if (inode.num_tuples() % num_simd_lanes != 0)
241 return test_simd_support(
static_cast<const DataLayout::INode&
>(layout), test_simd_support);
248 "layout must support SIMD to retrieve its number of SIMD lanes");
250 std::size_t num_simd_lanes = 1;
255 const uint64_t size_in_bytes = (tuple_entry.type->size() + 7) / 8;
256 num_simd_lanes = std::max<std::size_t>(num_simd_lanes, 16 / size_in_bytes);
259 return num_simd_lanes;
std::ostream & indent(std::ostream &out, unsigned indentation)
Start a new line with proper indentation.
const Schema const Schema & tuple_schema
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 ...
const Schema & layout_schema
static constexpr float DECIMAL_TO_BINARY_DIGITS
How many binary digits fit into a single decimal digit.
A Schema represents a sequence of identifiers, optionally with a prefix, and their associated types.
std::size_t num_entries() const
Returns the number of entries in this Schema.
iterator find(const Identifier &id)
Returns an iterator to the entry with the given Identifier id, or end() if no such entry exists.
This class represents types in the SQL type system.
a child Node and its relative offset and stride within the containing INode
std::unique_ptr< Node > ptr
An internal node of the recursive data layout model.
std::vector< child_t > children_
the child Nodes of this INode
void print(std::ostream &out, unsigned indentation=0) const
size_type num_tuples() const override
returns the number of tuples represented by an instance of this node
Leaf & add_leaf(const m::Type *type, size_type idx, uint64_t offset_in_bits, uint64_t stride_in_bits)
Creates a Leaf and adds it as a child to this INode.
void for_sibling_leaves(level_info_stack_t &level_info_stack, uint64_t inode_offset_in_bits, const callback_leaves_t &callback) const
void accept(ConstDataLayoutVisitor &v) const override
INode & add_inode(size_type num_tuples, uint64_t offset_in_bits, uint64_t stride_in_bits)
Creates an INode and adds it as a child to this INode.
size_type num_children() const
returns the number of child Nodes of this INode
The Leaf represents exactly one attribue.
void accept(ConstDataLayoutVisitor &v) const override
virtual size_type num_tuples() const =0
returns the number of tuples represented by an instance of this node
combines information of a single leaf for for_sibling_leaves()
combines information of a single internal level inside the DataLayout, used by for_sibling_leaves()
uint64_t stride_in_bits
the stride of instances of this level
Models how data is laid out in a linear address space.
INode inode_
use an INode to store a single child, allowing us to exploit INode abstractions within DataLayout
uint64_t stride_in_bits() const
return the stride (in bits) of the single child of the DataLayout
const Node & child() const
returns a reference to the single child of this DataLayout
INode & add_inode(size_type num_tuples, uint64_t stride_in_bits)
Creates an INode and adds it as a child to this DataLayout's internal INode.
size_type num_tuples() const
returns the number of tuples laid out by this DataLayout; must not be called when not is_finite()
std::vector< level_info_t > level_info_stack_t
Leaf & add_leaf(const m::Type *type, size_type idx, uint64_t stride_in_bits)
Creates a Leaf and adds it as a child to this DataLayout's internal INode.
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
void for_sibling_leaves(callback_leaves_t callback) const
void accept(ConstDataLayoutVisitor &v) const