Platform.Data.Doublets C++
Loading...
Searching...
No Matches
UInt64LinksTransactionsLayer.h
Go to the documentation of this file.
2{
3 class UInt64LinksTransactionsLayer : public LinksDisposableDecoratorBase<std::uint64_t>
4 {
5 struct Transition : public IEquatable<Transition>
6 {
7 public:
8 inline static const std::uint64_t Size = Structure<Transition>.Size;
9
10 public:
11 std::uint64_t TransactionId = 0;
12
13 public:
15
16 public:
18
19 public:
20 Timestamp Timestamp = 0;
21
22 public:
23 Transition(UniqueTimestampFactory uniqueTimestampFactory, std::uint64_t transactionId,
25 {
26 TransactionId = transactionId;
27 Before = before;
28 After = after;
29 Timestamp = uniqueTimestampFactory.Create();
30 }
31
32 public:
33 Transition(UniqueTimestampFactory uniqueTimestampFactory, std::uint64_t transactionId,
35 : this(uniqueTimestampFactory, transactionId, before, 0)
36 {
37 }
38
39 public:
40 Transition(UniqueTimestampFactory uniqueTimestampFactory, std::uint64_t transactionId)
41 : this(uniqueTimestampFactory, transactionId, 0, 0)
42 {
43 }
44
45 public:
46 std::string ToString()
47 {
48 return std::string("")
49 .append(Platform::Converters::To<std::string>(Timestamp))
50 .append(1, ' ')
51 .append(Platform::Converters::To<std::string>(TransactionId))
52 .append(": ")
53 .append(Platform::Converters::To<std::string>(Before))
54 .append(" => ")
55 .append(Platform::Converters::To<std::string>(After))
56 .append("");
57 }
58
59 public:
60 std::int32_t GetHashCode()
61 {
62 return Platform::Hashing::Hash(TransactionId, Before, After, Timestamp);
63 }
64
65 public:
66 bool operator==(const Transition& other) const
67 {
68 return TransactionId == other.TransactionId && Before == other.Before && After == other.After &&
69 Timestamp == other.Timestamp;
70 }
71 }
72
73 class Transaction : public DisposableBase
74 {
75 private:
76 Queue<Transition> _transitions;
77
78 private:
80
81 public:
82 inline bool IsCommitted;
83
84 public:
85 inline bool IsReverted;
86
87 public:
89 {
90 _layer = layer;
91 if (_layer._currentTransactionId != 0)
92 {
93 throw throw std::logic_error("Not supported exception.");
94 }
95 IsCommitted = false;
96 IsReverted = false;
97 _transitions = Queue<Transition>();
98 this->SetCurrentTransaction(layer, this);
99 }
100
101 public:
102 void Commit()
103 {
105 while (_transitions.Count() > 0)
106 {
107 auto transition = _transitions.Dequeue();
108 _layer._transitions.Enqueue(transition);
109 }
110 _layer._lastCommitedTransactionId = _layer._currentTransactionId;
111 IsCommitted = true;
112 }
113
114 private:
115 void Revert()
116 {
118 auto transitionsToRevert = Transition[_transitions.Count()];
119 _transitions.CopyTo(transitionsToRevert, 0);
120 for (auto i = transitionsToRevert.Length - 1; i >= 0; i--)
121 {
122 _layer.RevertTransition(transitionsToRevert[i]);
123 }
124 IsReverted = true;
125 }
126
127 public:
129 {
130 layer._currentTransactionId = layer._lastCommitedTransactionId + 1;
131 layer._currentTransactionTransitions = transaction._transitions;
132 layer._currentTransaction = transaction;
133 }
134
135 public:
137 {
138 if (transaction.IsReverted)
139 {
140 throw std::runtime_error("Transation is reverted.");
141 }
142 if (transaction.IsCommitted)
143 {
144 throw std::runtime_error("Transation is commited.");
145 }
146 }
147
148 public:
149 void Dispose(bool manual, bool wasDisposed)
150 {
151 if (!wasDisposed && _layer != nullptr && !_layer.Disposable.IsDisposed)
152 {
153 if (!IsCommitted && !IsReverted)
154 {
155 this->Revert();
156 }
157 _layer.ResetCurrentTransation();
158 }
159 }
160 }
161
162 public : inline static const TimeSpan DefaultPushDelay = TimeSpan.FromSeconds(0.1);
163
164 private:
165 std::string _logAddress = 0;
166
167 private:
168 FileStream _log = 0;
169
170 private:
171 Queue<Transition> _transitions;
172
173 private:
174 UniqueTimestampFactory _uniqueTimestampFactory = 0;
175
176 private:
177 Task _transitionsPusher = 0;
178
179 private:
180 Transition _lastCommitedTransition = 0;
181
182 private:
183 std::uint64_t _currentTransactionId = 0;
184
185 private:
186 Queue<Transition> _currentTransactionTransitions;
187
188 private:
189 Transaction _currentTransaction = 0;
190
191 private:
192 std::uint64_t _lastCommitedTransactionId = 0;
193
194 public:
195 UInt64LinksTransactionsLayer(ILinks<std::uint64_t>& storage, std::string logAddress) : base(storage)
196 {
197 if (std::string.IsNullOrWhiteSpace(logAddress))
198 {
199 throw std::invalid_argument("logAddress");
200 }
201 auto lastCommitedTransition = FileHelpers.ReadFirstOrDefault<Transition>(logAddress);
202 auto lastWrittenTransition = FileHelpers.ReadLastOrDefault<Transition>(logAddress);
203 if (!lastCommitedTransition.Equals(lastWrittenTransition))
204 {
205 this->Dispose();
206 throw throw std::logic_error("Not supported exception.");
207 }
208 if (lastCommitedTransition == 0)
209 {
210 FileHelpers.WriteFirst(logAddress, lastCommitedTransition);
211 }
212 _lastCommitedTransition = lastCommitedTransition;
213 auto allTransitions = FileHelpers.ReadAll<Transition>(logAddress);
214 _lastCommitedTransactionId = allTransitions.Length > 0 ? allTransitions.Max(x = > x.TransactionId) : 0;
215 _uniqueTimestampFactory = this->UniqueTimestampFactory();
216 _logAddress = logAddress;
217 _log = FileHelpers.Append(logAddress);
218 _transitions = Queue<Transition>();
219 _transitionsPusher = this->Task(TransitionsPusher);
220 _transitionsPusher.Start();
221 }
222
223 public:
224 IList<std::uint64_t> GetLinkValue(std::uint64_t link)
225 {
226 return _links.GetLink(link);
227 }
228
229 public:
230 std::uint64_t Create(IList<std::uint64_t>& restriction)
231 {
232 auto createdLinkIndex = _links.Create();
233 auto createdLink = Link<std::uint64_t>(_links.GetLink(createdLinkIndex));
234 this->CommitTransition(this->Transition(_uniqueTimestampFactory, _currentTransactionId, 0, createdLink));
235 return createdLinkIndex;
236 }
237
238 public:
239 std::uint64_t Update(IList<std::uint64_t>& restriction, IList<std::uint64_t>& substitution)
240 {
241 auto linkIndex = restriction[_constants.IndexPart];
242 auto beforeLink = Link<std::uint64_t>(_links.GetLink(linkIndex));
243 linkIndex = _links.Update(restriction, substitution);
244 auto afterLink = Link<std::uint64_t>(_links.GetLink(linkIndex));
245 this->CommitTransition(
246 this->Transition(_uniqueTimestampFactory, _currentTransactionId, beforeLink, afterLink));
247 return linkIndex;
248 }
249
250 public:
251 void Delete(IList<std::uint64_t>& restriction)
252 {
253 auto link = restriction[_constants.IndexPart];
254 auto deletedLink = Link<std::uint64_t>(_links.GetLink(link));
255 _links.Delete(link);
256 this->CommitTransition(this->Transition(_uniqueTimestampFactory, _currentTransactionId, deletedLink, 0));
257 }
258
259 private:
260 Queue<Transition> GetCurrentTransitions()
261 {
262 return _currentTransactionTransitions ? ? _transitions;
263 }
264
265 private:
266 void CommitTransition(Transition transition)
267 {
268 if (_currentTransaction != nullptr)
269 {
270 Transaction.EnsureTransactionAllowsWriteOperations(_currentTransaction);
271 }
272 auto transitions = this->GetCurrentTransitions();
273 transitions.Enqueue(transition);
274 }
275
276 private:
277 void RevertTransition(Transition transition)
278 {
279 if (transition.After.IsNull())
280 {
281 _links.Create();
282 }
283 else if (transition.Before.IsNull())
284 {
285 _links.Delete(transition.After.Index);
286 }
287 else
288 {
289 _links.Update(new[]{transition.After.Index, transition.Before.Source, transition.Before.Target});
290 }
291 }
292
293 private:
294 void ResetCurrentTransation()
295 {
296 _currentTransactionId = 0;
297 _currentTransactionTransitions = {};
298 _currentTransaction = {};
299 }
300
301 private:
302 void PushTransitions()
303 {
304 if (_log == nullptr || _transitions == nullptr)
305 {
306 return;
307 }
308 for (auto i = 0; i < _transitions.Count(); i++)
309 {
310 auto transition = _transitions.Dequeue();
311
312 _log.Write(transition);
313 _lastCommitedTransition = transition;
314 }
315 }
316
317 private:
318 void TransitionsPusher()
319 {
320 while (!Disposable.IsDisposed && _transitionsPusher != nullptr)
321 {
322 Thread.Sleep(DefaultPushDelay);
323 this->PushTransitions();
324 }
325 }
326
327 public:
329 {
330 return this->Transaction(this);
331 }
332
333 private:
334 void DisposeTransitions()
335 {
336 try
337 {
338 auto pusher = _transitionsPusher;
339 if (pusher != nullptr)
340 {
341 _transitionsPusher = {};
342 pusher.Wait();
343 }
344 if (_transitions != nullptr)
345 {
346 this->PushTransitions();
347 }
348 _log.DisposeIfPossible();
349 FileHelpers.WriteFirst(_logAddress, _lastCommitedTransition);
350 }
351 catch (const std::exception& ex)
352 {
353 Platform::Exceptions::ExceptionExtensions::Ignore(ex);
354 }
355 }
356
357 public:
358 void Dispose(bool manual, bool wasDisposed)
359 {
360 if (!wasDisposed)
361 {
362 this->DisposeTransitions();
363 }
364 base.Dispose(manual, wasDisposed);
365 }
366 };
367} // namespace Platform::Data::Doublets
constexpr auto x
Definition DoubletComparer.h:25
Definition UInt64LinksTransactionsLayer.h:4
Transaction(UInt64LinksTransactionsLayer layer)
Definition UInt64LinksTransactionsLayer.h:88
static void SetCurrentTransaction(UInt64LinksTransactionsLayer layer, Transaction transaction)
Definition UInt64LinksTransactionsLayer.h:128
void Delete(IList< std::uint64_t > &restriction)
Definition UInt64LinksTransactionsLayer.h:251
UInt64LinksTransactionsLayer(ILinks< std::uint64_t > &storage, std::string logAddress)
Definition UInt64LinksTransactionsLayer.h:195
IList< std::uint64_t > GetLinkValue(std::uint64_t link)
Definition UInt64LinksTransactionsLayer.h:224
Transaction BeginTransaction()
Definition UInt64LinksTransactionsLayer.h:328
void Dispose(bool manual, bool wasDisposed)
Definition UInt64LinksTransactionsLayer.h:149
bool IsReverted
Definition UInt64LinksTransactionsLayer.h:85
static const TimeSpan DefaultPushDelay
Definition UInt64LinksTransactionsLayer.h:162
static void EnsureTransactionAllowsWriteOperations(Transaction transaction)
Definition UInt64LinksTransactionsLayer.h:136
std::uint64_t Create(IList< std::uint64_t > &restriction)
Definition UInt64LinksTransactionsLayer.h:230
std::uint64_t Update(IList< std::uint64_t > &restriction, IList< std::uint64_t > &substitution)
Definition UInt64LinksTransactionsLayer.h:239
void Commit()
Definition UInt64LinksTransactionsLayer.h:102
bool IsCommitted
Definition UInt64LinksTransactionsLayer.h:82
Definition TargetMatcher.h:2