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