21#if defined(__APPLE__) || defined(__linux__)
22 int create(std::filesystem::path
const & path)
noexcept {
23 return ::open(path.c_str(), O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC | O_NOFOLLOW, 0600);
25 int remove(std::filesystem::path
const & path)
noexcept { return ::unlink(path.c_str()); }
26 std::ptrdiff_t write(
int fd, std::span<std::byte const> bytes)
noexcept { return ::write(fd, bytes.data(), bytes.size()); }
27 std::ptrdiff_t read_at(
int fd, std::span<std::byte> bytes, std::uint64_t at)
noexcept {
28 return ::pread(fd, bytes.data(), bytes.size(),
static_cast<off_t
>(at));
30 int close(
int fd)
noexcept { return ::close(fd); }
35 std::optional<blob_identity>
main;
38 namespace cola_detail {
48 void append(std::span<std::byte const> bytes) {
49 if (bytes.size() > std::uint64_t(std::numeric_limits<std::int64_t>::max()) -
bytes_)
50 throw std::length_error(
"secondary index spool extent");
51 if (bytes.empty())
return;
55 if (
ops_.remove(
path_) < 0)
fail(
"unlink secondary index spool");
58 while (!bytes.empty()) {
59 auto part = bytes.first(std::min(bytes.size(), std::size_t{1} << 20));
61 if (n < 0 && errno == EINTR)
continue;
62 if (n <= 0 || std::uint64_t(n) > part.size())
fail(
"write secondary index spool", n < 0 ? errno : EIO);
63 bytes_ += std::uint64_t(n); bytes = bytes.subspan(std::size_t(n));
66 template <
class Stream>
void replay(Stream & out) {
67 std::array<std::byte, 64 * 1024> buffer;
70 auto part = std::span(buffer).first(std::size_t(std::min<std::uint64_t>(
bytes_ - at, buffer.size())));
71 auto n =
ops_.read_at(
fd_, part, at);
72 if (n < 0 && errno == EINTR)
continue;
73 if (n <= 0 || std::uint64_t(n) > part.size())
fail(
"read secondary index spool", n < 0 ? errno : EIO);
74 out.append(std::span<std::byte const>(part).first(std::size_t(n))); at += std::uint64_t(n);
83 [[noreturn]]
static void fail(
char const * operation,
int code = errno) {
84 throw std::system_error(code, std::generic_category(), operation);
91 template <
class Sink>
void append(Sink & sink,
bit_view key, std::uint64_t common) {
92 if (key.size() & (P::bits_per_unit - 1))
throw std::invalid_argument(
"borrowed file key units");
93 auto retained = common >> P::unit_shift;
94 auto size = key.size() >> P::unit_shift;
97 if (block)
starts.push_back(sink.position() >> P::unit_shift);
100 else if (block) sink.template write_count<exponential_golomb<0>>(control);
101 else sink.template write_count<typename P::backspace_encoding>(control);
102 count(sink, size - retained);
103 sink.append(key.subview(retained << P::unit_shift, key.size() - (retained << P::unit_shift)));
111 template <
class Sink>
void finish(Sink & sink) {
115 template <
class Sink>
static void count(Sink & sink, std::uint64_t value) {
118 do {
auto byte = unsigned(value & 127); value >>= 7; sink.write_bits(
byte | (value ? 128 : 0), 8); }
while (value);
123 template <
class P,
class Sink,
class Stream,
class Spool>
126 std::uint64_t native_size, Sink & sink, Stream & stream, Spool & spool) {
127 auto emit_offsets = [&](
elias_fano const & ef) {
128 sink.align(); sink.words(ef.low); sink.align(); sink.words(ef.high);
129 sink.align(); sink.samples(ef.samples); sink.align(); sink.words(ef.sparse);
131 std::array<std::byte, cola_section_detail::directory_bytes> directory{};
132 for (
unsigned i = 0; i != 4; ++i) directory[i] = std::byte(
"IX03"[i]);
135 if (dependencies.
main) {
140 std::array<std::uint64_t, cola_section_detail::section_count> lengths{};
141 std::uint64_t count = 0;
143 auto const & state = profiles[
route];
auto const & m = state.metadata;
auto const & ef = state.offsets;
150 lengths[slot + 1] = ef.low.size() * 8; lengths[slot + 2] = ef.high.size() * 8;
151 lengths[slot + 3] = ef.samples.size() * 16; lengths[slot + 4] = ef.sparse.size() * 8;
153 lengths[slot] = metadata.
ranks[
route].classes.size() * 8;
154 lengths[slot + 1] = metadata.
ranks[
route].checkpoints.size() * 8;
157 count += m.record_count;
159 if (count > metadata.
count || native_size != metadata.
count - count)
160 throw std::invalid_argument(
"streamed COLA native count");
161 std::uint64_t end = directory.size();
162 for (std::size_t i = 0; i != lengths.size(); ++i) {
167 emit_offsets(profiles[0].offsets);
168 sink.align(); spool.replay(stream); emit_offsets(profiles[1].offsets);
170 sink.align(); sink.words(metadata.
ranks[
route].classes);
171 sink.align(); sink.words(metadata.
ranks[
route].checkpoints);
173 for (
auto const & flags : metadata.
flags) { sink.align(); stream.append(flags); }
174 for (
auto const & cuts : metadata.
cuts) { sink.align(); sink.words(cuts); }
176 return stream.finish(header, directory);
187 cola_section_detail::directory_bytes, ops),
199 else throw std::out_of_range(
"borrowed file route");
200 }
catch (...) {
failed_ =
true;
throw; }
207 throw std::invalid_argument(
"streamed COLA dependency shape");
210 }
catch (...) {
failed_ =
true;
throw; }
222 auto valid = [](
object_id const & id) {
if (
id.hex().size() != 32)
throw std::invalid_argument(
"COLA file dependency identity"); };
223 valid(deps.
native);
if (deps.
main) { valid(deps.
main->native); valid(deps.
main->index); }
232 template <
class Native,
class Main,
class Metadata>
auto finish(std::shared_ptr<Native const>
native,
233 std::shared_ptr<Main const>
main, std::shared_ptr<Native const>
secondary, Metadata metadata) {
240 template <
class P,
class Native = profile_array<P>,
class Main =
void,
241 class Ops = posix_
object_ops,
class SpoolOps = posix_index_spool_ops>
254 Ops & ops, SpoolOps & spool_ops)
255 :
output_(std::move(root), std::move(id), std::move(attempt), std::move(dependencies), ops, spool_ops),
Encodes two-target COLA routing in portable IX03 sections.
object_seal_receipt seal_file_index(cola_file_dependencies const &dependencies, std::array< borrowed_file_state< P >, 2 > const &profiles, index_metadata< P > const &metadata, std::uint64_t native_size, Sink &sink, Stream &stream, Spool &spool)
Definition cola_file_index.h:124
unsigned route(unsigned value)
Definition cola_index.h:37
constexpr std::size_t profile_slot(unsigned route) noexcept
Definition cola_sections.h:32
constexpr std::size_t section_count
Definition cola_sections.h:30
constexpr std::size_t flags_slot(unsigned route) noexcept
Definition cola_sections.h:34
constexpr std::size_t cuts_slot(unsigned route) noexcept
Definition cola_sections.h:35
constexpr std::size_t descriptor_offset
Definition cola_sections.h:30
constexpr std::size_t rank_slot(unsigned route) noexcept
Definition cola_sections.h:33
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 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
void put_id(std::span< std::byte > bytes, std::size_t at, object_id const &id)
Definition sections.h:75
Definition active_engine.h:18
file_kind
Definition object_path.h:25
Streams sort-owned KV03 payloads with bounded buffering and shared framing.
Definition cola_file_index.h:87
profile_metadata metadata
Definition cola_file_index.h:88
elias_fano offsets
Definition cola_file_index.h:90
static void count(Sink &sink, std::uint64_t value)
Definition cola_file_index.h:115
void finish(Sink &sink)
Definition cola_file_index.h:111
std::vector< std::uint64_t > starts
Definition cola_file_index.h:89
void finish_metadata(std::uint64_t bits)
Definition cola_file_index.h:106
void append(Sink &sink, bit_view key, std::uint64_t common)
Definition cola_file_index.h:91
Definition cola_file_index.h:228
bool failed() const noexcept
Definition cola_file_index.h:230
auto finish(std::shared_ptr< Native const > native, std::shared_ptr< Main const > main, std::shared_ptr< Native const > secondary, Metadata metadata)
Definition cola_file_index.h:232
void append_known(unsigned route, bit_view key, std::uint64_t common)
Definition cola_file_index.h:231
Output * output
Definition cola_file_index.h:229
Definition cola_file_index.h:178
object_seal_receipt finish(std::shared_ptr< Native const > native, std::shared_ptr< Main const > main, std::shared_ptr< Native const > secondary, index_metadata< P > metadata)
Definition cola_file_index.h:202
static cola_file_dependencies checked(cola_file_dependencies deps)
Definition cola_file_index.h:221
object_write_paths const & paths() const &&=delete
object_write_paths const & paths() const &noexcept
Definition cola_file_index.h:191
std::array< borrowed_file_state< P >, 2 > profiles_
Definition cola_file_index.h:218
std::uint64_t spooled_bytes() const noexcept
Definition cola_file_index.h:193
cola_file_dependencies dependencies_
Definition cola_file_index.h:213
file_index_output(std::filesystem::path root, object_id id, object_attempt_id attempt, cola_file_dependencies dependencies, Ops &ops, SpoolOps &spool_ops)
Definition cola_file_index.h:183
bool failed() const noexcept
Definition cola_file_index.h:189
bool finished() const noexcept
Definition cola_file_index.h:190
stream_type stream_
Definition cola_file_index.h:214
bool failed_
Definition cola_file_index.h:219
spool_type spool_
Definition cola_file_index.h:215
main_sink main_
Definition cola_file_index.h:216
void require_active() const
Definition cola_file_index.h:220
void append_known(unsigned route, bit_view key, std::uint64_t common)
Definition cola_file_index.h:194
secondary_sink secondary_
Definition cola_file_index.h:217
Definition cola_file_index.h:39
std::filesystem::path path_
Definition cola_file_index.h:78
void replay(Stream &out)
Definition cola_file_index.h:66
bool named_
Definition cola_file_index.h:81
std::uint64_t bytes_
Definition cola_file_index.h:82
secondary_spool(std::filesystem::path path, Ops &ops)
Definition cola_file_index.h:40
int fd_
Definition cola_file_index.h:80
Ops & ops_
Definition cola_file_index.h:79
secondary_spool(secondary_spool const &)=delete
std::uint64_t body_bytes() const noexcept
Definition cola_file_index.h:47
static void fail(char const *operation, int code=errno)
Definition cola_file_index.h:83
~secondary_spool()
Definition cola_file_index.h:43
secondary_spool & operator=(secondary_spool const &)=delete
void append(std::span< std::byte const > bytes)
Definition cola_file_index.h:48
Definition cola_file_index.h:33
object_id native
Definition cola_file_index.h:34
std::optional< blob_identity > main
Definition cola_file_index.h:35
std::optional< object_id > secondary
Definition cola_file_index.h:36
Definition cola_file_index.h:242
object_seal_receipt finish()
Definition cola_file_index.h:269
std::uint64_t step(std::uint64_t budget)
Definition cola_file_index.h:268
object_write_paths const & paths() const &&=delete
typename builder_type::main_pointer main_pointer
Definition cola_file_index.h:246
cola_file_index_builder(std::filesystem::path root, object_id id, object_attempt_id attempt, cola_file_dependencies dependencies, native_pointer native, main_pointer main, native_pointer secondary, Ops &ops, SpoolOps &spool_ops)
Definition cola_file_index.h:252
native_pointer native_owner() const noexcept
Definition cola_file_index.h:265
std::uint64_t size() const noexcept
Definition cola_file_index.h:264
cola_file_index_builder & operator=(cola_file_index_builder const &)=delete
object_write_paths const & paths() const &noexcept
Definition cola_file_index.h:271
cola_file_index_builder(std::filesystem::path root, object_id id, object_attempt_id attempt, cola_file_dependencies dependencies, native_pointer native, main_pointer main={}, native_pointer secondary={})
Definition cola_file_index.h:247
std::optional< Ops > owned_ops_
Definition cola_file_index.h:274
native_pointer secondary_target() const noexcept
Definition cola_file_index.h:267
cola_file_index_builder & operator=(cola_file_index_builder &&)=delete
bool done() const noexcept
Definition cola_file_index.h:261
typename builder_type::native_pointer native_pointer
Definition cola_file_index.h:245
cola_file_index_builder(cola_file_index_builder const &)=delete
bool finished() const noexcept
Definition cola_file_index.h:263
bool failed() const noexcept
Definition cola_file_index.h:262
output_type output_
Definition cola_file_index.h:276
main_pointer main_target() const noexcept
Definition cola_file_index.h:266
std::uint64_t spooled_bytes() const noexcept
Definition cola_file_index.h:270
std::optional< SpoolOps > owned_spool_ops_
Definition cola_file_index.h:275
cola_file_index_builder(cola_file_index_builder &&)=delete
builder_type builder_
Definition cola_file_index.h:277
native_pointer secondary_target() const noexcept
Definition cola_index.h:528
std::uint64_t size() const noexcept
Definition cola_index.h:525
main_pointer main_target() const noexcept
Definition cola_index.h:527
bool failed() const noexcept
Definition cola_index.h:523
typename index_type::main_pointer main_pointer
Definition cola_index.h:501
bool finished() const noexcept
Definition cola_index.h:524
native_pointer native_owner() const noexcept
Definition cola_index.h:526
auto finish()
Definition cola_index.h:581
bool done() const noexcept
Definition cola_index.h:520
std::uint64_t step(std::uint64_t budget)
Definition cola_index.h:529
typename index_type::native_pointer native_pointer
Definition cola_index.h:499
Definition elias_fano.h:397
Definition object_writer.h:39
Definition object_path.h:38
Definition object_writer.h:88
object_write_paths const & paths() const &noexcept
Definition object_stream.h:62
bool failed() const noexcept
Definition object_stream.h:60
bool finished() const noexcept
Definition object_stream.h:61
Definition object_writer.h:53
Definition cola_file_index.h:20
Definition sort_profile_file_writer.h:19