CCF
Loading...
Searching...
No Matches
untyped_map.h
Go to the documentation of this file.
1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the Apache 2.0 License.
3#pragma once
4
5#include "ccf/ds/logger.h"
8#include "ccf/pal/locking.h"
9#include "ds/dl_list.h"
10#include "kv/kv_serialiser.h"
11#include "kv/kv_types.h"
13
14#include <functional>
15#include <list>
16#include <optional>
17#include <unordered_set>
18
19namespace ccf::kv::untyped
20{
22 {
23 LocalCommit() = default;
24 LocalCommit(Version v, State&& s, const Write& w) :
25 version(v),
26 state(std::move(s)),
27 writes(w)
28 {}
29
33 LocalCommit* next = nullptr;
34 LocalCommit* prev = nullptr;
35 };
37
38 struct Roll
39 {
40 std::unique_ptr<LocalCommits> commits;
42
44
46 {
47 commits->clear();
48 commits->insert_back(create_new_local_commit(0, State(), Write()));
49 }
50
51 template <typename... Args>
53 {
55 if (c == nullptr)
56 {
57 c = new LocalCommit(std::forward<Args>(args)...);
58 }
59 else
60 {
61 c->~LocalCommit();
62 new (c) LocalCommit(std::forward<Args>(args)...);
63 }
64 return c;
65 }
66 };
67
68 class Map : public AbstractMap
69 {
70 public:
74
76
79
80 private:
81 AbstractStore* store;
82 Roll roll;
83 CommitHook global_hook = nullptr;
84 MapHook hook = nullptr;
85 std::list<std::pair<Version, Write>> commit_deltas;
87 const SecurityDomain security_domain;
88
89 static State deserialize_map_snapshot(
90 std::span<const uint8_t> serialized_state)
91 {
92 State map;
93 const uint8_t* data = serialized_state.data();
94 size_t size = serialized_state.size();
95
96 while (size != 0)
97 {
98 // Deserialize the key
99 size_t key_size = size;
100 K key = map::deserialize<K>(data, size);
101 key_size -= size;
102 serialized::skip(data, size, map::get_padding(key_size));
103
104 // Deserialize the value
105 size_t value_size = size;
106 VersionV value = map::deserialize<VersionV>(data, size);
107 value_size -= size;
108 serialized::skip(data, size, map::get_padding(value_size));
109
110 // Version was previously signed, with negative values indicating
111 // deletions. Maintain ability to parse those snapshots, but do not
112 // retain these deletions locally.
113 if ((int64_t)value.version >= 0)
114 {
115 map = map.put(key, value);
116 }
117 }
118 return map;
119 }
120
121 public:
123 {
124 protected:
126
128
130
131 bool changes = false;
132 bool committed_writes = false;
133
134 public:
135 HandleCommitter(Map& m, ChangeSet& change_set_) :
136 map(m),
137 change_set(change_set_)
138 {}
139
140 // Commit-related methods
141 bool has_writes() override
142 {
143 return committed_writes || change_set.has_writes();
144 }
145
146 bool prepare() override
147 {
148 auto& map_roll = map.get_roll();
149
150 // If the parent map has rolled back since this transaction began, this
151 // transaction must fail.
152 if (change_set.rollback_counter != map_roll.rollback_counter)
153 return false;
154
155 // If we have iterated over the map, check for a global version match.
156 auto current = map_roll.commits->get_tail();
157 if (
158 (change_set.read_version != NoVersion) &&
159 (change_set.read_version != current->version))
160 {
161 LOG_DEBUG_FMT("Read version {} is invalid", change_set.read_version);
162 return false;
163 }
164
165 // Check each key in our read set.
166 for (auto it = change_set.reads.begin(); it != change_set.reads.end();
167 ++it)
168 {
169 // Get the value from the current state.
170 auto search = current->state.get(it->first);
171
172 if (std::get<0>(it->second) == NoVersion)
173 {
174 // If we depend on the key not existing, it must be absent.
175 if (search.has_value())
176 {
177 LOG_DEBUG_FMT("Read depends on non-existing entry");
178 return false;
179 }
180 }
181 else
182 {
183 // If the transaction depends on the key existing, it must be
184 // present and have the the expected version. If also tracking
185 // conflicts then ensure that the read versions also match.
186 if (
187 !search.has_value() ||
188 std::get<0>(it->second) != search.value().version)
189 {
190 LOG_DEBUG_FMT("Read depends on invalid version of entry");
191 return false;
192 }
193 }
194 }
195
196 return true;
197 }
198
199 void commit(Version v, bool track_deletes_on_missing_keys) override
200 {
201 if (change_set.writes.empty())
202 {
203 commit_version = change_set.start_version;
204 return;
205 }
206
207 auto& map_roll = map.get_roll();
208 auto state = map_roll.commits->get_tail()->state;
209
210 // Record our commit time.
211 commit_version = v;
212 committed_writes = true;
213
214 for (auto it = change_set.writes.begin(); it != change_set.writes.end();
215 ++it)
216 {
217 if (it->second.has_value())
218 {
219 // Write the new value with the global version.
220 changes = true;
221 state = state.put(it->first, VersionV{v, v, it->second.value()});
222 }
223 else
224 {
225 // Delete the key if it exists
226 auto search = state.get(it->first);
227 if (search.has_value())
228 {
229 changes = true;
230 state = state.remove(it->first);
231 }
232 else if (track_deletes_on_missing_keys)
233 {
234 // track deletes even when they delete keys that don't exist in
235 // this map's state
236 changes = true;
237 }
238 }
239 }
240
241 if (changes)
242 {
243 map.roll.commits->insert_back(map.roll.create_new_local_commit(
244 v, std::move(state), change_set.writes));
245 }
246 }
247
249 {
250 // This is run separately from commit so that all commits in the Tx
251 // have been applied before map hooks are run. The maps in the Tx
252 // are still locked when post_commit is run.
253 return map.trigger_map_hook(commit_version, change_set.writes);
254 }
255
257 {
258 commit_version = v;
259 }
260 };
261
263 {
264 private:
265 const std::string name;
266 const SecurityDomain security_domain;
267 const ccf::kv::Version version;
268
269 std::unique_ptr<StateSnapshot> map_snapshot;
270
271 public:
273 const std::string& name_,
274 SecurityDomain security_domain_,
275 ccf::kv::Version version_,
276 std::unique_ptr<StateSnapshot>&& map_snapshot_) :
277 name(name_),
278 security_domain(security_domain_),
279 version(version_),
280 map_snapshot(std::move(map_snapshot_))
281 {}
282
283 void serialise(KvStoreSerialiser& s) override
284 {
285 LOG_TRACE_FMT("Serialising snapshot for map: {}", name);
286 s.start_map(name, security_domain);
287 s.serialise_entry_version(version);
288
289 std::vector<uint8_t> ret(map_snapshot->get_serialized_size());
290 map_snapshot->serialize(ret.data());
291 s.serialise_raw(ret);
292 }
293
295 {
296 return security_domain;
297 }
298 };
299
300 // Public typedefs for external consumption
305
307 AbstractStore* store_,
308 const std::string& name_,
309 SecurityDomain security_domain_) :
310 AbstractMap(name_),
311 store(store_),
312 roll{std::make_unique<LocalCommits>(), 0, {}},
313 security_domain(security_domain_)
314 {
315 roll.reset_commits();
316 }
317
318 Map(const Map& that) = delete;
319
320 virtual AbstractMap* clone(AbstractStore* other) override
321 {
322 return (AbstractMap*)new Map(other, name, security_domain);
323 }
324
326 const AbstractChangeSet* changes,
328 bool include_reads) override
329 {
330 const auto non_abstract =
331 dynamic_cast<const ccf::kv::untyped::ChangeSet*>(changes);
332 if (non_abstract == nullptr)
333 {
334 LOG_FAIL_FMT("Unable to serialise map due to type mismatch");
335 return;
336 }
337
338 const auto& change_set = *non_abstract;
339
340 s.start_map(name, security_domain);
341
342 if (include_reads)
343 {
344 s.serialise_entry_version(change_set.read_version);
345
346 s.serialise_count_header(change_set.reads.size());
347 for (auto it = change_set.reads.begin(); it != change_set.reads.end();
348 ++it)
349 {
350 s.serialise_read(it->first, std::get<0>(it->second));
351 }
352 }
353 else
354 {
355 s.serialise_entry_version(NoVersion);
357 }
358
359 uint64_t write_ctr = 0;
360 uint64_t remove_ctr = 0;
361 for (auto it = change_set.writes.begin(); it != change_set.writes.end();
362 ++it)
363 {
364 if (it->second.has_value())
365 {
366 ++write_ctr;
367 }
368 else
369 {
370 ++remove_ctr;
371 }
372 }
373
374 s.serialise_count_header(write_ctr);
375 for (auto it = change_set.writes.begin(); it != change_set.writes.end();
376 ++it)
377 {
378 if (it->second.has_value())
379 {
380 s.serialise_write(it->first, it->second.value());
381 }
382 }
383
384 s.serialise_count_header(remove_ctr);
385 for (auto it = change_set.writes.begin(); it != change_set.writes.end();
386 ++it)
387 {
388 if (!it->second.has_value())
389 {
390 s.serialise_remove(it->first);
391 }
392 }
393 }
394
396 {
397 private:
398 Map& map;
399
400 SnapshotChangeSet& change_set;
401
402 public:
404 map(m),
405 change_set(change_set_)
406 {}
407
408 bool has_writes() override
409 {
410 return true;
411 }
412
413 bool prepare() override
414 {
415 // Snapshots never conflict
416 return true;
417 }
418
419 void commit(Version v, bool track_deletes_on_missing_keys) override
420 {
421 (void)v;
422 (void)track_deletes_on_missing_keys;
423 // Version argument is ignored. The version of the roll after the
424 // snapshot is applied depends on the version of the map at which the
425 // snapshot was taken.
426 map.roll.reset_commits();
427 map.roll.rollback_counter++;
428
429 auto r = map.roll.commits->get_head();
430
431 r->state = change_set.state;
432 r->version = change_set.version;
433
434 // Executing hooks from snapshot requires copying the entire snapshotted
435 // state so only do it if there's a hook on the table
436 if (map.hook || map.global_hook)
437 {
438 r->state.foreach([&r](const K& k, const VersionV& v) {
439 r->writes[k] = v.value;
440 return true;
441 });
442 }
443 }
444
446 {
447 auto r = map.roll.commits->get_head();
448 return map.trigger_map_hook(change_set.version, r->writes);
449 }
450 };
451
453 {
454 // Create a new empty change set, deserialising d's contents into it.
455 auto v = d.deserialise_entry_version();
456 auto map_snapshot = d.deserialise_raw();
457
458 return std::make_unique<SnapshotChangeSet>(
459 deserialize_map_snapshot(map_snapshot), v);
460 }
461
463 {
464 return deserialise_internal(d, version);
465 }
466
468 {
469 // Create a new change set, and deserialise d's contents into it.
470 auto change_set_ptr = create_change_set(version, false);
471 if (change_set_ptr == nullptr)
472 {
474 "Failed to create change set over '{}' at {} - too early",
475 name,
476 version);
477 throw std::logic_error("Can't create change set");
478 }
479
480 auto& change_set = *change_set_ptr;
481
482 uint64_t ctr;
483
484 auto rv = d.deserialise_entry_version();
485 if (rv != NoVersion)
486 {
487 change_set.read_version = rv;
488 }
489
490 ctr = d.deserialise_read_header();
491 for (size_t i = 0; i < ctr; ++i)
492 {
493 auto r = d.deserialise_read();
494 change_set.reads[std::get<0>(r)] =
495 std::make_tuple(std::get<1>(r), NoVersion);
496 }
497
498 ctr = d.deserialise_write_header();
499 for (size_t i = 0; i < ctr; ++i)
500 {
501 auto w = d.deserialise_write();
502 change_set.writes[std::get<0>(w)] = std::get<1>(w);
503 }
504
506 for (size_t i = 0; i < ctr; ++i)
507 {
508 auto r = d.deserialise_remove();
509 change_set.writes[r] = std::nullopt;
510 }
511
512 return change_set_ptr;
513 }
514
515 std::unique_ptr<AbstractCommitter> create_committer(
516 AbstractChangeSet* changes) override
517 {
518 auto non_abstract = dynamic_cast<ChangeSet*>(changes);
519 if (non_abstract == nullptr)
520 {
521 throw std::logic_error("Type confusion error");
522 }
523
524 auto snapshot_change_set = dynamic_cast<SnapshotChangeSet*>(non_abstract);
525 if (snapshot_change_set != nullptr)
526 {
527 return std::make_unique<SnapshotHandleCommitter>(
528 *this, *snapshot_change_set);
529 }
530
531 return std::make_unique<HandleCommitter>(*this, *non_abstract);
532 }
533
539 {
540 return store;
541 }
542
543 void set_map_hook(const MapHook& hook_)
544 {
545 hook = hook_;
546 }
547
549 {
550 hook = nullptr;
551 }
552
557 void set_global_hook(const CommitHook& hook_)
558 {
559 global_hook = hook_;
560 }
561
565 {
566 global_hook = nullptr;
567 }
568
574 {
575 return security_domain;
576 }
577
578 bool operator==(const Map& that) const
579 {
580 if (name != that.name)
581 return false;
582
583 auto state1 = roll.commits->get_tail();
584 auto state2 = that.roll.commits->get_tail();
585
586 if (state1->version != state2->version)
587 return false;
588
589 size_t count = 0;
590 state2->state.foreach([&count](const K&, const VersionV&) {
591 count++;
592 return true;
593 });
594
595 size_t i = 0;
596 bool ok =
597 state1->state.foreach([&state2, &i](const K& k, const VersionV& v) {
598 auto search = state2->state.get(k);
599
600 if (search.has_value())
601 {
602 auto& found = search.value();
603 if (found.version != v.version)
604 {
605 return false;
606 }
607 else if (found.value != v.value)
608 {
609 return false;
610 }
611 }
612 else
613 {
614 return false;
615 }
616
617 i++;
618 return true;
619 });
620
621 if (i != count)
622 ok = false;
623
624 return ok;
625 }
626
627#ifndef __cpp_impl_three_way_comparison
628 bool operator!=(const Map& that) const
629 {
630 return !(*this == that);
631 }
632#endif
633
634 std::unique_ptr<AbstractMap::Snapshot> snapshot(Version v) override
635 {
636 // This takes a snapshot of the state of the map at the last entry
637 // committed at or before this version. The Map expects to be locked while
638 // taking the snapshot.
639 auto r = roll.commits->get_head();
640
641 for (auto current = roll.commits->get_tail(); current != nullptr;
642 current = current->prev)
643 {
644 if (current->version <= v)
645 {
646 r = current;
647 break;
648 }
649 }
650
651 return std::make_unique<Snapshot>(
652 name, security_domain, r->version, r->state.make_snapshot());
653 }
654
655 void compact(Version v) override
656 {
657 // This discards available rollback state before version v, and
658 // populates the commit_deltas to be passed to the global commit hook,
659 // if there is one, up to version v. The Map expects to be locked during
660 // compaction.
661 while (roll.commits->get_head() != roll.commits->get_tail())
662 {
663 auto r = roll.commits->get_head();
664
665 // Globally committed but not discardable.
666 if (r->version == v)
667 {
668 // We know that write set is not empty.
669 if (global_hook)
670 {
671 commit_deltas.emplace_back(r->version, std::move(r->writes));
672 }
673 return;
674 }
675
676 // Discardable, so move to commit_deltas.
677 if (global_hook && !r->writes.empty())
678 {
679 commit_deltas.emplace_back(r->version, std::move(r->writes));
680 }
681
682 // Stop if the next state may be rolled back or is the only state.
683 // This ensures there is always a state present.
684 if (r->next->version > v)
685 return;
686
687 auto c = roll.commits->pop();
688 roll.empty_commits.insert(c);
689 }
690
691 // There is only one roll. We may need to call the commit hook.
692 auto r = roll.commits->get_head();
693
694 if (global_hook && !r->writes.empty())
695 {
696 commit_deltas.emplace_back(r->version, std::move(r->writes));
697 }
698 }
699
700 void post_compact() override
701 {
702 if (global_hook)
703 {
704 for (auto& [version, writes] : commit_deltas)
705 {
707 "Executing global hook on table {} at version {}",
708 get_name(),
709 version);
710 global_hook(version, writes);
711 }
712 }
713
714 commit_deltas.clear();
715 }
716
717 void rollback(Version v) override
718 {
719 // This rolls the current state back to version v.
720 // The Map expects to be locked during rollback.
721 bool advance = false;
722
723 while (roll.commits->get_head() != roll.commits->get_tail())
724 {
725 auto r = roll.commits->get_tail();
726
727 // The initial empty state has v = 0, so will not be discarded if it
728 // is present.
729 if (r->version <= v)
730 break;
731
732 advance = true;
733 auto c = roll.commits->pop_tail();
734 roll.empty_commits.insert(c);
735 }
736
737 if (advance)
738 roll.rollback_counter++;
739 }
740
741 void clear() override
742 {
743 // This discards all entries in the roll and resets the rollback
744 // counter. The Map expects to be locked before clearing it.
745 roll.reset_commits();
746 roll.rollback_counter = 0;
747 }
748
749 void lock() override
750 {
751 sl.lock();
752 }
753
754 void unlock() override
755 {
756 sl.unlock();
757 }
758
759 void swap(AbstractMap* map_) override
760 {
761 Map* map = dynamic_cast<Map*>(map_);
762 if (map == nullptr)
763 throw std::logic_error(
764 "Attempted to swap maps with incompatible types");
765
766 std::swap(roll, map->roll);
767 }
768
770 Version version, bool track_deletes_on_missing_keys)
771 {
772 lock();
773
774 ChangeSetPtr changes = nullptr;
775
776 // Find the last entry committed at or before this version.
777 for (auto current = roll.commits->get_tail(); current != nullptr;
778 current = current->prev)
779 {
780 if (current->version <= version)
781 {
783 if (track_deletes_on_missing_keys)
784 {
785 writes = current->writes;
786 }
787 changes = std::make_unique<untyped::ChangeSet>(
788 roll.rollback_counter,
789 current->state,
790 roll.commits->get_head()->state,
791 writes,
792 current->version);
793 break;
794 }
795 }
796
797 // Returning nullptr is allowed, and indicates that we have no suitable
798 // version - the version requested is _earlier_ than anything in the
799 // roll
800
801 unlock();
802 return changes;
803 }
804
806 {
807 return roll;
808 }
809
811 {
812 if (hook && !writes.empty())
813 {
815 "Executing local hook on table {} at version {}",
816 get_name(),
817 version);
818 return hook(version, writes);
819 }
820 return nullptr;
821 }
822 };
823}
Definition kv_types.h:590
Definition kv_types.h:598
Definition kv_types.h:614
Definition kv_types.h:611
Definition kv_types.h:680
Definition generic_serialise_wrapper.h:239
std::tuple< SerialisedKey, Version > deserialise_read()
Definition generic_serialise_wrapper.h:416
std::vector< uint8_t > deserialise_raw()
Definition generic_serialise_wrapper.h:435
std::tuple< SerialisedKey, SerialisedValue > deserialise_write()
Definition generic_serialise_wrapper.h:428
uint64_t deserialise_write_header()
Definition generic_serialise_wrapper.h:423
uint64_t deserialise_remove_header()
Definition generic_serialise_wrapper.h:445
uint64_t deserialise_read_header()
Definition generic_serialise_wrapper.h:411
Version deserialise_entry_version()
Definition generic_serialise_wrapper.h:406
SerialisedKey deserialise_remove()
Definition generic_serialise_wrapper.h:450
Definition generic_serialise_wrapper.h:20
void serialise_count_header(uint64_t ctr)
Definition generic_serialise_wrapper.h:124
void serialise_remove(const SerialisedKey &k)
Definition generic_serialise_wrapper.h:141
void serialise_raw(const std::vector< uint8_t > &raw)
Definition generic_serialise_wrapper.h:108
void start_map(const std::string &name, SecurityDomain domain)
Definition generic_serialise_wrapper.h:92
void serialise_entry_version(const Version &version)
Definition generic_serialise_wrapper.h:119
void serialise_read(const SerialisedKey &k, const Version &version)
Definition generic_serialise_wrapper.h:129
void serialise_write(const SerialisedKey &k, const SerialisedValue &v)
Definition generic_serialise_wrapper.h:135
Definition untyped_map_diff.h:19
Definition untyped_map_handle.h:18
Definition untyped_map.h:123
void commit(Version v, bool track_deletes_on_missing_keys) override
Definition untyped_map.h:199
bool prepare() override
Definition untyped_map.h:146
Version commit_version
Definition untyped_map.h:129
bool changes
Definition untyped_map.h:131
bool committed_writes
Definition untyped_map.h:132
void set_commit_version(Version v)
Definition untyped_map.h:256
ConsensusHookPtr post_commit() override
Definition untyped_map.h:248
Map & map
Definition untyped_map.h:125
ChangeSet & change_set
Definition untyped_map.h:127
HandleCommitter(Map &m, ChangeSet &change_set_)
Definition untyped_map.h:135
bool has_writes() override
Definition untyped_map.h:141
bool prepare() override
Definition untyped_map.h:413
SnapshotHandleCommitter(Map &m, SnapshotChangeSet &change_set_)
Definition untyped_map.h:403
bool has_writes() override
Definition untyped_map.h:408
void commit(Version v, bool track_deletes_on_missing_keys) override
Definition untyped_map.h:419
ConsensusHookPtr post_commit() override
Definition untyped_map.h:445
Definition untyped_map.h:263
Snapshot(const std::string &name_, SecurityDomain security_domain_, ccf::kv::Version version_, std::unique_ptr< StateSnapshot > &&map_snapshot_)
Definition untyped_map.h:272
void serialise(KvStoreSerialiser &s) override
Definition untyped_map.h:283
SecurityDomain get_security_domain() const override
Definition untyped_map.h:294
Definition untyped_map.h:69
Map(const Map &that)=delete
ChangeSetPtr deserialise_changes(KvStoreDeserialiser &d, Version version)
Definition untyped_map.h:462
void swap(AbstractMap *map_) override
Definition untyped_map.h:759
std::unique_ptr< AbstractCommitter > create_committer(AbstractChangeSet *changes) override
Definition untyped_map.h:515
void compact(Version v) override
Definition untyped_map.h:655
virtual SecurityDomain get_security_domain() override
Definition untyped_map.h:573
ConsensusHookPtr trigger_map_hook(Version version, const Write &writes)
Definition untyped_map.h:810
ChangeSetPtr deserialise_internal(KvStoreDeserialiser &d, Version version)
Definition untyped_map.h:467
bool operator==(const Map &that) const
Definition untyped_map.h:578
Map(AbstractStore *store_, const std::string &name_, SecurityDomain security_domain_)
Definition untyped_map.h:306
virtual AbstractMap * clone(AbstractStore *other) override
Definition untyped_map.h:320
void unlock() override
Definition untyped_map.h:754
ccf::kv::untyped::CommitHook CommitHook
Definition untyped_map.h:77
void clear() override
Definition untyped_map.h:741
void set_global_hook(const CommitHook &hook_)
Definition untyped_map.h:557
ccf::kv::untyped::SerialisedEntry V
Definition untyped_map.h:72
void serialise_changes(const AbstractChangeSet *changes, KvStoreSerialiser &s, bool include_reads) override
Definition untyped_map.h:325
ccf::kv::untyped::SerialisedKeyHasher H
Definition untyped_map.h:73
ChangeSetPtr create_change_set(Version version, bool track_deletes_on_missing_keys)
Definition untyped_map.h:769
ccf::kv::untyped::MapHook MapHook
Definition untyped_map.h:78
Roll & get_roll()
Definition untyped_map.h:805
bool operator!=(const Map &that) const
Definition untyped_map.h:628
ccf::kv::untyped::State::Snapshot StateSnapshot
Definition untyped_map.h:75
ccf::kv::untyped::SerialisedEntry K
Definition untyped_map.h:71
void unset_global_hook()
Definition untyped_map.h:564
ChangeSetPtr deserialise_snapshot_changes(KvStoreDeserialiser &d)
Definition untyped_map.h:452
void lock() override
Definition untyped_map.h:749
void set_map_hook(const MapHook &hook_)
Definition untyped_map.h:543
AbstractStore * get_store() override
Definition untyped_map.h:538
void unset_map_hook()
Definition untyped_map.h:548
void post_compact() override
Definition untyped_map.h:700
void rollback(Version v) override
Definition untyped_map.h:717
std::unique_ptr< AbstractMap::Snapshot > snapshot(Version v) override
Definition untyped_map.h:634
Snapshot< K, VersionV, H > Snapshot
Definition champ_map.h:403
void insert(T *item)
Definition dl_list.h:87
T * pop()
Definition dl_list.h:67
#define LOG_TRACE_FMT
Definition logger.h:356
#define LOG_DEBUG_FMT
Definition logger.h:357
#define LOG_FAIL_FMT
Definition logger.h:363
Definition untyped.h:12
ccf::kv::CommitHook< Write > CommitHook
Definition untyped.h:18
ccf::ByteVector SerialisedEntry
Definition untyped_change_set.h:19
std::hash< SerialisedEntry > SerialisedKeyHasher
Definition untyped_change_set.h:20
std::map< ccf::kv::serialisers::SerialisedEntry, std::optional< ccf::kv::serialisers::SerialisedEntry > > Write
Definition untyped.h:16
std::unique_ptr< ChangeSet > ChangeSetPtr
Definition untyped_change_set.h:78
ccf::kv::MapHook< Write > MapHook
Definition untyped.h:19
champ::Map< K, VersionV, H > State
Definition untyped_change_set.h:29
SecurityDomain
Definition kv_types.h:255
std::unique_ptr< ConsensusHook > ConsensusHookPtr
Definition hooks.h:21
uint64_t Version
Definition version.h:8
std::mutex Mutex
Definition locking.h:12
Definition map_serializers.h:11
void skip(const uint8_t *&data, size_t &size, size_t skip)
Definition serialized.h:166
STL namespace.
std::string name
Definition get_name.h:12
Definition version_v.h:11
V value
Definition version_v.h:14
Version version
Definition version_v.h:12
Definition untyped_change_set.h:43
ccf::kv::untyped::Read reads
Definition untyped_change_set.h:54
const size_t rollback_counter
Definition untyped_change_set.h:48
bool has_writes() const override
Definition untyped_change_set.h:72
Version read_version
Definition untyped_change_set.h:53
const Version start_version
Definition untyped_change_set.h:51
ccf::kv::untyped::Write writes
Definition untyped_change_set.h:55
Definition untyped_map.h:22
State state
Definition untyped_map.h:31
LocalCommit * next
Definition untyped_map.h:33
LocalCommit(Version v, State &&s, const Write &w)
Definition untyped_map.h:24
LocalCommit * prev
Definition untyped_map.h:34
Version version
Definition untyped_map.h:30
Write writes
Definition untyped_map.h:32
Definition untyped_map.h:39
LocalCommits empty_commits
Definition untyped_map.h:43
LocalCommit * create_new_local_commit(Args &&... args)
Definition untyped_map.h:52
void reset_commits()
Definition untyped_map.h:45
size_t rollback_counter
Definition untyped_map.h:41
std::unique_ptr< LocalCommits > commits
Definition untyped_map.h:40
Definition untyped_change_set.h:83
const ccf::kv::untyped::State state
Definition untyped_change_set.h:84
const Version version
Definition untyped_change_set.h:85