5 struct Transition :
public IEquatable<Transition>
8 inline static const std::uint64_t Size = Structure<Transition>.Size;
11 std::uint64_t TransactionId = 0;
20 Timestamp Timestamp = 0;
23 Transition(UniqueTimestampFactory uniqueTimestampFactory, std::uint64_t transactionId,
26 TransactionId = transactionId;
29 Timestamp = uniqueTimestampFactory.Create();
33 Transition(UniqueTimestampFactory uniqueTimestampFactory, std::uint64_t transactionId,
35 :
this(uniqueTimestampFactory, transactionId, before, 0)
40 Transition(UniqueTimestampFactory uniqueTimestampFactory, std::uint64_t transactionId)
41 :
this(uniqueTimestampFactory, transactionId, 0, 0)
46 std::string ToString()
48 return std::string(
"")
49 .append(Platform::Converters::To<std::string>(Timestamp))
51 .append(Platform::Converters::To<std::string>(TransactionId))
53 .append(Platform::Converters::To<std::string>(
Before))
55 .append(Platform::Converters::To<std::string>(
After))
60 std::int32_t GetHashCode()
62 return Platform::Hashing::Hash(TransactionId,
Before,
After, Timestamp);
68 return TransactionId == other.TransactionId &&
Before == other.Before &&
After == other.After &&
69 Timestamp == other.Timestamp;
76 Queue<Transition> _transitions;
91 if (_layer._currentTransactionId != 0)
93 throw throw std::logic_error(
"Not supported exception.");
97 _transitions = Queue<Transition>();
105 while (_transitions.Count() > 0)
107 auto transition = _transitions.Dequeue();
108 _layer._transitions.Enqueue(transition);
110 _layer._lastCommitedTransactionId = _layer._currentTransactionId;
118 auto transitionsToRevert =
Transition[_transitions.Count()];
119 _transitions.CopyTo(transitionsToRevert, 0);
120 for (
auto i = transitionsToRevert.Length - 1; i >= 0; i--)
122 _layer.RevertTransition(transitionsToRevert[i]);
130 layer._currentTransactionId = layer._lastCommitedTransactionId + 1;
131 layer._currentTransactionTransitions = transaction._transitions;
132 layer._currentTransaction = transaction;
138 if (transaction.IsReverted)
140 throw std::runtime_error(
"Transation is reverted.");
142 if (transaction.IsCommitted)
144 throw std::runtime_error(
"Transation is commited.");
151 if (!wasDisposed && _layer !=
nullptr && !_layer.Disposable.IsDisposed)
157 _layer.ResetCurrentTransation();
165 std::string _logAddress = 0;
171 Queue<Transition> _transitions;
174 UniqueTimestampFactory _uniqueTimestampFactory = 0;
177 Task _transitionsPusher = 0;
183 std::uint64_t _currentTransactionId = 0;
186 Queue<Transition> _currentTransactionTransitions;
192 std::uint64_t _lastCommitedTransactionId = 0;
197 if (std::string.IsNullOrWhiteSpace(logAddress))
199 throw std::invalid_argument(
"logAddress");
201 auto lastCommitedTransition = FileHelpers.ReadFirstOrDefault<
Transition>(logAddress);
202 auto lastWrittenTransition = FileHelpers.ReadLastOrDefault<
Transition>(logAddress);
203 if (!lastCommitedTransition.Equals(lastWrittenTransition))
206 throw throw std::logic_error(
"Not supported exception.");
208 if (lastCommitedTransition == 0)
210 FileHelpers.WriteFirst(logAddress, lastCommitedTransition);
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();
226 return _links.GetLink(link);
230 std::uint64_t
Create(IList<std::uint64_t>& restriction)
232 auto createdLinkIndex = _links.Create();
234 this->CommitTransition(this->
Transition(_uniqueTimestampFactory, _currentTransactionId, 0, createdLink));
235 return createdLinkIndex;
239 std::uint64_t
Update(IList<std::uint64_t>& restriction, IList<std::uint64_t>& substitution)
241 auto linkIndex = restriction[_constants.IndexPart];
243 linkIndex = _links.Update(restriction, substitution);
245 this->CommitTransition(
246 this->
Transition(_uniqueTimestampFactory, _currentTransactionId, beforeLink, afterLink));
251 void Delete(IList<std::uint64_t>& restriction)
253 auto link = restriction[_constants.IndexPart];
256 this->CommitTransition(this->
Transition(_uniqueTimestampFactory, _currentTransactionId, deletedLink, 0));
260 Queue<Transition> GetCurrentTransitions()
262 return _currentTransactionTransitions ? ? _transitions;
266 void CommitTransition(Transition transition)
268 if (_currentTransaction !=
nullptr)
270 Transaction.EnsureTransactionAllowsWriteOperations(_currentTransaction);
272 auto transitions = this->GetCurrentTransitions();
273 transitions.Enqueue(transition);
277 void RevertTransition(Transition transition)
279 if (transition.After.IsNull())
283 else if (transition.Before.IsNull())
285 _links.Delete(transition.After.Index);
289 _links.Update(
new[]{transition.After.Index, transition.Before.Source, transition.Before.Target});
294 void ResetCurrentTransation()
296 _currentTransactionId = 0;
297 _currentTransactionTransitions = {};
298 _currentTransaction = {};
302 void PushTransitions()
304 if (_log ==
nullptr || _transitions ==
nullptr)
308 for (
auto i = 0; i < _transitions.Count(); i++)
310 auto transition = _transitions.Dequeue();
312 _log.Write(transition);
313 _lastCommitedTransition = transition;
318 void TransitionsPusher()
320 while (!Disposable.IsDisposed && _transitionsPusher !=
nullptr)
323 this->PushTransitions();
334 void DisposeTransitions()
338 auto pusher = _transitionsPusher;
339 if (pusher !=
nullptr)
341 _transitionsPusher = {};
344 if (_transitions !=
nullptr)
346 this->PushTransitions();
348 _log.DisposeIfPossible();
349 FileHelpers.WriteFirst(_logAddress, _lastCommitedTransition);
351 catch (
const std::exception& ex)
353 Platform::Exceptions::ExceptionExtensions::Ignore(ex);
362 this->DisposeTransitions();
364 base.Dispose(manual, wasDisposed);