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(bool track_read_versions) 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 (track_read_versions &&
190 std::get<1>(it->second) != search.value().read_version))
191 {
192 LOG_DEBUG_FMT("Read depends on invalid version of entry");
193 return false;
194 }
195 }
196 }
197
198 return true;
199 }
200
201 void commit(
202 Version v,
203 bool track_read_versions,
204 bool track_deletes_on_missing_keys) override
205 {
206 if (change_set.writes.empty() && !track_read_versions)
207 {
208 commit_version = change_set.start_version;
209 return;
210 }
211
212 auto& map_roll = map.get_roll();
213 auto state = map_roll.commits->get_tail()->state;
214
215 // To track conflicts the read version of all keys that are read or
216 // written within a transaction must be updated.
217 if (track_read_versions)
218 {
219 for (auto it = change_set.reads.begin(); it != change_set.reads.end();
220 ++it)
221 {
222 auto search = state.get(it->first);
223 if (!search.has_value())
224 {
225 continue;
226 }
227 state =
228 state.put(it->first, VersionV{search->version, v, search->value});
229 }
230 if (change_set.writes.empty())
231 {
232 commit_version = change_set.start_version;
233 map.roll.commits->insert_back(map.roll.create_new_local_commit(
234 commit_version, std::move(state), change_set.writes));
235 return;
236 }
237 }
238
239 // Record our commit time.
240 commit_version = v;
241 committed_writes = true;
242
243 for (auto it = change_set.writes.begin(); it != change_set.writes.end();
244 ++it)
245 {
246 if (it->second.has_value())
247 {
248 // Write the new value with the global version.
249 changes = true;
250 state = state.put(it->first, VersionV{v, v, it->second.value()});
251 }
252 else
253 {
254 // Delete the key if it exists
255 auto search = state.get(it->first);
256 if (search.has_value())
257 {
258 changes = true;
259 state = state.remove(it->first);
260 }
261 else if (track_deletes_on_missing_keys)
262 {
263 // track deletes even when they delete keys that don't exist in
264 // this map's state
265 changes = true;
266 }
267 }
268 }
269
270 if (changes)
271 {
272 map.roll.commits->insert_back(map.roll.create_new_local_commit(
273 v, std::move(state), change_set.writes));
274 }
275 }
276
278 {
279 // This is run separately from commit so that all commits in the Tx
280 // have been applied before map hooks are run. The maps in the Tx
281 // are still locked when post_commit is run.
282 return map.trigger_map_hook(commit_version, change_set.writes);
283 }
284
286 {
287 commit_version = v;
288 }
289 };
290
292 {
293 private:
294 const std::string name;
295 const SecurityDomain security_domain;
296 const ccf::kv::Version version;
297
298 std::unique_ptr<StateSnapshot> map_snapshot;
299
300 public:
302 const std::string& name_,
303 SecurityDomain security_domain_,
304 ccf::kv::Version version_,
305 std::unique_ptr<StateSnapshot>&& map_snapshot_) :
306 name(name_),
307 security_domain(security_domain_),
308 version(version_),
309 map_snapshot(std::move(map_snapshot_))
310 {}
311
312 void serialise(KvStoreSerialiser& s) override
313 {
314 LOG_TRACE_FMT("Serialising snapshot for map: {}", name);
315 s.start_map(name, security_domain);
316 s.serialise_entry_version(version);
317
318 std::vector<uint8_t> ret(map_snapshot->get_serialized_size());
319 map_snapshot->serialize(ret.data());
320 s.serialise_raw(ret);
321 }
322
324 {
325 return security_domain;
326 }
327 };
328
329 // Public typedefs for external consumption
334
336 AbstractStore* store_,
337 const std::string& name_,
338 SecurityDomain security_domain_) :
339 AbstractMap(name_),
340 store(store_),
341 roll{std::make_unique<LocalCommits>(), 0, {}},
342 security_domain(security_domain_)
343 {
344 roll.reset_commits();
345 }
346
347 Map(const Map& that) = delete;
348
349 virtual AbstractMap* clone(AbstractStore* other) override
350 {
351 return (AbstractMap*)new Map(other, name, security_domain);
352 }
353
355 const AbstractChangeSet* changes,
357 bool include_reads) override
358 {
359 const auto non_abstract =
360 dynamic_cast<const ccf::kv::untyped::ChangeSet*>(changes);
361 if (non_abstract == nullptr)
362 {
363 LOG_FAIL_FMT("Unable to serialise map due to type mismatch");
364 return;
365 }
366
367 const auto& change_set = *non_abstract;
368
369 s.start_map(name, security_domain);
370
371 if (include_reads)
372 {
374
375 s.serialise_count_header(change_set.reads.size());
376 for (auto it = change_set.reads.begin(); it != change_set.reads.end();
377 ++it)
378 {
379 s.serialise_read(it->first, std::get<0>(it->second));
380 }
381 }
382 else
383 {
384 s.serialise_entry_version(NoVersion);
386 }
387
388 uint64_t write_ctr = 0;
389 uint64_t remove_ctr = 0;
390 for (auto it = change_set.writes.begin(); it != change_set.writes.end();
391 ++it)
392 {
393 if (it->second.has_value())
394 {
395 ++write_ctr;
396 }
397 else
398 {
399 ++remove_ctr;
400 }
401 }
402
403 s.serialise_count_header(write_ctr);
404 for (auto it = change_set.writes.begin(); it != change_set.writes.end();
405 ++it)
406 {
407 if (it->second.has_value())
408 {
409 s.serialise_write(it->first, it->second.value());
410 }
411 }
412
413 s.serialise_count_header(remove_ctr);
414 for (auto it = change_set.writes.begin(); it != change_set.writes.end();
415 ++it)
416 {
417 if (!it->second.has_value())
418 {
419 s.serialise_remove(it->first);
420 }
421 }
422 }
423
425 {
426 private:
427 Map& map;
428
429 SnapshotChangeSet& change_set;
430
431 public:
433 map(m),
434 change_set(change_set_)
435 {}
436
437 bool has_writes() override
438 {
439 return true;
440 }
441
442 bool prepare(bool) override
443 {
444 // Snapshots never conflict
445 return true;
446 }
447
448 void commit(Version, bool, bool) override
449 {
450 // Version argument is ignored. The version of the roll after the
451 // snapshot is applied depends on the version of the map at which the
452 // snapshot was taken.
453 map.roll.reset_commits();
454 map.roll.rollback_counter++;
455
456 auto r = map.roll.commits->get_head();
457
458 r->state = change_set.state;
459 r->version = change_set.version;
460
461 // Executing hooks from snapshot requires copying the entire snapshotted
462 // state so only do it if there's a hook on the table
463 if (map.hook || map.global_hook)
464 {
465 r->state.foreach([&r](const K& k, const VersionV& v) {
466 r->writes[k] = v.value;
467 return true;
468 });
469 }
470 }
471
473 {
474 auto r = map.roll.commits->get_head();
475 return map.trigger_map_hook(change_set.version, r->writes);
476 }
477 };
478
480 {
481 // Create a new empty change set, deserialising d's contents into it.
482 auto v = d.deserialise_entry_version();
483 auto map_snapshot = d.deserialise_raw();
484
485 return std::make_unique<SnapshotChangeSet>(
486 deserialize_map_snapshot(map_snapshot), v);
487 }
488
490 {
491 return deserialise_internal(d, version);
492 }
493
495 {
496 // Create a new change set, and deserialise d's contents into it.
497 auto change_set_ptr = create_change_set(version, false);
498 if (change_set_ptr == nullptr)
499 {
501 "Failed to create change set over '{}' at {} - too early",
502 name,
503 version);
504 throw std::logic_error("Can't create change set");
505 }
506
507 auto& change_set = *change_set_ptr;
508
509 uint64_t ctr;
510
511 auto rv = d.deserialise_entry_version();
512 if (rv != NoVersion)
513 {
514 change_set.read_version = rv;
515 }
516
517 ctr = d.deserialise_read_header();
518 for (size_t i = 0; i < ctr; ++i)
519 {
520 auto r = d.deserialise_read();
521 change_set.reads[std::get<0>(r)] =
522 std::make_tuple(std::get<1>(r), NoVersion);
523 }
524
525 ctr = d.deserialise_write_header();
526 for (size_t i = 0; i < ctr; ++i)
527 {
528 auto w = d.deserialise_write();
529 change_set.writes[std::get<0>(w)] = std::get<1>(w);
530 }
531
532 ctr = d.deserialise_remove_header();
533 for (size_t i = 0; i < ctr; ++i)
534 {
535 auto r = d.deserialise_remove();
536 change_set.writes[r] = std::nullopt;
537 }
538
539 return change_set_ptr;
540 }
541
542 std::unique_ptr<AbstractCommitter> create_committer(
543 AbstractChangeSet* changes) override
544 {
545 auto non_abstract = dynamic_cast<ChangeSet*>(changes);
546 if (non_abstract == nullptr)
547 {
548 throw std::logic_error("Type confusion error");
549 }
550
551 auto snapshot_change_set = dynamic_cast<SnapshotChangeSet*>(non_abstract);
552 if (snapshot_change_set != nullptr)
553 {
554 return std::make_unique<SnapshotHandleCommitter>(
555 *this, *snapshot_change_set);
556 }
557
558 return std::make_unique<HandleCommitter>(*this, *non_abstract);
559 }
560
566 {
567 return store;
568 }
569
570 void set_map_hook(const MapHook& hook_)
571 {
572 hook = hook_;
573 }
574
576 {
577 hook = nullptr;
578 }
579
584 void set_global_hook(const CommitHook& hook_)
585 {
586 global_hook = hook_;
587 }
588
592 {
593 global_hook = nullptr;
594 }
595
601 {
602 return security_domain;
603 }
604
605 bool operator==(const Map& that) const
606 {
607 if (name != that.name)
608 return false;
609
610 auto state1 = roll.commits->get_tail();
611 auto state2 = that.roll.commits->get_tail();
612
613 if (state1->version != state2->version)
614 return false;
615
616 size_t count = 0;
617 state2->state.foreach([&count](const K&, const VersionV&) {
618 count++;
619 return true;
620 });
621
622 size_t i = 0;
623 bool ok =
624 state1->state.foreach([&state2, &i](const K& k, const VersionV& v) {
625 auto search = state2->state.get(k);
626
627 if (search.has_value())
628 {
629 auto& found = search.value();
630 if (found.version != v.version)
631 {
632 return false;
633 }
634 else if (found.value != v.value)
635 {
636 return false;
637 }
638 }
639 else
640 {
641 return false;
642 }
643
644 i++;
645 return true;
646 });
647
648 if (i != count)
649 ok = false;
650
651 return ok;
652 }
653
654#ifndef __cpp_impl_three_way_comparison
655 bool operator!=(const Map& that) const
656 {
657 return !(*this == that);
658 }
659#endif
660
661 std::unique_ptr<AbstractMap::Snapshot> snapshot(Version v) override
662 {
663 // This takes a snapshot of the state of the map at the last entry
664 // committed at or before this version. The Map expects to be locked while
665 // taking the snapshot.
666 auto r = roll.commits->get_head();
667
668 for (auto current = roll.commits->get_tail(); current != nullptr;
669 current = current->prev)
670 {
671 if (current->version <= v)
672 {
673 r = current;
674 break;
675 }
676 }
677
678 return std::make_unique<Snapshot>(
679 name, security_domain, r->version, r->state.make_snapshot());
680 }
681
682 void compact(Version v) override
683 {
684 // This discards available rollback state before version v, and
685 // populates the commit_deltas to be passed to the global commit hook,
686 // if there is one, up to version v. The Map expects to be locked during
687 // compaction.
688 while (roll.commits->get_head() != roll.commits->get_tail())
689 {
690 auto r = roll.commits->get_head();
691
692 // Globally committed but not discardable.
693 if (r->version == v)
694 {
695 // We know that write set is not empty.
696 if (global_hook)
697 {
698 commit_deltas.emplace_back(r->version, std::move(r->writes));
699 }
700 return;
701 }
702
703 // Discardable, so move to commit_deltas.
704 if (global_hook && !r->writes.empty())
705 {
706 commit_deltas.emplace_back(r->version, std::move(r->writes));
707 }
708
709 // Stop if the next state may be rolled back or is the only state.
710 // This ensures there is always a state present.
711 if (r->next->version > v)
712 return;
713
714 auto c = roll.commits->pop();
715 roll.empty_commits.insert(c);
716 }
717
718 // There is only one roll. We may need to call the commit hook.
719 auto r = roll.commits->get_head();
720
721 if (global_hook && !r->writes.empty())
722 {
723 commit_deltas.emplace_back(r->version, std::move(r->writes));
724 }
725 }
726
727 void post_compact() override
728 {
729 if (global_hook)
730 {
731 for (auto& [version, writes] : commit_deltas)
732 {
734 "Executing global hook on table {} at version {}",
735 get_name(),
736 version);
737 global_hook(version, writes);
738 }
739 }
740
741 commit_deltas.clear();
742 }
743
744 void rollback(Version v) override
745 {
746 // This rolls the current state back to version v.
747 // The Map expects to be locked during rollback.
748 bool advance = false;
749
750 while (roll.commits->get_head() != roll.commits->get_tail())
751 {
752 auto r = roll.commits->get_tail();
753
754 // The initial empty state has v = 0, so will not be discarded if it
755 // is present.
756 if (r->version <= v)
757 break;
758
759 advance = true;
760 auto c = roll.commits->pop_tail();
761 roll.empty_commits.insert(c);
762 }
763
764 if (advance)
765 roll.rollback_counter++;
766 }
767
768 void clear() override
769 {
770 // This discards all entries in the roll and resets the rollback
771 // counter. The Map expects to be locked before clearing it.
772 roll.reset_commits();
773 roll.rollback_counter = 0;
774 }
775
776 void lock() override
777 {
778 sl.lock();
779 }
780
781 void unlock() override
782 {
783 sl.unlock();
784 }
785
786 void swap(AbstractMap* map_) override
787 {
788 Map* map = dynamic_cast<Map*>(map_);
789 if (map == nullptr)
790 throw std::logic_error(
791 "Attempted to swap maps with incompatible types");
792
793 std::swap(roll, map->roll);
794 }
795
797 Version version, bool track_deletes_on_missing_keys)
798 {
799 lock();
800
801 ChangeSetPtr changes = nullptr;
802
803 // Find the last entry committed at or before this version.
804 for (auto current = roll.commits->get_tail(); current != nullptr;
805 current = current->prev)
806 {
807 if (current->version <= version)
808 {
810 if (track_deletes_on_missing_keys)
811 {
812 writes = current->writes;
813 }
814 changes = std::make_unique<untyped::ChangeSet>(
815 roll.rollback_counter,
816 current->state,
817 roll.commits->get_head()->state,
818 writes,
819 current->version);
820 break;
821 }
822 }
823
824 // Returning nullptr is allowed, and indicates that we have no suitable
825 // version - the version requested is _earlier_ than anything in the
826 // roll
827
828 unlock();
829 return changes;
830 }
831
833 {
834 return roll;
835 }
836
838 {
839 if (hook && !writes.empty())
840 {
842 "Executing local hook on table {} at version {}",
843 get_name(),
844 version);
845 return hook(version, writes);
846 }
847 return nullptr;
848 }
849 };
850}
Definition kv_types.h:584
Definition kv_types.h:592
Definition kv_types.h:611
Definition kv_types.h:608
Definition kv_types.h:677
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_read_versions, bool track_deletes_on_missing_keys) override
Definition untyped_map.h:201
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:285
ConsensusHookPtr post_commit() override
Definition untyped_map.h:277
bool prepare(bool track_read_versions) override
Definition untyped_map.h:146
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(bool) override
Definition untyped_map.h:442
SnapshotHandleCommitter(Map &m, SnapshotChangeSet &change_set_)
Definition untyped_map.h:432
void commit(Version, bool, bool) override
Definition untyped_map.h:448
bool has_writes() override
Definition untyped_map.h:437
ConsensusHookPtr post_commit() override
Definition untyped_map.h:472
Definition untyped_map.h:292
Snapshot(const std::string &name_, SecurityDomain security_domain_, ccf::kv::Version version_, std::unique_ptr< StateSnapshot > &&map_snapshot_)
Definition untyped_map.h:301
void serialise(KvStoreSerialiser &s) override
Definition untyped_map.h:312
SecurityDomain get_security_domain() const override
Definition untyped_map.h:323
Definition untyped_map.h:69
Map(const Map &that)=delete
ChangeSetPtr deserialise_changes(KvStoreDeserialiser &d, Version version)
Definition untyped_map.h:489
void swap(AbstractMap *map_) override
Definition untyped_map.h:786
std::unique_ptr< AbstractCommitter > create_committer(AbstractChangeSet *changes) override
Definition untyped_map.h:542
void compact(Version v) override
Definition untyped_map.h:682
virtual SecurityDomain get_security_domain() override
Definition untyped_map.h:600
ConsensusHookPtr trigger_map_hook(Version version, const Write &writes)
Definition untyped_map.h:837
ChangeSetPtr deserialise_internal(KvStoreDeserialiser &d, Version version)
Definition untyped_map.h:494
bool operator==(const Map &that) const
Definition untyped_map.h:605
Map(AbstractStore *store_, const std::string &name_, SecurityDomain security_domain_)
Definition untyped_map.h:335
virtual AbstractMap * clone(AbstractStore *other) override
Definition untyped_map.h:349
void unlock() override
Definition untyped_map.h:781
ccf::kv::untyped::CommitHook CommitHook
Definition untyped_map.h:77
void clear() override
Definition untyped_map.h:768
void set_global_hook(const CommitHook &hook_)
Definition untyped_map.h:584
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:354
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:796
ccf::kv::untyped::MapHook MapHook
Definition untyped_map.h:78
Roll & get_roll()
Definition untyped_map.h:832
bool operator!=(const Map &that) const
Definition untyped_map.h:655
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:591
ChangeSetPtr deserialise_snapshot_changes(KvStoreDeserialiser &d)
Definition untyped_map.h:479
void lock() override
Definition untyped_map.h:776
void set_map_hook(const MapHook &hook_)
Definition untyped_map.h:570
AbstractStore * get_store() override
Definition untyped_map.h:565
void unset_map_hook()
Definition untyped_map.h:575
void post_compact() override
Definition untyped_map.h:727
void rollback(Version v) override
Definition untyped_map.h:744
std::unique_ptr< AbstractMap::Snapshot > snapshot(Version v) override
Definition untyped_map.h:661
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:378
#define LOG_DEBUG_FMT
Definition logger.h:380
#define LOG_FAIL_FMT
Definition logger.h:396
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:253
std::unique_ptr< ConsensusHook > ConsensusHookPtr
Definition hooks.h:21
uint64_t Version
Definition version.h:8
GenericDeserialiseWrapper< RawReader > KvStoreDeserialiser
Definition serialiser_declare.h:21
std::mutex Mutex
Definition locking.h:17
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