25 using pair_type =
typename family_type::node_type::pair_type;
27 inline static constexpr std::array<std::byte, 8> magic{
28 std::byte{
'E'}, std::byte{
'V'}, std::byte{
'R'}, std::byte{
'T'},
29 std::byte{
'R'}, std::byte{
'F'}, std::byte{0}, std::byte{1}};
34 std::vector<object_pointer> result;
35 std::unordered_map<std::uint64_t, object_pointer> seen;
36 std::unordered_set<std::uint64_t>
active;
37 auto visit = [&](
auto && self,
object_pointer const & value) ->
void {
39 if (
auto found = seen.find(value->identity); found != seen.end()) {
40 if (found->second != value)
throw std::invalid_argument(
"duplicate checkpoint object identity");
43 if (!value->identity || !
active.insert(value->identity).second)
44 throw std::invalid_argument(
"cyclic checkpoint object routes");
45 self(self, value->next.main); self(self, value->next.secondary);
46 active.erase(value->identity); seen.emplace(value->identity, value); result.push_back(value);
48 auto routes = [&](
auto const & value) { visit(visit, value.main); visit(visit, value.secondary); };
49 routes(frontier.root);
50 for (
auto const & level : frontier.levels) {
51 for (
auto const & slot : level.slots) { visit(visit, slot.object); routes(slot.route); }
53 auto const & job = *level.job;
54 routes(job.destination_route); visit(visit, job.existing_main); visit(visit, job.output);
64 auto const & levels = source.frontier().levels;
65 for (
auto level = levels.rbegin(); level != levels.rend(); ++level)
66 for (
auto const & slot : level->slots)
if (slot.object) visit(slot.object);
69 std::size_t count = 0;
70 for_each_object(source, [&](
auto const &) { ++count; });
74 pair(source.query_root().head());
75 for_each_object(source, [&](
auto const &
object) { pair(object->pair);
native(object->native); });
76 for (
auto const & level : source.frontier().levels) {
77 for (
auto const & slot : level.slots) pair(slot.carrier);
78 if (level.job) { pair(level.job->carrier);
native(level.job->merged); }
81 template <
class Pair,
class Native>
static std::vector<std::byte>
encode(
snapshot_type const & source,
82 std::span<std::byte const> semantic, Pair pair_id, Native native_id) {
83 std::vector<std::byte> out(magic.begin(), magic.end());
85 auto object = [&](
object_pointer const & value) { number(value ? value->identity : 0); };
86 auto routes = [&](
auto const & value) { object(value.main); object(value.secondary); };
89 auto const & f = source.frontier();
90 number(f.admissions); number(f.next_identity); number(f.service_due);
91 number(object_count(source));
92 for_each_object(source, [&](
auto const & value) {
93 number(value->identity); number(value->first); number(value->last); number(value->level);
94 native(value->native); pair(value->pair); routes(value->next);
96 routes(f.root); number(f.levels.size());
97 for (
auto const & level : f.levels) {
98 number(level.last_destination); number(level.last_destination_visible);
99 for (
auto const & slot : level.slots) {
100 number(
static_cast<unsigned>(slot.state)); object(slot.object); routes(slot.route);
101 pair(slot.carrier); number(slot.ever_visible);
103 number(
bool(level.job));
105 auto const & job = *level.job;
106 for (
auto input : job.inputs) number(input);
107 number(job.destination); number(job.carrier_slot); number(job.new_main);
108 routes(job.destination_route); object(job.existing_main); object(job.output);
109 native(job.merged); pair(job.carrier); number(
static_cast<unsigned>(job.stage));
115 std::span<std::byte const> encoded,
blob_identity const & head, Resolver & resolver) {
116 if (encoded.size() < magic.size() || !std::equal(magic.begin(), magic.end(), encoded.begin()))
117 throw std::invalid_argument(
"unsupported redundant Everett checkpoint");
119 auto small = [&](
unsigned maximum) {
121 if (n > maximum)
throw std::invalid_argument(
"invalid redundant checkpoint field");
122 return static_cast<unsigned>(n);
124 auto flag = [&] {
return small(1) != 0; };
126 if (!flag())
return {};
127 auto native = input.field(), index = input.field();
131 std::unordered_map<std::uint64_t, object_pointer> objects;
133 auto id = input.number();
135 auto found = objects.find(
id);
136 if (found == objects.end())
throw std::invalid_argument(
"checkpoint route is not a preceding object");
137 return found->second;
141 f.admissions = input.number(); f.next_identity = input.number(); f.service_due = input.number();
142 auto count = input.number();
143 if (count > input.data.size() / 64)
throw std::invalid_argument(
"invalid checkpoint object count");
144 for (std::uint64_t i = 0; i != count; ++i) {
146 value.identity = input.number(); value.first = input.number(); value.last = input.number(); value.level = small(63);
147 value.native =
native(); value.pair = pair(); value.next = routes();
148 auto id = value.identity;
149 if (!
id || !objects.emplace(
id, std::make_shared<object_type const>(std::move(value))).second)
150 throw std::invalid_argument(
"duplicate checkpoint object identity");
153 auto levels = small(64); f.levels.resize(levels);
154 for (
auto & level : f.levels) {
155 level.last_destination = input.number(); level.last_destination_visible = flag();
156 for (
auto & slot : level.slots) {
158 slot.object = object(); slot.route = routes(); slot.carrier = pair(); slot.ever_visible = flag();
161 auto & job = level.job.emplace();
162 for (
auto & slot : job.inputs) slot = small(2);
163 job.destination = small(2); job.carrier_slot = small(2); job.new_main = flag();
164 job.destination_route = routes(); job.existing_main = object(); job.output = object();
165 job.merged =
native(); job.carrier = pair();
169 auto size = input.number();
170 if (size != input.data.size())
throw std::invalid_argument(
"invalid redundant semantic extent");
171 std::vector<std::byte> semantic(input.data.begin(), input.data.end());
172 auto restored = snapshot_type::restore(std::move(f), resolver.pair(head));
173 if (runtime_storage_codec::object_count(restored) != objects.size())
174 throw std::invalid_argument(
"unreachable redundant checkpoint object");
175 return {std::move(restored), std::move(semantic)};
void number(bytes &out, std::uint64_t value)
Definition sqlite_catalog.h:109
void pair(bytes &out, blob_identity const &value)
Definition sqlite_catalog.h:121
void identity(bytes &out, object_id const &value)
Definition sqlite_catalog.h:117
void binary(bytes &out, std::span< std::byte const > value)
Definition sqlite_catalog.h:127
Definition active_engine.h:18
redundant_slot_state
Definition redundant_runtime.h:151
redundant_stage
Definition redundant_runtime.h:152
Executes redundant COLA slots with charged jobs and immutable frontiers.
Selects runtime checkpoint codecs and encodes binary admission intervals.
Definition sqlite_catalog.h:152
std::uint64_t number()
Definition sqlite_catalog.h:155
Definition runtime_checkpoint.h:58
Definition object_path.h:38
Definition redundant_runtime.h:139
Definition redundant_runtime.h:918
typename family_type::node_type::pair_type pair_type
Definition redundant_checkpoint.h:25
static void collect(snapshot_type const &source, Pair pair, Native native)
Definition redundant_checkpoint.h:73
static void for_each_object(snapshot_type const &source, F &&visit)
Definition redundant_checkpoint.h:63
typename family_type::frontier_type frontier_type
Definition redundant_checkpoint.h:21
static decoded_runtime_checkpoint< snapshot_type > decode(std::span< std::byte const > encoded, blob_identity const &head, Resolver &resolver)
Definition redundant_checkpoint.h:114
typename family_type::node_type::native_pointer native_pointer
Definition redundant_checkpoint.h:26
typename family_type::snapshot_type snapshot_type
Definition redundant_checkpoint.h:20
static std::size_t object_count(snapshot_type const &source) noexcept
Definition redundant_checkpoint.h:68
static std::vector< object_pointer > objects(frontier_type const &frontier)
Definition redundant_checkpoint.h:33
typename snapshot_type::object_pointer object_pointer
Definition redundant_checkpoint.h:24
static std::vector< std::byte > encode(snapshot_type const &source, std::span< std::byte const > semantic, Pair pair_id, Native native_id)
Definition redundant_checkpoint.h:81
typename family_type::object_type object_type
Definition redundant_checkpoint.h:22
typename family_type::routes_type routes_type
Definition redundant_checkpoint.h:23
Definition runtime_checkpoint.h:62