CCF
Loading...
Searching...
No Matches
tx.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/ccf_assert.h"
7#include "ccf/tx_id.h"
8
9#include <list>
10#include <map>
11#include <memory>
12#include <optional>
13#include <string>
14
15namespace ccf::kv
16{
17 class AbstractHandle;
18 class AbstractMap;
19 class AbstractStore;
20
21 namespace untyped
22 {
23 struct ChangeSet;
24 }
25
27 {
29 const std::shared_ptr<AbstractMap>& m,
30 std::unique_ptr<untyped::ChangeSet>&& cs);
32
33 // Shared ownership over source map
34 std::shared_ptr<AbstractMap> map;
35
36 // Owning pointer of ChangeSet over that map
37 std::unique_ptr<untyped::ChangeSet> changeset;
38 };
39
40 // When a collection of Maps are locked, the locks must be acquired in a
41 // stable order to avoid deadlocks. This ordered map will claim in name-order
42 using OrderedChanges = std::map<std::string, MapChanges>;
43
44 // Manages a collection of MapHandles. Derived implementations should call
45 // get_handle_by_name to retrieve handles over their desired maps.
46 class BaseTx
47 {
48 protected:
49 struct PrivateImpl;
50 std::unique_ptr<PrivateImpl> pimpl;
51
53
54 std::optional<ccf::crypto::Sha256Hash> root_at_read_version = std::nullopt;
55
57 const std::string& map_name,
58 std::unique_ptr<untyped::ChangeSet>&& change_set,
59 const std::shared_ptr<AbstractMap>& abstract_map);
60 void retain_handle(
61 const std::string& map_name, std::unique_ptr<AbstractHandle>&& handle);
62
64 const std::string& map_name, bool track_deletes_on_missing_keys);
65
66 std::list<AbstractHandle*> get_possible_handles(
67 const std::string& map_name);
68
69 void compacted_version_conflict(const std::string& map_name);
70
71 template <class THandle>
73 const std::string& map_name, bool track_deletes_on_missing_keys)
74 {
75 auto possible_handles = get_possible_handles(map_name);
76 for (auto handle : possible_handles)
77 {
78 auto typed_handle = dynamic_cast<THandle*>(handle);
79 if (typed_handle != nullptr)
80 {
81 return typed_handle;
82 }
83 }
84
85 auto it = all_changes.find(map_name);
86 if (it != all_changes.end())
87 {
88 auto& [abstract_map, change_set] = it->second;
89
90 auto typed_handle = new THandle(*change_set, map_name);
91 std::unique_ptr<AbstractHandle> abstract_handle(typed_handle);
92 retain_handle(map_name, std::move(abstract_handle));
93 return typed_handle;
94 }
95 else
96 {
97 auto [abstract_map, change_set] = get_map_and_change_set_by_name(
98 map_name, track_deletes_on_missing_keys);
99
100 if (change_set == nullptr)
101 {
103 }
104
105 auto typed_handle = new THandle(*change_set, map_name);
106 std::unique_ptr<AbstractHandle> abstract_handle(typed_handle);
107 retain_handle(map_name, std::move(abstract_handle));
108 retain_change_set(map_name, std::move(change_set), abstract_map);
109 return typed_handle;
110 }
111 }
112
113 public:
114 BaseTx(AbstractStore* _store);
115
116 // To avoid accidental copies and promote use of pass-by-reference, this is
117 // non-copyable
118 BaseTx(const BaseTx& that) = delete;
119
120 // To support reset/reconstruction, this is move-assignable.
121 BaseTx& operator=(BaseTx&& other) = default;
122
123 virtual ~BaseTx();
124
125 std::optional<ccf::crypto::Sha256Hash> get_root_at_read_version()
126 {
128 }
129 };
130
131 class TxDiff : public BaseTx
132 {
133 public:
134 using BaseTx::BaseTx;
135
136 template <class M>
137 typename M::Diff* diff(M& m)
138 {
139 return get_handle_by_name<typename M::Diff>(m.get_name(), true);
140 }
141
147 template <class M>
148 typename M::Diff* diff(const std::string& map_name)
149 {
150 return get_handle_by_name<typename M::Diff>(map_name, true);
151 }
152 };
153
160 class ReadOnlyTx : public BaseTx
161 {
162 public:
163 using BaseTx::BaseTx;
164
169 template <class M>
170 typename M::ReadOnlyHandle* ro(M& m)
171 {
172 // NB: Always creates a (writeable) MapHandle, which is cast to
173 // ReadOnlyHandle on return. This is so that other calls (before or
174 // after) can retrieve writeable handles over the same map.
175 return get_handle_by_name<typename M::Handle>(m.get_name(), false);
176 }
177
183 template <class M>
184 typename M::ReadOnlyHandle* ro(const std::string& map_name)
185 {
186 return get_handle_by_name<typename M::Handle>(map_name, false);
187 }
188 };
189
201 class Tx : public ReadOnlyTx
202 {
203 public:
204 using ReadOnlyTx::ReadOnlyTx;
205
212 template <class M>
213 typename M::Handle* rw(M& m)
214 {
215 return get_handle_by_name<typename M::Handle>(m.get_name(), false);
216 }
217
223 template <class M>
224 typename M::Handle* rw(const std::string& map_name)
225 {
226 return get_handle_by_name<typename M::Handle>(map_name, false);
227 }
228
233 template <class M>
234 typename M::WriteOnlyHandle* wo(M& m)
235 {
236 // As with ro, this returns a full-featured Handle
237 // which is cast to only show its writeable facet.
238 return get_handle_by_name<typename M::Handle>(m.get_name(), false);
239 }
240
246 template <class M>
247 typename M::WriteOnlyHandle* wo(const std::string& map_name)
248 {
249 return get_handle_by_name<typename M::Handle>(map_name, false);
250 }
251 };
252}
Definition kv_types.h:677
Definition tx.h:47
void compacted_version_conflict(const std::string &map_name)
Definition tx.cpp:114
virtual ~BaseTx()
void retain_change_set(const std::string &map_name, std::unique_ptr< untyped::ChangeSet > &&change_set, const std::shared_ptr< AbstractMap > &abstract_map)
Definition tx.cpp:25
BaseTx(AbstractStore *_store)
Definition tx.cpp:124
THandle * get_handle_by_name(const std::string &map_name, bool track_deletes_on_missing_keys)
Definition tx.h:72
void retain_handle(const std::string &map_name, std::unique_ptr< AbstractHandle > &&handle)
Definition tx.cpp:43
MapChanges get_map_and_change_set_by_name(const std::string &map_name, bool track_deletes_on_missing_keys)
Definition tx.cpp:49
OrderedChanges all_changes
Definition tx.h:52
std::optional< ccf::crypto::Sha256Hash > root_at_read_version
Definition tx.h:54
BaseTx & operator=(BaseTx &&other)=default
std::unique_ptr< PrivateImpl > pimpl
Definition tx.h:50
BaseTx(const BaseTx &that)=delete
std::optional< ccf::crypto::Sha256Hash > get_root_at_read_version()
Definition tx.h:125
std::list< AbstractHandle * > get_possible_handles(const std::string &map_name)
Definition tx.cpp:99
Definition tx.h:161
M::ReadOnlyHandle * ro(M &m)
Definition tx.h:170
M::ReadOnlyHandle * ro(const std::string &map_name)
Definition tx.h:184
Definition tx.h:132
M::Diff * diff(const std::string &map_name)
Definition tx.h:148
M::Diff * diff(M &m)
Definition tx.h:137
Definition tx.h:202
M::Handle * rw(M &m)
Definition tx.h:213
M::WriteOnlyHandle * wo(const std::string &map_name)
Definition tx.h:247
M::WriteOnlyHandle * wo(M &m)
Definition tx.h:234
M::Handle * rw(const std::string &map_name)
Definition tx.h:224
Definition app_interface.h:20
std::map< std::string, MapChanges > OrderedChanges
Definition tx.h:42
Definition tx_pimpl.h:10
Definition tx.h:27
std::unique_ptr< untyped::ChangeSet > changeset
Definition tx.h:37
std::shared_ptr< AbstractMap > map
Definition tx.h:34