Пример #1
0
            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);
            }
Пример #2
0
        /// <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();
            }
        }
Пример #3
0
        /// <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();
            }
        }
Пример #4
0
            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);
            }