Everett
Loading...
Searching...
No Matches
sort_profile_file.h
Go to the documentation of this file.
1
12#pragma once
13
16#include <everett/cola_query.h>
17#include <everett/mapped_cola.h>
18
19namespace everett {
20 namespace sort_profile_file_detail {
21 inline constexpr std::size_t directory_bytes = 192, section_count = 8;
22 inline constexpr std::size_t descriptors = 64;
23 inline void append_words(std::vector<std::byte> & out, std::span<std::uint64_t const> words) {
24 out.resize(words.size() << 3);
25 for (std::size_t i = 0; i != words.size(); ++i) file_detail::put(out, i << 3, 8, words[i]);
26 }
27 }
28
29 template <class P> struct encoded_sort_sections {
34 : header_(other.header_), directory_(other.directory_), zero_(other.zero_), parts_(other.parts_),
35 owned_(std::move(other.owned_)), active_(std::exchange(other.active_, false)) {}
37 if (this != &other) {
38 header_ = other.header_; directory_ = other.directory_; zero_ = other.zero_;
39 parts_ = other.parts_; owned_ = std::move(other.owned_); active_ = std::exchange(other.active_, false);
40 }
41 return *this;
42 }
43 template <class Selector> static encoded_sort_sections from(sort_profile_array<P, Selector> const & source) {
45 auto & directory = result.directory_;
46 for (unsigned i = 0; i != 4; ++i) directory[i] = std::byte("KV03"[i]);
47 file_detail::put(directory, 4, 2, 3); file_detail::put(directory, 6, 2, 8);
48 auto const & metadata = source.metadata();
49 auto const & ef = source.group_offsets();
50 file_detail::put(directory, 8, 8, metadata.extent);
51 file_detail::put(directory, 16, 8, metadata.terminal_key_units);
52 file_detail::put(directory, 24, 8, ef.universe);
53 file_detail::put(directory, 32, 8, source.dictionary().bit_size);
54 file_detail::put(directory, 40, 8, source.seeds().bit_size);
55 directory[48] = std::byte(ef.low_width);
56 result.parts_[0] = source.data().bytes;
57 result.parts_[5] = source.dictionary().bytes;
58 result.parts_[7] = source.seeds().bytes;
59 result.words(1, ef.low); result.words(2, ef.high); result.words(4, ef.sparse);
60 result.words(6, source.dictionary_offsets());
61 auto & samples = result.owned_[3]; samples.resize(ef.samples.size() << 4);
62 for (std::size_t i = 0; i != ef.samples.size(); ++i) {
63 file_detail::put(samples, i << 4, 8, ef.samples[i].first);
64 file_detail::put(samples, (i << 4) + 8, 8, ef.samples[i].sparse);
65 }
66 result.parts_[3] = samples;
67 std::uint64_t end = directory.size();
68 for (std::size_t i = 0; i != result.parts_.size(); ++i) {
69 auto start = section_detail::align(end);
70 file_detail::put(directory, 64 + 16 * i, 8, start);
71 file_detail::put(directory, 72 + 16 * i, 8, result.parts_[i].size());
72 end = profile_detail::add(start, result.parts_[i].size());
73 }
74 result.header_.record_count = source.size();
75 result.header_.common_value_width = metadata.common_value_width;
76 result.header_.extent = profile_detail::multiply(end, 8);
77 return result;
78 }
79 template <class Selector> static encoded_sort_sections from(sort_profile_array<P, Selector> const &&) = delete;
80 file_header<P> const & header() const & { require_active(); return header_; }
81 file_header<P> const & header() const && = delete;
82 std::vector<std::span<std::byte const>> chunks() const & {
84 std::vector<std::span<std::byte const>> result{directory_};
85 std::uint64_t end = directory_.size();
86 for (auto part : parts_) {
87 auto gap = section_detail::align(end) - end;
88 if (gap) result.push_back(std::span(zero_).first(gap));
89 result.push_back(part); end += gap + part.size();
90 }
91 return result;
92 }
93 std::vector<std::span<std::byte const>> chunks() const && = delete;
94 std::vector<std::byte> materialize() const {
95 std::vector<std::byte> body;
96 for (auto part : chunks()) body.insert(body.end(), part.begin(), part.end());
97 return encode_file(header_, body);
98 }
99 object_seal_receipt seal(std::filesystem::path const & root, object_id const & id,
100 object_attempt_id const & attempt) const {
101 auto parts = chunks(); return object_writer<P>::seal(root, id, attempt, header_, parts);
102 }
103 private:
105 std::array<std::byte, 192> directory_{};
106 std::array<std::byte, 8> zero_{};
107 std::array<std::span<std::byte const>, 8> parts_;
108 std::array<std::vector<std::byte>, 8> owned_;
109 bool active_ = true;
110 void require_active() const { if (!active_) throw std::logic_error("inactive encoded sort profile"); }
111 void words(std::size_t slot, std::span<std::uint64_t const> source) {
112 sort_profile_file_detail::append_words(owned_[slot], source); parts_[slot] = owned_[slot];
113 }
114 };
115
116 template <class P, class Selector = registry_selector<typename P::registry_type>> struct mapped_sort_profile {
117 using policy_type = P;
121 auto header = source.header(); auto body = source.body(); auto bytes = body.bytes();
122 if (header.kind != file_kind::native_blob || bytes.size() < 192 ||
123 header.extent != profile_detail::multiply(bytes.size(), 8))
124 throw std::invalid_argument("sort profile file extent or kind");
125 for (unsigned i = 0; i != 4; ++i)
126 if (bytes[i] != std::byte("KV03"[i])) throw std::invalid_argument("sort profile file revision");
127 if (file_detail::get(bytes, 4, 2) != 3 || file_detail::get(bytes, 6, 2) != 8)
128 throw std::invalid_argument("sort profile section revision");
129 section_detail::zero(bytes.subspan(49, 15), "nonzero sort profile reserved bytes");
130 std::array<std::span<std::byte const>, 8> parts;
131 std::uint64_t end = 192;
132 for (std::size_t i = 0; i != parts.size(); ++i) {
133 auto first = file_detail::get(bytes, 64 + 16 * i, 8), count = file_detail::get(bytes, 72 + 16 * i, 8);
134 if (first != section_detail::align(end) || first > bytes.size() || count > bytes.size() - first)
135 throw std::invalid_argument("sort profile section range");
136 parts[i] = bytes.subspan(first, count); end = first + count;
137 }
138 if (end != bytes.size()) throw std::invalid_argument("trailing sort profile sections");
139 auto metadata = profile_detail::initial_metadata<P, stream_role::native>();
140 metadata.version = 3; metadata.extent = file_detail::get(bytes, 8, 8);
141 metadata.record_count = header.record_count; metadata.terminal_key_units = file_detail::get(bytes, 16, 8);
142 metadata.common_value_width = header.common_value_width;
143 metadata.policy_fixed_values = header.policy_value_width.has_value();
144 metadata.policy_value_width = header.policy_value_width.value_or(0);
145 auto dictionary_bits = file_detail::get(bytes, 32, 8), seed_bits = file_detail::get(bytes, 40, 8);
146 if (parts[0].size() != profile_detail::byte_count(metadata.extent) ||
147 parts[5].size() != profile_detail::byte_count(dictionary_bits) ||
148 parts[7].size() != profile_detail::byte_count(seed_bits))
149 throw std::invalid_argument("sort profile bit section extent");
150 auto blocks = header.record_count / P::codec_block_size + (header.record_count % P::codec_block_size != 0);
152 sample_view::little_endian(parts[3]), word_view::little_endian(parts[4]), blocks + 1,
153 file_detail::get(bytes, 24, 8), unsigned(std::to_integer<unsigned char>(bytes[48]))};
154 view_type view({parts[0], metadata.extent}, ef, metadata, {parts[5], dictionary_bits},
155 word_view::little_endian(parts[6]), {parts[7], seed_bits});
156 return {std::move(source), std::move(body), std::move(view)};
157 }
158 static mapped_sort_profile open(std::filesystem::path const & path) { return open(file<P>::open(path)); }
160 return open(file<P>::from_slice(std::move(source), mode));
161 }
162 view_type view() const & { require_active(); return view_; }
163 view_type view() const && = delete;
164 std::uint64_t size() const { require_active(); return view_.size(); }
165 void scan() const {
166 require_active(); source_.scan(); view_.scan();
167 auto bytes = body_.bytes(); std::uint64_t end = 192;
168 for (unsigned i = 0; i != 8; ++i) {
169 auto first = file_detail::get(bytes, 64 + 16 * i, 8), count = file_detail::get(bytes, 72 + 16 * i, 8);
170 section_detail::zero(bytes.subspan(end, first - end), "nonzero sort profile section gap"); end = first + count;
171 }
172 for (auto bits : {view_.data(), view_.dictionary(), view_.seeds()})
173 if ((bits.size() & 7) && (std::to_integer<unsigned>(bits.storage().back()) & ((1u << (8 - (bits.size() & 7))) - 1)))
174 throw std::invalid_argument("sort profile tail padding");
175 }
176 private:
177 void require_active() const { if (body_.empty()) throw std::logic_error("inactive mapped sort profile"); }
182 : source_(std::move(source)), body_(std::move(body)), view_(view) {}
183 };
184
185 template <class P, class Selector = registry_selector<typename P::registry_type>> struct mapped_sort_cola {
186 using policy_type = P;
188 using native_pointer = std::shared_ptr<native_type const>;
190 using index_pointer = std::shared_ptr<index_type const>;
191 using pair_type = std::shared_ptr<mapped_sort_cola const>;
198 std::shared_ptr<mapped_cola_index<P> const> index, pair_type main = {},
199 native_pointer secondary = {}, std::optional<object_id> secondary_id = {}) {
200 if (!native || !index || identity.native != index->native_id() ||
201 bool(index->main_id()) != bool(main) || (main && *index->main_id() != main->identity()) ||
202 bool(secondary) != bool(secondary_id) || index->secondary_id() != secondary_id)
203 throw std::invalid_argument("sort COLA pinned identity mismatch");
204 if (index->borrowed(0).size() != (main ? main->group_count() : 0) ||
205 index->borrowed(1).size() != (secondary ? secondary->size() / P::group_size + (secondary->size() % P::group_size != 0) : 0))
206 throw std::invalid_argument("sort COLA sample count mismatch");
207 // Validate the immutable combined shape once, without touching payload.
208 // Its spans remain backed by the native/index owners retained below.
209 view_type view{native->view(), {index->borrowed(0), index->borrowed(1)}, {index->interleave(0), index->interleave(1)},
210 {index->false_borrow_bits(0), index->false_borrow_bits(1)}, {index->cut_lcps(0), index->cut_lcps(1)}, index->virtual_size()};
211 return pair_type(new mapped_sort_cola(identity, std::move(native), std::move(index), std::move(main),
212 std::move(secondary), std::move(view)));
213 }
214 auto const & identity() const & noexcept { return identity_; }
215 auto const & identity() const && = delete;
216 native_pointer native_owner() const noexcept { return native_; }
217 native_pointer native_object() const noexcept { return native_; }
218 index_pointer index_object() const noexcept { return index_; }
219 pair_type main_target() const noexcept { return main_; }
220 native_pointer secondary_target() const noexcept { return secondary_; }
221 std::uint64_t virtual_size() const noexcept { return view_.virtual_size(); }
222 std::uint64_t group_count() const noexcept { return view_.group_count(); }
223 view_type view() const & { return view_; }
224 view_type view() const && = delete;
225 void scan() const { scan_mapped_cola(*this); }
226 private:
229 std::shared_ptr<mapped_cola_index<P> const> index_;
235 : identity_(identity), native_(std::move(native)), index_(std::move(index)), main_(std::move(main)),
236 secondary_(std::move(secondary)), view_(std::move(view)) {}
237 };
238}
Enumerates native matches along a COLA main chain and its terminal secondaries.
Encodes two-target COLA routing in portable IX03 sections.
Binds mapped COLA main and secondary targets with exact immutable pins.
void put(std::span< std::byte > bytes, std::size_t at, unsigned width, std::uint64_t value) noexcept
Definition file.h:70
std::uint64_t get(std::span< std::byte const > bytes, std::size_t at, unsigned width) noexcept
Definition file.h:65
std::uint64_t add(std::uint64_t a, std::uint64_t b)
Definition profile.h:39
std::uint64_t multiply(std::uint64_t a, std::uint64_t b)
Definition profile.h:44
std::uint64_t byte_count(std::uint64_t bits) noexcept
Definition profile.h:50
std::uint64_t align(std::uint64_t value) noexcept
Definition sections.h:68
void zero(std::span< std::byte const > bytes, char const *message)
Definition sections.h:71
void append_words(std::vector< std::byte > &out, std::span< std::uint64_t const > words)
Definition sort_profile_file.h:23
constexpr std::size_t descriptors
Definition sort_profile_file.h:22
constexpr std::size_t section_count
Definition sort_profile_file.h:21
constexpr std::size_t directory_bytes
Definition sort_profile_file.h:21
Definition active_engine.h:18
void scan_mapped_cola(Blob const &source)
Definition mapped_cola.h:202
file_open_mode
Definition file.h:32
std::vector< std::byte > encode_file(file_header< P > const &header, std::span< std::byte const > body)
Definition file.h:221
Navigates sort-owned bit records using shared sort seeds and sparse offsets.
Definition sections.h:34
Definition cola_index.h:114
std::uint64_t virtual_size() const noexcept
Definition cola_index.h:144
borrowed_view const & borrowed(unsigned route) const
Definition cola_index.h:136
std::uint64_t group_count() const noexcept
Definition cola_index.h:145
Definition elias_fano.h:212
Definition sort_profile_file.h:29
std::vector< std::byte > materialize() const
Definition sort_profile_file.h:94
encoded_sort_sections & operator=(encoded_sort_sections const &)=delete
encoded_sort_sections & operator=(encoded_sort_sections &&other) noexcept
Definition sort_profile_file.h:36
static encoded_sort_sections from(sort_profile_array< P, Selector > const &&)=delete
void require_active() const
Definition sort_profile_file.h:110
std::vector< std::span< std::byte const > > chunks() const &&=delete
std::array< std::vector< std::byte >, 8 > owned_
Definition sort_profile_file.h:108
std::vector< std::span< std::byte const > > chunks() const &
Definition sort_profile_file.h:82
std::array< std::byte, 8 > zero_
Definition sort_profile_file.h:106
encoded_sort_sections(encoded_sort_sections const &)=delete
std::array< std::span< std::byte const >, 8 > parts_
Definition sort_profile_file.h:107
std::array< std::byte, 192 > directory_
Definition sort_profile_file.h:105
file_header< P > const & header() const &&=delete
object_seal_receipt seal(std::filesystem::path const &root, object_id const &id, object_attempt_id const &attempt) const
Definition sort_profile_file.h:99
bool active_
Definition sort_profile_file.h:109
file_header< P > header_
Definition sort_profile_file.h:104
file_header< P > const & header() const &
Definition sort_profile_file.h:80
void words(std::size_t slot, std::span< std::uint64_t const > source)
Definition sort_profile_file.h:111
encoded_sort_sections(encoded_sort_sections &&other) noexcept
Definition sort_profile_file.h:33
static encoded_sort_sections from(sort_profile_array< P, Selector > const &source)
Definition sort_profile_file.h:43
Definition file.h:34
Definition file.h:242
file_header< P > header() const
Definition file.h:268
mapped_slice body() const
Definition file.h:269
Definition cola_sections.h:266
Definition mapped_file.h:81
std::span< std::byte const > bytes() const &noexcept
Definition mapped_file.h:99
bool empty() const noexcept
Definition mapped_file.h:97
Definition sort_profile_file.h:185
void scan() const
Definition sort_profile_file.h:225
index_pointer index_object() const noexcept
Definition sort_profile_file.h:218
blob_identity identity_
Definition sort_profile_file.h:227
view_type view_
Definition sort_profile_file.h:232
std::shared_ptr< index_type const > index_pointer
Definition sort_profile_file.h:190
std::shared_ptr< mapped_cola_index< P > const > index_
Definition sort_profile_file.h:229
std::shared_ptr< mapped_sort_cola const > pair_type
Definition sort_profile_file.h:191
native_pointer secondary_
Definition sort_profile_file.h:231
view_type view() const &&=delete
auto const & identity() const &noexcept
Definition sort_profile_file.h:214
std::uint64_t virtual_size() const noexcept
Definition sort_profile_file.h:221
P policy_type
Definition sort_profile_file.h:186
std::uint64_t group_count() const noexcept
Definition sort_profile_file.h:222
mapped_sort_cola & operator=(mapped_sort_cola &&)=delete
static pair_type bind(blob_identity identity, native_pointer native, std::shared_ptr< mapped_cola_index< P > const > index, pair_type main={}, native_pointer secondary={}, std::optional< object_id > secondary_id={})
Definition sort_profile_file.h:197
std::shared_ptr< native_type const > native_pointer
Definition sort_profile_file.h:188
auto const & identity() const &&=delete
native_pointer native_
Definition sort_profile_file.h:228
mapped_sort_cola(mapped_sort_cola &&)=delete
mapped_sort_cola & operator=(mapped_sort_cola const &)=delete
view_type view() const &
Definition sort_profile_file.h:223
pair_type main_
Definition sort_profile_file.h:230
mapped_sort_cola(blob_identity identity, native_pointer native, std::shared_ptr< mapped_cola_index< P > const > index, pair_type main, native_pointer secondary, view_type view)
Definition sort_profile_file.h:233
native_pointer native_owner() const noexcept
Definition sort_profile_file.h:216
native_pointer native_object() const noexcept
Definition sort_profile_file.h:217
cola_index_view< P, sort_profile_family< P, Selector > > view_type
Definition sort_profile_file.h:192
native_pointer secondary_target() const noexcept
Definition sort_profile_file.h:220
mapped_sort_cola(mapped_sort_cola const &)=delete
pair_type main_target() const noexcept
Definition sort_profile_file.h:219
Definition sort_profile_file.h:116
mapped_slice body_
Definition sort_profile_file.h:179
void require_active() const
Definition sort_profile_file.h:177
mapped_sort_profile(file< P > source, mapped_slice body, view_type view)
Definition sort_profile_file.h:181
std::uint64_t size() const
Definition sort_profile_file.h:164
view_type view() const &&=delete
file< P > source_
Definition sort_profile_file.h:178
static mapped_sort_profile from_slice(mapped_slice source, file_open_mode mode=file_open_mode::checked)
Definition sort_profile_file.h:159
view_type view() const &
Definition sort_profile_file.h:162
void scan() const
Definition sort_profile_file.h:165
view_type view_
Definition sort_profile_file.h:180
P policy_type
Definition sort_profile_file.h:117
static mapped_sort_profile open(std::filesystem::path const &path)
Definition sort_profile_file.h:158
static mapped_sort_profile open(file< P > source)
Definition sort_profile_file.h:120
Definition object_writer.h:39
Definition object_path.h:38
Definition object_writer.h:88
static object_seal_receipt seal(std::filesystem::path const &root, object_id const &id, object_attempt_id const &attempt, file_header< P > const &header, std::span< std::span< std::byte const > const > chunks, Ops &ops)
Definition object_writer.h:164
static sample_view little_endian(std::span< std::byte const > bytes)
Definition word_view.h:92
Definition sort_profile.h:405
auto const & data() const &noexcept
Definition sort_profile.h:417
std::uint64_t size() const noexcept
Definition sort_profile.h:414
std::span< std::uint64_t const > dictionary_offsets() const noexcept
Definition sort_profile.h:419
auto const & metadata() const noexcept
Definition sort_profile.h:415
auto const & dictionary() const &noexcept
Definition sort_profile.h:418
auto const & seeds() const &noexcept
Definition sort_profile.h:420
auto const & group_offsets() const &noexcept
Definition sort_profile.h:416
Definition sort_profile.h:397
Definition sort_profile.h:176
void scan() const
Definition sort_profile.h:281
std::uint64_t size() const noexcept
Definition sort_profile.h:206
bit_view seeds() const noexcept
Definition sort_profile.h:219
bit_view data() const noexcept
Definition sort_profile.h:216
bit_view dictionary() const noexcept
Definition sort_profile.h:217
static word_view little_endian(std::span< std::byte const > bytes)
Definition word_view.h:36