コード例 #1
0
        /// <summary>
        /// Creates a new transaction log manager.
        /// </summary>
        /// <param name="engineId">The engine this transaction log manager is used for. Only used for logging purposes.</param>
        /// <param name="keyValueStore">The key/value store to write transaction logs to.</param>
        /// <param name="policy">The serialization policy to use when serializing objects.</param>
        public TransactionLogManager(Uri engineId, IKeyValueStore keyValueStore, ISerializationPolicy policy)
        {
            _engineId      = engineId;
            _keyValueStore = keyValueStore;
            _policy        = policy;

            _lock          = new AsyncLock();
            _versionedLogs = new Queue <ITransactionLog>();
            _metadataTable = new SerializingKeyValueTable <string>(
                _keyValueStore.GetTable(MetadataTableName),
                (str, s) =>
            {
                using var writer = new BinaryWriter(s);

                writer.Write(str);
            },
                s =>
            {
                using var reader = new BinaryReader(s);

                return(reader.ReadString());
            }
                );

            using (var t = _keyValueStore.CreateTransaction())
            {
                var tx = _metadataTable.Enter(t);
                if (!tx.Contains(ActiveCountKey))
                {
                    Invariant.Assert(!tx.Contains(LatestKey) && !tx.Contains(HeldCountKey), "Transaction log versioning keys are only partially populated.");

                    _activeCount = _heldCount = _latest = 0;
                }
                else
                {
                    Invariant.Assert(tx.Contains(LatestKey) && tx.Contains(HeldCountKey), "Transaction log versioning keys are only partially populated.");

                    _activeCount = long.Parse(tx[ActiveCountKey], CultureInfo.InvariantCulture);
                    _heldCount   = long.Parse(tx[HeldCountKey], CultureInfo.InvariantCulture);
                    _latest      = long.Parse(tx[LatestKey], CultureInfo.InvariantCulture);
                }
            }

            Tracing.Transaction_Log_Initialization(null, _engineId, _latest, _activeCount, _heldCount);

            for (var i = _latest - _heldCount + 1; i <= _latest; i++)
            {
                _versionedLogs.Enqueue(new TransactionLog(_keyValueStore, _policy, i));
            }
        }
コード例 #2
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);
            }