/// <inheritdoc />
        public void GlobalBeforeEnteringState <Key, Value>(
            SystemState next,
            FasterKV <Key, Value> faster)
            where Key : new()
            where Value : new()
        {
            switch (next.phase)
            {
            case Phase.PREP_INDEX_CHECKPOINT:
                Debug.Assert(faster._indexCheckpoint.IsDefault() &&
                             faster._hybridLogCheckpoint.IsDefault());
                var fullCheckpointToken = Guid.NewGuid();
                faster._indexCheckpointToken     = fullCheckpointToken;
                faster._hybridLogCheckpointToken = fullCheckpointToken;
                faster.InitializeIndexCheckpoint(faster._indexCheckpointToken);
                faster.InitializeHybridLogCheckpoint(faster._hybridLogCheckpointToken, next.version);
                break;

            case Phase.WAIT_FLUSH:
                faster._indexCheckpoint.info.num_buckets = faster.overflowBucketsAllocator.GetMaxValidAddress();
                faster.ObtainCurrentTailAddress(ref faster._indexCheckpoint.info.finalLogicalAddress);
                break;

            case Phase.PERSISTENCE_CALLBACK:
                faster.WriteIndexMetaInfo();
                faster._indexCheckpoint.Reset();
                break;
            }
        }
        /// <inheritdoc />
        public virtual void GlobalBeforeEnteringState <Key, Value, Input, Output, Context, Functions>(SystemState next,
                                                                                                      FasterKV <Key, Value, Input, Output, Context, Functions> faster)
            where Key : new()
            where Value : new()
            where Functions : IFunctions <Key, Value, Input, Output, Context>
        {
            switch (next.phase)
            {
            case Phase.PREPARE:
                if (faster._hybridLogCheckpointToken == default)
                {
                    faster._hybridLogCheckpointToken = Guid.NewGuid();
                    faster.InitializeHybridLogCheckpoint(faster._hybridLogCheckpointToken, next.version);
                }

                faster.ObtainCurrentTailAddress(ref faster._hybridLogCheckpoint.info.startLogicalAddress);
                break;

            case Phase.WAIT_FLUSH:
                faster._hybridLogCheckpoint.info.headAddress  = faster.hlog.HeadAddress;
                faster._hybridLogCheckpoint.info.beginAddress = faster.hlog.BeginAddress;
                break;

            case Phase.PERSISTENCE_CALLBACK:
                // Collect object log offsets only after flushes
                // are completed
                var seg = faster.hlog.GetSegmentOffsets();
                if (seg != null)
                {
                    faster._hybridLogCheckpoint.info.objectLogSegmentOffsets = new long[seg.Length];
                    Array.Copy(seg, faster._hybridLogCheckpoint.info.objectLogSegmentOffsets, seg.Length);
                }

                if (faster._activeSessions != null)
                {
                    // write dormant sessions to checkpoint
                    foreach (var kvp in faster._activeSessions)
                    {
                        faster.AtomicSwitch(kvp.Value.ctx, kvp.Value.ctx.prevCtx, next.version - 1);
                    }
                }

                faster.WriteHybridLogMetaInfo();
                break;

            case Phase.REST:
                faster._hybridLogCheckpointToken = default;
                faster._hybridLogCheckpoint.Reset();
                var nextTcs = new TaskCompletionSource <LinkedCheckpointInfo>(TaskCreationOptions.RunContinuationsAsynchronously);
                faster.checkpointTcs.SetResult(new LinkedCheckpointInfo {
                    NextTask = nextTcs.Task
                });
                faster.checkpointTcs = nextTcs;
                break;
            }
        }
