private static void UpdateInvalidReplays(string id, ArtifactOperation failingOperation, IDictionary <string, ArtifactOperation> replayList, IDictionary <string, List <ArtifactOperation> > failedReplays) { if (!failedReplays.TryGetValue(id, out List <ArtifactOperation> lst)) { var prev = replayList[id]; replayList.Remove(id); failedReplays[id] = lst = new List <ArtifactOperation> { prev }; } lst.Add(failingOperation); }
/// <summary> /// Loads the artifact operation from the underlying stream. /// </summary> /// <returns>The loaded artifact instance.</returns> public ArtifactOperation Load() { var major = _serializer.Deserialize <int>(_stream); var minor = _serializer.Deserialize <int>(_stream); var build = _serializer.Deserialize <int>(_stream); var revision = _serializer.Deserialize <int>(_stream); var version = new Version(major, minor, build, revision); if (version < TransactionStateVersion.v1) { throw new InvalidDataException("Version not supported: " + version); } var kind = _serializer.Deserialize <ArtifactOperationKind>(_stream); switch (kind) { case ArtifactOperationKind.Create: { var expr = _serializer.Deserialize <Expression>(_stream); var state = _serializer.Deserialize <object>(_stream); return(ArtifactOperation.Create(expr, state)); } case ArtifactOperationKind.DeleteCreate: { var expr = _serializer.Deserialize <Expression>(_stream); var state = _serializer.Deserialize <object>(_stream); return(ArtifactOperation.DeleteCreate(expr, state)); } case ArtifactOperationKind.Delete: return(ArtifactOperation.Delete()); default: throw new NotSupportedException(); } }
/// <summary> /// Saves the artifact operation to the underlying stream. /// </summary> /// <param name="operation">The artifact instance to save.</param> public void Save(ArtifactOperation operation) { var version = TransactionStateVersion.v1; _serializer.Serialize(version.Major, _stream); _serializer.Serialize(version.Minor, _stream); _serializer.Serialize(version.Build, _stream); _serializer.Serialize(version.Revision, _stream); var kind = operation.OperationKind; _serializer.Serialize(kind, _stream); switch (kind) { case ArtifactOperationKind.Create: { _serializer.Serialize(operation.Expression, _stream); _serializer.Serialize(operation.State, _stream); break; } case ArtifactOperationKind.DeleteCreate: { _serializer.Serialize(operation.Expression, _stream); _serializer.Serialize(operation.State, _stream); break; } case ArtifactOperationKind.Delete: break; default: throw new NotSupportedException(); } }
private Dictionary <string, ArtifactOperation> Coalesce( IKeyValueStore keyValueStore, IList <ITransactionLog> logs, Func <ITransactionLog, IKeyValueTable <string, ArtifactOperation> > tableSelector) { var result = new Dictionary <string, ArtifactOperation>(); foreach (var log in logs) { var table = tableSelector(log); using var tx = keyValueStore.CreateTransaction(); var txTable = table.Enter(tx); foreach (var item in txTable) { if (result.TryGetValue(item.Key, out ArtifactOperation op)) { Tracing.Transaction_Log_Coalesce(null, _parent._engineId, item.Key, op.OperationKind.ToString(), item.Value.OperationKind.ToString()); // // SECOND // // Create Delete DeleteCreate // +--------------+--------------+--------------+ // F Create | Invalid | No-op | Create | // I +--------------+--------------+--------------+ // R Delete | DeleteCreate | Invalid | Invalid | // S +--------------+--------------+--------------+ // T DeleteCreate | Invalid | Delete | DeleteCreate | // +--------------+--------------+--------------+ // switch (op.OperationKind) { case ArtifactOperationKind.Create: switch (item.Value.OperationKind) { case ArtifactOperationKind.Create: UpdateInvalidReplays(item.Key, item.Value, result, _invalidReplaySequence); break; case ArtifactOperationKind.Delete: result.Remove(item.Key); break; case ArtifactOperationKind.DeleteCreate: result[item.Key] = ArtifactOperation.Create(item.Value.Expression, item.Value.State); break; } break; case ArtifactOperationKind.Delete: switch (item.Value.OperationKind) { case ArtifactOperationKind.Create: result[item.Key] = ArtifactOperation.DeleteCreate(item.Value.Expression, item.Value.State); break; case ArtifactOperationKind.Delete: UpdateInvalidReplays(item.Key, item.Value, result, _invalidReplaySequence); break; case ArtifactOperationKind.DeleteCreate: UpdateInvalidReplays(item.Key, item.Value, result, _invalidReplaySequence); break; } break; case ArtifactOperationKind.DeleteCreate: switch (item.Value.OperationKind) { case ArtifactOperationKind.Create: UpdateInvalidReplays(item.Key, item.Value, result, _invalidReplaySequence); break; case ArtifactOperationKind.Delete: result[item.Key] = item.Value; break; case ArtifactOperationKind.DeleteCreate: result[item.Key] = item.Value; break; } break; } } else { result.Add(item.Key, item.Value); } } } return(result); }