Exemple #3
0
        /// <inheritdoc />
        public virtual void GlobalBeforeEnteringState <Key, Value>(SystemState next,
                                                                   FasterKV <Key, Value> faster)
            where Key : new()
            where Value : new()
        {
            switch (next.phase)
            {
            case Phase.PREPARE:
                if (faster._hybridLogCheckpoint.IsDefault())
                {
                    faster._hybridLogCheckpointToken = Guid.NewGuid();
                    faster.InitializeHybridLogCheckpoint(faster._hybridLogCheckpointToken, next.version);
                }

                faster.ObtainCurrentTailAddress(ref faster._hybridLogCheckpoint.info.startLogicalAddress);
                break;

            case Phase.WAIT_FLUSH:
                faster._hybridLogCheckpoint.info.headAddress  = faster.hlog.HeadAddress;
                faster._hybridLogCheckpoint.info.beginAddress = faster.hlog.BeginAddress;
                break;

            case Phase.PERSISTENCE_CALLBACK:
                // Collect object log offsets only after flushes
                // are completed
                var seg = faster.hlog.GetSegmentOffsets();
                if (seg != null)
                {
                    faster._hybridLogCheckpoint.info.objectLogSegmentOffsets = new long[seg.Length];
                    Array.Copy(seg, faster._hybridLogCheckpoint.info.objectLogSegmentOffsets, seg.Length);
                }

                // Temporarily block new sessions from starting, which may add an entry to the table and resize the
                // dictionary. There should be minimal contention here.
                lock (faster._activeSessions)
                    // write dormant sessions to checkpoint
                    foreach (var kvp in faster._activeSessions)
                    {
                        kvp.Value.AtomicSwitch(next.version - 1);
                    }

                faster.WriteHybridLogMetaInfo();
                break;

            case Phase.REST:
                faster._hybridLogCheckpoint.Reset();
                var nextTcs = new TaskCompletionSource <LinkedCheckpointInfo>(TaskCreationOptions.RunContinuationsAsynchronously);
                faster.checkpointTcs.SetResult(new LinkedCheckpointInfo {
                    NextTask = nextTcs.Task
                });
                faster.checkpointTcs = nextTcs;
                break;
            }
        }
        /// <inheritdoc />
        public void GlobalBeforeEnteringState <Key, Value, Input, Output, Context, Functions>(
            SystemState next,
            FasterKV <Key, Value, Input, Output, Context, Functions> faster)
            where Key : new()
            where Value : new()
            where Functions : IFunctions <Key, Value, Input, Output, Context>
        {
            switch (next.phase)
            {
            case Phase.PREP_INDEX_CHECKPOINT:
                Debug.Assert(faster._indexCheckpointToken == default &&
                             faster._hybridLogCheckpointToken == default);
                var fullCheckpointToken = Guid.NewGuid();
                faster._indexCheckpointToken     = fullCheckpointToken;
                faster._hybridLogCheckpointToken = fullCheckpointToken;
                faster.InitializeIndexCheckpoint(faster._indexCheckpointToken);
                faster.InitializeHybridLogCheckpoint(faster._hybridLogCheckpointToken, next.version);
                break;

            case Phase.PREPARE:
                if (faster.UseReadCache && faster.ReadCache.BeginAddress != faster.ReadCache.TailAddress)
                {
                    throw new FasterException("Index checkpoint with read cache is not supported");
                }
                faster.TakeIndexFuzzyCheckpoint();
                break;

            case Phase.WAIT_FLUSH:
                faster._indexCheckpoint.info.num_buckets = faster.overflowBucketsAllocator.GetMaxValidAddress();
                faster.ObtainCurrentTailAddress(ref faster._indexCheckpoint.info.finalLogicalAddress);
                break;

            case Phase.PERSISTENCE_CALLBACK:
                faster.WriteIndexMetaInfo();
                faster._indexCheckpointToken = default;
                break;
            }
        }
        /// <inheritdoc />
        public virtual void GlobalBeforeEnteringState <Key, Value>(SystemState next,
                                                                   FasterKV <Key, Value> faster)
        {
            switch (next.Phase)
            {
            case Phase.PREPARE:
                lastVersion = faster.systemState.Version;
                if (faster._hybridLogCheckpoint.IsDefault())
                {
                    faster._hybridLogCheckpointToken = Guid.NewGuid();
                    faster.InitializeHybridLogCheckpoint(faster._hybridLogCheckpointToken, next.Version);
                }
                faster._hybridLogCheckpoint.info.version = next.Version;
                faster.ObtainCurrentTailAddress(ref faster._hybridLogCheckpoint.info.startLogicalAddress);
                break;

            case Phase.WAIT_FLUSH:
                faster._hybridLogCheckpoint.info.headAddress  = faster.hlog.HeadAddress;
                faster._hybridLogCheckpoint.info.beginAddress = faster.hlog.BeginAddress;
                faster._hybridLogCheckpoint.info.nextVersion  = next.Version;
                break;

            case Phase.PERSISTENCE_CALLBACK:
                CollectMetadata(next, faster);
                faster.WriteHybridLogMetaInfo();
                faster.lastVersion = lastVersion;
                break;

            case Phase.REST:
                faster._hybridLogCheckpoint.Dispose();
                var nextTcs = new TaskCompletionSource <LinkedCheckpointInfo>(TaskCreationOptions.RunContinuationsAsynchronously);
                faster.checkpointTcs.SetResult(new LinkedCheckpointInfo {
                    NextTask = nextTcs.Task
                });
                faster.checkpointTcs = nextTcs;
                break;
            }
        }