コード例 #1
0
ファイル: FASTER.cs プロジェクト: wjdz99/FASTER
        internal Status ContextDelete <Input, Output, Context, FasterSession>(
            ref Key key,
            Context context,
            FasterSession fasterSession,
            long serialNo,
            FasterExecutionContext <Input, Output, Context> sessionCtx)
            where FasterSession : IFasterSession <Key, Value, Input, Output, Context>
        {
            var    pcontext       = default(PendingContext <Input, Output, Context>);
            var    internalStatus = InternalDelete(ref key, ref context, ref pcontext, fasterSession, sessionCtx, serialNo);
            Status status;

            if (internalStatus == OperationStatus.SUCCESS || internalStatus == OperationStatus.NOTFOUND)
            {
                status = (Status)internalStatus;
            }
            else
            {
                status = HandleOperationStatus(sessionCtx, sessionCtx, pcontext, fasterSession, internalStatus);
            }

            sessionCtx.serialNum = serialNo;
            return(status);
        }
コード例 #2
0
ファイル: FASTER.cs プロジェクト: ryanrc/FASTER
        internal Status ContextRead <Input, Output, Context, FasterSession>(ref Key key, ref Input input, ref Output output, Context context, FasterSession fasterSession, long serialNo,
                                                                            FasterExecutionContext <Input, Output, Context> sessionCtx)
            where FasterSession : IFasterSession <Key, Value, Input, Output, Context>
        {
            var pcontext       = default(PendingContext <Input, Output, Context>);
            var internalStatus = InternalRead(ref key, ref input, ref output, ref context, ref pcontext, fasterSession, sessionCtx, serialNo);

            Debug.Assert(internalStatus != OperationStatus.RETRY_NOW);

            Status status;

            if (internalStatus == OperationStatus.SUCCESS || internalStatus == OperationStatus.NOTFOUND)
            {
                status = (Status)internalStatus;
            }
            else
            {
                status = HandleOperationStatus(sessionCtx, sessionCtx, ref pcontext, fasterSession, internalStatus, false, out _);
            }

            Debug.Assert(serialNo >= sessionCtx.serialNum, "Operation serial numbers must be non-decreasing");
            sessionCtx.serialNum = serialNo;
            return(status);
        }
コード例 #3
0
        internal void AcquireSharedLatchesForAllPendingRequests <Input, Output, Context>(FasterExecutionContext <Input, Output, Context> ctx)
        {
            foreach (var _ctx in ctx.retryRequests)
            {
                AcquireSharedLatch(_ctx.key.Get());
            }

            foreach (var _ctx in ctx.ioPendingRequests.Values)
            {
                AcquireSharedLatch(_ctx.key.Get());
            }
        }
コード例 #4
0
ファイル: FASTERAsync.cs プロジェクト: zhuyanxi/FASTER
        internal ValueTask <RmwAsyncResult <Input, Output, Context> > RmwAsync <Input, Output, Context>(IFasterSession <Key, Value, Input, Output, Context> fasterSession,
                                                                                                        FasterExecutionContext <Input, Output, Context> currentCtx, ref Key key, ref Input input, Context context, long serialNo, CancellationToken token = default)
        {
            var pcontext    = default(PendingContext <Input, Output, Context>);
            var diskRequest = default(AsyncIOContext <Key, Value>);

            fasterSession.UnsafeResumeThread();
            try
            {
                OperationStatus internalStatus;

                do
                {
                    internalStatus = InternalRMW(ref key, ref input, ref context, ref pcontext, fasterSession, currentCtx, serialNo);
                }while (internalStatus == OperationStatus.RETRY_NOW || internalStatus == OperationStatus.RETRY_LATER);


                if (internalStatus == OperationStatus.SUCCESS || internalStatus == OperationStatus.NOTFOUND)
                {
                    return(new ValueTask <RmwAsyncResult <Input, Output, Context> >(new RmwAsyncResult <Input, Output, Context>((Status)internalStatus, default)));
コード例 #5
0
        private static async ValueTask <ExceptionDispatchInfo> WaitForFlushCompletionAsync <Input, Output, Context>(FasterKV <Key, Value> @this, FasterExecutionContext <Input, Output, Context> currentCtx, CompletionEvent flushEvent, CancellationToken token)
        {
            ExceptionDispatchInfo exceptionDispatchInfo = default;

            try
            {
                token.ThrowIfCancellationRequested();

                if (@this.epoch.ThisInstanceProtected())
                {
                    throw new NotSupportedException("Async operations not supported over protected epoch");
                }

                await flushEvent.WaitAsync(token).ConfigureAwait(false);
            }
            catch (Exception e)
            {
                exceptionDispatchInfo = ExceptionDispatchInfo.Capture(e);
            }
            return(exceptionDispatchInfo);
        }
コード例 #6
0
ファイル: Checkpoint.cs プロジェクト: karollapinski/FASTER
        private void HandleCheckpointingPhases(FasterExecutionContext ctx, ClientSession <Key, Value, Input, Output, Context, Functions> clientSession)
        {
            var _ = HandleCheckpointingPhasesAsync(ctx, clientSession, false);

            return;
        }
コード例 #7
0
        internal async ValueTask CompleteIOPendingRequestsAsync(FasterExecutionContext opCtx, FasterExecutionContext currentCtx, ClientSession <Key, Value, Input, Output, Context, Functions> clientSession, CancellationToken token = default)
        {
            while (opCtx.ioPendingRequests.Count > 0)
            {
                AsyncIOContext <Key, Value> request;

                if (opCtx.readyResponses.Count > 0)
                {
                    clientSession.UnsafeResumeThread();
                    while (opCtx.readyResponses.Count > 0)
                    {
                        opCtx.readyResponses.TryDequeue(out request);
                        InternalContinuePendingRequestAndCallback(opCtx, currentCtx, request);
                    }
                    clientSession.UnsafeSuspendThread();
                }
                else
                {
                    request = await opCtx.readyResponses.DequeueAsync(token);

                    clientSession.UnsafeResumeThread();
                    InternalContinuePendingRequestAndCallback(opCtx, currentCtx, request);
                    clientSession.UnsafeSuspendThread();
                }
            }
        }
コード例 #8
0
ファイル: FASTERAsync.cs プロジェクト: wjnv172/FASTER
        private async ValueTask HandleCheckpointingPhasesAsync(FasterExecutionContext ctx, ClientSession <Key, Value, Input, Output, Context, Functions> clientSession, bool async = true, CancellationToken token = default)
        {
            if (async)
            {
                clientSession?.UnsafeResumeThread();
            }

            var finalState = SystemState.Copy(ref _systemState);

            while (finalState.phase == Phase.INTERMEDIATE)
            {
                finalState = SystemState.Copy(ref _systemState);
            }

            var previousState = ctx != null?SystemState.Make(ctx.phase, ctx.version) : finalState;

            // We need to move from previousState to finalState one step at a time
            var currentState = previousState;

            SystemState startState = GetStartState(finalState);

            if ((currentState.version < startState.version) ||
                (currentState.version == startState.version && currentState.phase < startState.phase))
            {
                // Fast-forward to beginning of current checkpoint cycle
                currentState = startState;
            }

            do
            {
                switch (currentState.phase)
                {
                case Phase.PREP_INDEX_CHECKPOINT:
                {
                    if (ctx != null)
                    {
                        if (!ctx.markers[EpochPhaseIdx.PrepareForIndexCheckpt])
                        {
                            ctx.markers[EpochPhaseIdx.PrepareForIndexCheckpt] = true;
                        }
                        epoch.Mark(EpochPhaseIdx.PrepareForIndexCheckpt, currentState.version);
                    }

                    if (epoch.CheckIsComplete(EpochPhaseIdx.PrepareForIndexCheckpt, currentState.version))
                    {
                        GlobalMoveToNextCheckpointState(currentState);
                    }
                    break;
                }

                case Phase.INDEX_CHECKPOINT:
                {
                    if (_checkpointType == CheckpointType.INDEX_ONLY && ctx != null)
                    {
                        // Reseting the marker for a potential FULL or INDEX_ONLY checkpoint in the future
                        ctx.markers[EpochPhaseIdx.PrepareForIndexCheckpt] = false;
                    }

                    if (async && !IsIndexFuzzyCheckpointCompleted())
                    {
                        clientSession?.UnsafeSuspendThread();
                        await IsIndexFuzzyCheckpointCompletedAsync(token);

                        clientSession?.UnsafeResumeThread();
                    }
                    GlobalMoveToNextCheckpointState(currentState);

                    break;
                }

                case Phase.PREPARE:
                {
                    if (ctx != null)
                    {
                        if (!ctx.markers[EpochPhaseIdx.Prepare])
                        {
                            if (!RelaxedCPR)
                            {
                                AcquireSharedLatchesForAllPendingRequests(ctx);
                            }
                            ctx.markers[EpochPhaseIdx.Prepare] = true;
                        }
                        epoch.Mark(EpochPhaseIdx.Prepare, currentState.version);
                    }

                    if (epoch.CheckIsComplete(EpochPhaseIdx.Prepare, currentState.version))
                    {
                        GlobalMoveToNextCheckpointState(currentState);
                    }

                    break;
                }

                case Phase.IN_PROGRESS:
                {
                    if (ctx != null)
                    {
                        // Need to be very careful here as threadCtx is changing
                        FasterExecutionContext _ctx;
                        if (previousState.phase == Phase.IN_PROGRESS)
                        {
                            _ctx = ctx.prevCtx;
                        }
                        else
                        {
                            _ctx = ctx;
                        }

                        if (!_ctx.markers[EpochPhaseIdx.InProgress])
                        {
                            AtomicSwitch(ctx, ctx.prevCtx, _ctx.version);
                            InitContext(ctx, ctx.prevCtx.guid, ctx.prevCtx.serialNum);

                            // Has to be prevCtx, not ctx
                            ctx.prevCtx.markers[EpochPhaseIdx.InProgress] = true;
                        }

                        epoch.Mark(EpochPhaseIdx.InProgress, currentState.version);
                    }

                    // Has to be prevCtx, not ctx
                    if (epoch.CheckIsComplete(EpochPhaseIdx.InProgress, currentState.version))
                    {
                        GlobalMoveToNextCheckpointState(currentState);
                    }
                    break;
                }

                case Phase.WAIT_PENDING:
                {
                    if (ctx != null)
                    {
                        if (!ctx.prevCtx.markers[EpochPhaseIdx.WaitPending])
                        {
                            var notify = (ctx.prevCtx.ioPendingRequests.Count == 0);
                            notify = notify && (ctx.prevCtx.retryRequests.Count == 0);

                            if (notify)
                            {
                                ctx.prevCtx.markers[EpochPhaseIdx.WaitPending] = true;
                            }
                            else
                            {
                                break;
                            }
                        }
                        epoch.Mark(EpochPhaseIdx.WaitPending, currentState.version);
                    }

                    if (epoch.CheckIsComplete(EpochPhaseIdx.WaitPending, currentState.version))
                    {
                        GlobalMoveToNextCheckpointState(currentState);
                    }
                    break;
                }

                case Phase.WAIT_FLUSH:
                {
                    if (ctx == null || !ctx.prevCtx.markers[EpochPhaseIdx.WaitFlush])
                    {
                        bool notify;

                        if (FoldOverSnapshot)
                        {
                            notify = (hlog.FlushedUntilAddress >= _hybridLogCheckpoint.info.finalLogicalAddress);
                        }
                        else
                        {
                            notify = (_hybridLogCheckpoint.flushedSemaphore != null) && _hybridLogCheckpoint.flushedSemaphore.CurrentCount > 0;
                        }

                        if (async && !notify)
                        {
                            Debug.Assert(_hybridLogCheckpoint.flushedSemaphore != null);
                            clientSession?.UnsafeSuspendThread();
                            await _hybridLogCheckpoint.flushedSemaphore.WaitAsync(token);

                            clientSession?.UnsafeResumeThread();

                            _hybridLogCheckpoint.flushedSemaphore.Release();

                            notify = true;
                        }

                        if (_checkpointType == CheckpointType.FULL)
                        {
                            notify = notify && IsIndexFuzzyCheckpointCompleted();

                            if (async && !notify)
                            {
                                clientSession?.UnsafeSuspendThread();
                                await IsIndexFuzzyCheckpointCompletedAsync(token);

                                clientSession?.UnsafeResumeThread();

                                notify = true;
                            }
                        }

                        if (notify)
                        {
                            if (ctx != null)
                            {
                                ctx.prevCtx.markers[EpochPhaseIdx.WaitFlush] = true;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (ctx != null)
                    {
                        epoch.Mark(EpochPhaseIdx.WaitFlush, currentState.version);
                    }

                    if (epoch.CheckIsComplete(EpochPhaseIdx.WaitFlush, currentState.version))
                    {
                        GlobalMoveToNextCheckpointState(currentState);
                    }
                    break;
                }

                case Phase.PERSISTENCE_CALLBACK:
                {
                    if (ctx != null)
                    {
                        if (!ctx.prevCtx.markers[EpochPhaseIdx.CheckpointCompletionCallback])
                        {
                            if (ctx.prevCtx.serialNum != -1)
                            {
                                var commitPoint = new CommitPoint
                                {
                                    UntilSerialNo     = ctx.prevCtx.serialNum,
                                    ExcludedSerialNos = ctx.prevCtx.excludedSerialNos
                                };

                                // Thread local action
                                functions.CheckpointCompletionCallback(ctx.guid, commitPoint);
                                if (clientSession != null)
                                {
                                    clientSession.LatestCommitPoint = commitPoint;
                                }
                            }
                            ctx.prevCtx.markers[EpochPhaseIdx.CheckpointCompletionCallback] = true;
                        }
                        epoch.Mark(EpochPhaseIdx.CheckpointCompletionCallback, currentState.version);
                    }
                    if (epoch.CheckIsComplete(EpochPhaseIdx.CheckpointCompletionCallback, currentState.version))
                    {
                        GlobalMoveToNextCheckpointState(currentState);
                    }
                    break;
                }

                case Phase.REST:
                {
                    break;
                }

                default:
                    throw new FasterException("Invalid state found during checkpointing");
                }

                if (ctx != null)
                {
                    // update thread local variables
                    ctx.phase   = currentState.phase;
                    ctx.version = currentState.version;
                }
                previousState.word = currentState.word;
                currentState       = GetNextState(currentState, _checkpointType);
            } while (previousState.word != finalState.word);

            if (async)
            {
                clientSession?.UnsafeSuspendThread();
            }
        }
コード例 #9
0
        /// <summary>
        /// Steps the thread's local state machine. Threads catch up to the current global state and performs
        /// necessary actions associated with the state as defined by the current state machine
        /// </summary>
        /// <param name="ctx">null if calling without a context (e.g. waiting on a checkpoint)</param>
        /// <param name="fasterSession">Faster session.</param>
        /// <param name="valueTasks">Return list of tasks that caller needs to await, to continue checkpointing</param>
        /// <param name="token">Cancellation token</param>
        /// <returns></returns>
        private void ThreadStateMachineStep <Input, Output, Context, FasterSession>(
            FasterExecutionContext <Input, Output, Context> ctx,
            FasterSession fasterSession,
            List <ValueTask> valueTasks,
            CancellationToken token = default)
            where FasterSession : IFasterSession
        {
            #region Capture current (non-intermediate) system state
            var currentTask = currentSyncStateMachine;
            var targetState = SystemState.Copy(ref systemState);
            SystemState.RemoveIntermediate(ref targetState);

            while (currentSyncStateMachine != currentTask)
            {
                currentTask = currentSyncStateMachine;
                targetState = SystemState.Copy(ref systemState);
                SystemState.RemoveIntermediate(ref targetState);
            }
            #endregion

            var currentState     = ctx == null ? targetState : SystemState.Make(ctx.phase, ctx.version);
            var targetStartState = StartOfCurrentCycle(targetState);

            #region Get returning thread to start of current cycle, issuing completion callbacks if needed
            if (ctx != null)
            {
                if (ctx.version < targetStartState.version)
                {
                    // Issue CPR callback for full session
                    if (ctx.serialNum != -1)
                    {
                        List <long> excludedSerialNos = new List <long>();
                        foreach (var v in ctx.ioPendingRequests.Values)
                        {
                            excludedSerialNos.Add(v.serialNum);
                        }
                        foreach (var v in ctx.retryRequests)
                        {
                            excludedSerialNos.Add(v.serialNum);
                        }

                        var commitPoint = new CommitPoint
                        {
                            UntilSerialNo     = ctx.serialNum,
                            ExcludedSerialNos = excludedSerialNos
                        };

                        // Thread local action
                        fasterSession?.CheckpointCompletionCallback(ctx.guid, commitPoint);
                    }
                }
                if ((ctx.version == targetStartState.version) && (ctx.phase < Phase.REST))
                {
                    IssueCompletionCallback(ctx, fasterSession);
                }
            }
            #endregion

            // No state machine associated with target, or target is in REST phase:
            // we can directly fast forward session to target state
            if (currentTask == null || targetState.phase == Phase.REST)
            {
                if (ctx != null)
                {
                    ctx.phase   = targetState.phase;
                    ctx.version = targetState.version;
                }
                return;
            }

            #region Jump on and execute current state machine
            // We start at either the start point or our previous position in the state machine.
            // If we are calling from somewhere other than an execution thread (e.g. waiting on
            // a checkpoint to complete on a client app thread), we start at current system state
            var threadState =
                ctx == null ? targetState :
                FastForwardToCurrentCycle(currentState, targetStartState);

            var previousState = threadState;
            do
            {
                Debug.Assert(
                    (threadState.version < targetState.version) ||
                    (threadState.version == targetState.version &&
                     (threadState.phase <= targetState.phase || currentTask is IndexSnapshotStateMachine)
                    ));

                currentTask.OnThreadEnteringState(threadState, previousState, this, ctx, fasterSession, valueTasks, token);

                if (ctx != null)
                {
                    ctx.phase   = threadState.phase;
                    ctx.version = threadState.version;
                }

                previousState.word = threadState.word;
                threadState        = currentTask.NextState(threadState);
                if (systemState.word != targetState.word)
                {
                    var tmp = SystemState.Copy(ref systemState);
                    if (currentSyncStateMachine == currentTask)
                    {
                        targetState = tmp;
                        SystemState.RemoveIntermediate(ref targetState);
                    }
                }
            } while (previousState.word != targetState.word);
            #endregion

            return;
        }
コード例 #10
0
        private ValueTask <UpsertAsyncResult <Input, Output, Context> > UpsertAsync <Input, Output, Context>(IFasterSession <Key, Value, Input, Output, Context> fasterSession,
                                                                                                             FasterExecutionContext <Input, Output, Context> currentCtx, ref PendingContext <Input, Output, Context> pcontext, ref Key key, ref Value value, Context userContext, long serialNo, CancellationToken token)
        {
            CompletionEvent flushEvent;

            fasterSession.UnsafeResumeThread();
            try
            {
                OperationStatus internalStatus;
                do
                {
                    flushEvent     = hlog.FlushEvent;
                    internalStatus = InternalUpsert(ref key, ref value, ref userContext, ref pcontext, fasterSession, currentCtx, serialNo);
                } while (internalStatus == OperationStatus.RETRY_NOW);

                if (internalStatus == OperationStatus.SUCCESS || internalStatus == OperationStatus.NOTFOUND)
                {
                    return(new ValueTask <UpsertAsyncResult <Input, Output, Context> >(new UpsertAsyncResult <Input, Output, Context>((Status)internalStatus)));
                }
                Debug.Assert(internalStatus == OperationStatus.ALLOCATE_FAILED);
            }
            finally
            {
                Debug.Assert(serialNo >= currentCtx.serialNum, "Operation serial numbers must be non-decreasing");
                currentCtx.serialNum = serialNo;
                fasterSession.UnsafeSuspendThread();
            }

            return(SlowUpsertAsync(this, fasterSession, currentCtx, pcontext, flushEvent, token));
        }
コード例 #11
0
ファイル: CompletePendingAsync.cs プロジェクト: tli2/FASTER
        /// <summary>
        /// Check if at least one (sync) request is ready for CompletePending to operate on
        /// </summary>
        /// <param name="currentCtx"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        internal async ValueTask ReadyToCompletePendingAsync <Input, Output, Context>(FasterExecutionContext <Input, Output, Context> currentCtx, CancellationToken token = default)
        {
            #region Previous pending requests
            if (!RelaxedCPR)
            {
                if (currentCtx.phase == Phase.IN_PROGRESS || currentCtx.phase == Phase.WAIT_PENDING)
                {
                    if (currentCtx.prevCtx.SyncIoPendingCount != 0)
                    {
                        await currentCtx.prevCtx.readyResponses.WaitForEntryAsync(token).ConfigureAwait(false);
                    }
                }
            }
            #endregion

            if (currentCtx.SyncIoPendingCount != 0)
            {
                await currentCtx.readyResponses.WaitForEntryAsync(token).ConfigureAwait(false);
            }
        }
コード例 #12
0
ファイル: FASTERAsync.cs プロジェクト: tommydb/FASTER
        private static ExceptionDispatchInfo GetSlowUpdelAsyncExceptionDispatchInfo <Input, Output, Context>(FasterKV <Key, Value> @this, FasterExecutionContext <Input, Output, Context> currentCtx, CancellationToken token)
        {
            currentCtx.asyncPendingCount++;

            ExceptionDispatchInfo exceptionDispatchInfo = default;

            try
            {
                token.ThrowIfCancellationRequested();

                if (@this.epoch.ThisInstanceProtected())
                {
                    throw new NotSupportedException("Async operations not supported over protected epoch");
                }
            }
            catch (Exception e)
            {
                exceptionDispatchInfo = ExceptionDispatchInfo.Capture(e);
            }

            return(exceptionDispatchInfo);
        }
コード例 #13
0
ファイル: FASTERAsync.cs プロジェクト: tommydb/FASTER
        internal ValueTask <DeleteAsyncResult <Input, Output, Context> > DeleteAsync <Input, Output, Context>(IFasterSession <Key, Value, Input, Output, Context> fasterSession,
                                                                                                              FasterExecutionContext <Input, Output, Context> currentCtx, ref Key key, Context userContext, long serialNo, CancellationToken token = default)
        {
            var pcontext = default(PendingContext <Input, Output, Context>);

            pcontext.IsAsync = true;
            Task flushTask;

            fasterSession.UnsafeResumeThread();
            try
            {
                OperationStatus internalStatus;
                do
                {
                    flushTask      = hlog.FlushTask;
                    internalStatus = InternalDelete(ref key, ref userContext, ref pcontext, fasterSession, currentCtx, serialNo);
                } while (internalStatus == OperationStatus.RETRY_NOW);

                if (internalStatus == OperationStatus.SUCCESS || internalStatus == OperationStatus.NOTFOUND)
                {
                    return(new ValueTask <DeleteAsyncResult <Input, Output, Context> >(new DeleteAsyncResult <Input, Output, Context>(internalStatus)));
                }
                Debug.Assert(internalStatus == OperationStatus.ALLOCATE_FAILED);
            }
            finally
            {
                Debug.Assert(serialNo >= currentCtx.serialNum, "Operation serial numbers must be non-decreasing");
                currentCtx.serialNum = serialNo;
                fasterSession.UnsafeSuspendThread();
            }

            return(SlowDeleteAsync(this, fasterSession, currentCtx, pcontext, flushTask, token));
        }
コード例 #14
0
ファイル: FASTERAsync.cs プロジェクト: tommydb/FASTER
 public OperationStatus DoFastOperation(FasterKV <Key, Value> fasterKV, PendingContext <Input, Output, Context> pendingContext, IFasterSession <Key, Value, Input, Output, Context> fasterSession,
                                        FasterExecutionContext <Input, Output, Context> currentCtx)
 => fasterKV.InternalDelete(ref pendingContext.key.Get(), ref pendingContext.userContext, ref pendingContext, fasterSession, currentCtx, pendingContext.serialNum);
コード例 #15
0
ファイル: FASTERAsync.cs プロジェクト: tommydb/FASTER
 public ValueTask <UpsertAsyncResult <Input, Output, Context> > DoSlowOperation(FasterKV <Key, Value> fasterKV, IFasterSession <Key, Value, Input, Output, Context> fasterSession,
                                                                                FasterExecutionContext <Input, Output, Context> currentCtx, PendingContext <Input, Output, Context> pendingContext, Task flushTask, CancellationToken token)
 => SlowUpsertAsync(fasterKV, fasterSession, currentCtx, pendingContext, flushTask, token);
コード例 #16
0
ファイル: FASTER.cs プロジェクト: zhoubass/FASTER
        internal Status ContextRMW(ref Key key, ref Input input, Context context, long serialNo, FasterExecutionContext sessionCtx)
        {
            var    pcontext       = default(PendingContext);
            var    internalStatus = InternalRMW(ref key, ref input, ref context, ref pcontext, sessionCtx, serialNo);
            Status status;

            if (internalStatus == OperationStatus.SUCCESS || internalStatus == OperationStatus.NOTFOUND)
            {
                status = (Status)internalStatus;
            }
            else
            {
                status = HandleOperationStatus(sessionCtx, sessionCtx, pcontext, internalStatus);
            }
            sessionCtx.serialNum = serialNo;
            return(status);
        }
コード例 #17
0
ファイル: ReadAsync.cs プロジェクト: tli2/FASTER
        internal ValueTask <ReadAsyncResult <Input, Output, Context> > ReadAsync <Input, Output, Context>(IFasterSession <Key, Value, Input, Output, Context> fasterSession,
                                                                                                          FasterExecutionContext <Input, Output, Context> currentCtx,
                                                                                                          ref Key key, ref Input input, long startAddress, Context context, long serialNo, CancellationToken token, byte operationFlags = 0)
        {
            var pcontext = default(PendingContext <Input, Output, Context>);

            pcontext.SetOperationFlags(operationFlags, startAddress);
            var    diskRequest = default(AsyncIOContext <Key, Value>);
            Output output      = default;

            fasterSession.UnsafeResumeThread();
            try
            {
                OperationStatus internalStatus = InternalRead(ref key, ref input, ref output, startAddress, ref context, ref pcontext, fasterSession, currentCtx, serialNo);
                Debug.Assert(internalStatus != OperationStatus.RETRY_NOW);
                Debug.Assert(internalStatus != OperationStatus.RETRY_LATER);

                if (internalStatus == OperationStatus.SUCCESS || internalStatus == OperationStatus.NOTFOUND)
                {
                    return(new ValueTask <ReadAsyncResult <Input, Output, Context> >(new ReadAsyncResult <Input, Output, Context>((Status)internalStatus, output, pcontext.recordInfo)));
                }
                else
                {
                    var status = HandleOperationStatus(currentCtx, currentCtx, ref pcontext, fasterSession, internalStatus, true, out diskRequest);

                    if (status != Status.PENDING)
                    {
                        return(new ValueTask <ReadAsyncResult <Input, Output, Context> >(new ReadAsyncResult <Input, Output, Context>(status, output, pcontext.recordInfo)));
                    }
                }
            }
            finally
            {
                Debug.Assert(serialNo >= currentCtx.serialNum, "Operation serial numbers must be non-decreasing");
                currentCtx.serialNum = serialNo;
                fasterSession.UnsafeSuspendThread();
            }

            return(SlowReadAsync(this, fasterSession, currentCtx, pcontext, diskRequest, token));
        }
コード例 #18
0
ファイル: FASTERThread.cs プロジェクト: randyammar/FASTER
        internal void InternalRetryRequestAndCallback(
            FasterExecutionContext ctx,
            PendingContext pendingContext)
        {
            var status         = default(Status);
            var internalStatus = default(OperationStatus);

            #region Entry latch operation
            var handleLatches = false;
            if ((ctx.version < threadCtx.version)   // Thread has already shifted to (v+1)
                ||
                (threadCtx.phase == Phase.PREPARE)) // Thread still in version v, but acquired shared-latch
            {
                handleLatches = true;
            }
            #endregion

            // Issue retry command
            switch (pendingContext.type)
            {
            case OperationType.RMW:
                internalStatus = InternalRetryPendingRMW(ctx, ref pendingContext);
                break;

            case OperationType.UPSERT:
                internalStatus = InternalUpsert(ref pendingContext.key,
                                                ref pendingContext.value,
                                                ref pendingContext.userContext,
                                                ref pendingContext);
                break;

            case OperationType.READ:
                throw new Exception("Cannot happen!");
            }


            // Handle operation status
            if (internalStatus == OperationStatus.SUCCESS || internalStatus == OperationStatus.NOTFOUND)
            {
                status = (Status)internalStatus;
            }
            else
            {
                status = HandleOperationStatus(ctx, pendingContext, internalStatus);
            }

            // If done, callback user code.
            if (status == Status.OK || status == Status.NOTFOUND)
            {
                if (handleLatches)
                {
                    ReleaseSharedLatch(pendingContext.key);
                }

                switch (pendingContext.type)
                {
                case OperationType.RMW:
                    functions.RMWCompletionCallback(ref pendingContext.key,
                                                    ref pendingContext.input,
                                                    pendingContext.userContext, status);
                    break;

                case OperationType.UPSERT:
                    functions.UpsertCompletionCallback(ref pendingContext.key,
                                                       ref pendingContext.value,
                                                       pendingContext.userContext);
                    break;

                default:
                    throw new Exception("Operation type not allowed for retry");
                }
            }
        }
コード例 #19
0
ファイル: ReadAsync.cs プロジェクト: tli2/FASTER
 internal ReadAsyncInternal(FasterKV <Key, Value> fasterKV, IFasterSession <Key, Value, Input, Output, Context> fasterSession, FasterExecutionContext <Input, Output, Context> currentCtx,
                            PendingContext <Input, Output, Context> pendingContext, AsyncIOContext <Key, Value> diskRequest, ExceptionDispatchInfo exceptionDispatchInfo)
 {
     _exception              = exceptionDispatchInfo;
     _fasterKV               = fasterKV;
     _fasterSession          = fasterSession;
     _currentCtx             = currentCtx;
     _pendingContext         = pendingContext;
     _diskRequest            = diskRequest;
     CompletionComputeStatus = Pending;
     _recordInfo             = default;
 }
コード例 #20
0
ファイル: FASTERAsync.cs プロジェクト: okwh/FASTER
 internal bool AtomicSwitch <Input, Output, Context>(FasterExecutionContext <Input, Output, Context> fromCtx, FasterExecutionContext <Input, Output, Context> toCtx, int version, ConcurrentDictionary <string, CommitPoint> tokens)
 {
     lock (toCtx)
     {
         if (toCtx.version < version)
         {
             CopyContext(fromCtx, toCtx);
             if (toCtx.serialNum != -1)
             {
                 tokens.TryAdd(toCtx.guid,
                               new CommitPoint
                 {
                     UntilSerialNo     = toCtx.serialNum,
                     ExcludedSerialNos = toCtx.excludedSerialNos
                 });
             }
             return(true);
         }
     }
     return(false);
 }
コード例 #21
0
ファイル: FASTERAsync.cs プロジェクト: wjdz99/FASTER
 internal bool AtomicSwitch <Input, Output, Context>(FasterExecutionContext <Input, Output, Context> fromCtx, FasterExecutionContext <Input, Output, Context> toCtx, int version)
 {
     lock (toCtx)
     {
         if (toCtx.version < version)
         {
             CopyContext(fromCtx, toCtx);
             if (toCtx.serialNum != -1)
             {
                 _hybridLogCheckpoint.info.checkpointTokens.TryAdd(toCtx.guid,
                                                                   new CommitPoint
                 {
                     UntilSerialNo     = toCtx.serialNum,
                     ExcludedSerialNos = toCtx.excludedSerialNos
                 });
             }
             return(true);
         }
     }
     return(false);
 }
コード例 #22
0
ファイル: DeleteAsync.cs プロジェクト: yitao-zhang/FASTER
 /// <inheritdoc/>
 public ValueTask <DeleteAsyncResult <Input, Output, Context> > DoSlowOperation(FasterKV <Key, Value> fasterKV, IFasterSession <Key, Value, Input, Output, Context> fasterSession,
                                                                                FasterExecutionContext <Input, Output, Context> currentCtx, PendingContext <Input, Output, Context> pendingContext, CompletionEvent flushEvent, CancellationToken token)
 => SlowDeleteAsync(fasterKV, fasterSession, currentCtx, pendingContext, flushEvent, token);
コード例 #23
0
ファイル: FASTERThread.cs プロジェクト: randyammar/FASTER
        internal void InternalContinuePendingRequestAndCallback(
            FasterExecutionContext ctx,
            AsyncIOContext <Key, Value> request)
        {
            var handleLatches = false;

            if ((ctx.version < threadCtx.version)   // Thread has already shifted to (v+1)
                ||
                (threadCtx.phase == Phase.PREPARE)) // Thread still in version v, but acquired shared-latch
            {
                handleLatches = true;
            }

            if (ctx.ioPendingRequests.TryGetValue(request.id, out PendingContext pendingContext))
            {
                var status         = default(Status);
                var internalStatus = default(OperationStatus);

                // Remove from pending dictionary
                ctx.ioPendingRequests.Remove(request.id);

                // Issue the continue command
                if (pendingContext.type == OperationType.READ)
                {
                    internalStatus = InternalContinuePendingRead(ctx, request, ref pendingContext);
                }
                else
                {
                    internalStatus = InternalContinuePendingRMW(ctx, request, ref pendingContext);;
                }

                request.record.Return();

                // Handle operation status
                if (internalStatus == OperationStatus.SUCCESS || internalStatus == OperationStatus.NOTFOUND)
                {
                    status = (Status)internalStatus;
                }
                else
                {
                    status = HandleOperationStatus(ctx, pendingContext, internalStatus);
                }

                // If done, callback user code
                if (status == Status.OK || status == Status.NOTFOUND)
                {
                    if (handleLatches)
                    {
                        ReleaseSharedLatch(pendingContext.key);
                    }

                    if (pendingContext.type == OperationType.READ)
                    {
                        functions.ReadCompletionCallback(ref pendingContext.key,
                                                         ref pendingContext.input,
                                                         ref pendingContext.output,
                                                         pendingContext.userContext,
                                                         status);
                    }
                    else
                    {
                        functions.RMWCompletionCallback(ref pendingContext.key,
                                                        ref pendingContext.input,
                                                        pendingContext.userContext,
                                                        status);
                    }
                }
            }
        }
コード例 #24
0
ファイル: DeleteAsync.cs プロジェクト: yitao-zhang/FASTER
 /// <inheritdoc/>
 public void DecrementPending(FasterExecutionContext <Input, Output, Context> currentCtx, ref PendingContext <Input, Output, Context> pendingContext)
 {
 }
コード例 #25
0
        /// <summary>
        /// Issue completion callback if needed, for the given context's prevCtx
        /// </summary>
        internal void IssueCompletionCallback <Input, Output, Context, FasterSession>(FasterExecutionContext <Input, Output, Context> ctx, FasterSession fasterSession)
            where FasterSession : IFasterSession
        {
            CommitPoint commitPoint = default;

            if (ctx.prevCtx.excludedSerialNos != null)
            {
                lock (ctx.prevCtx)
                {
                    if (ctx.prevCtx.serialNum != -1)
                    {
                        commitPoint = new CommitPoint
                        {
                            UntilSerialNo     = ctx.prevCtx.serialNum,
                            ExcludedSerialNos = ctx.prevCtx.excludedSerialNos
                        };
                        ctx.prevCtx.excludedSerialNos = null;
                    }
                }
                if (commitPoint.ExcludedSerialNos != null)
                {
                    fasterSession?.CheckpointCompletionCallback(ctx.guid, commitPoint);
                }
            }
        }
コード例 #26
0
ファイル: DeleteAsync.cs プロジェクト: yitao-zhang/FASTER
        internal ValueTask <DeleteAsyncResult <Input, Output, Context> > DeleteAsync <Input, Output, Context>(IFasterSession <Key, Value, Input, Output, Context> fasterSession,
                                                                                                              FasterExecutionContext <Input, Output, Context> currentCtx, ref Key key, Context userContext, long serialNo, CancellationToken token = default)
        {
            var pcontext = new PendingContext <Input, Output, Context> {
                IsAsync = true
            };

            return(DeleteAsync(fasterSession, currentCtx, ref pcontext, ref key, userContext, serialNo, token));
        }
コード例 #27
0
 internal void InternalCompleteRetryRequest(FasterExecutionContext opCtx, FasterExecutionContext currentCtx, PendingContext pendingContext)
 {
     var       internalStatus = default(OperationStatus);
     ref Key   key            = ref pendingContext.key.Get();
コード例 #28
0
ファイル: DeleteAsync.cs プロジェクト: yitao-zhang/FASTER
        internal ValueTask <DeleteAsyncResult <Input, Output, Context> > DeleteAsync <Input, Output, Context>(IFasterSession <Key, Value, Input, Output, Context> fasterSession,
                                                                                                              FasterExecutionContext <Input, Output, Context> currentCtx, ref PendingContext <Input, Output, Context> pcontext, ref Key key, Context userContext, long serialNo, CancellationToken token)
        {
            CompletionEvent flushEvent;

            fasterSession.UnsafeResumeThread();
            try
            {
                OperationStatus internalStatus;
                do
                {
                    flushEvent     = hlog.FlushEvent;
                    internalStatus = InternalDelete(ref key, ref userContext, ref pcontext, fasterSession, currentCtx, serialNo);
                } while (internalStatus == OperationStatus.RETRY_NOW);

                if (OperationStatusUtils.TryConvertToStatusCode(internalStatus, out Status status))
                {
                    return(new ValueTask <DeleteAsyncResult <Input, Output, Context> >(new DeleteAsyncResult <Input, Output, Context>(new(internalStatus))));
                }

                Debug.Assert(internalStatus == OperationStatus.ALLOCATE_FAILED);
            }
            finally
            {
                Debug.Assert(serialNo >= currentCtx.serialNum, "Operation serial numbers must be non-decreasing");
                currentCtx.serialNum = serialNo;
                fasterSession.UnsafeSuspendThread();
            }

            return(SlowDeleteAsync(this, fasterSession, currentCtx, pcontext, flushEvent, token));
        }
コード例 #29
0
ファイル: FASTERThread.cs プロジェクト: zhangzihan/FASTER
        internal void CopyContext <Input, Output, Context>(FasterExecutionContext <Input, Output, Context> src, FasterExecutionContext <Input, Output, Context> dst)
        {
            dst.phase              = src.phase;
            dst.version            = src.version;
            dst.threadStateMachine = src.threadStateMachine;
            dst.markers            = src.markers;
            dst.serialNum          = src.serialNum;
            dst.guid = src.guid;
            dst.excludedSerialNos = new List <long>();

            if (!RelaxedCPR)
            {
                dst.totalPending      = src.totalPending;
                dst.retryRequests     = src.retryRequests;
                dst.readyResponses    = src.readyResponses;
                dst.ioPendingRequests = src.ioPendingRequests;
                dst.pendingReads      = src.pendingReads;
            }
            else
            {
                foreach (var v in src.ioPendingRequests.Values)
                {
                    dst.excludedSerialNos.Add(v.serialNum);
                }
                foreach (var v in src.retryRequests)
                {
                    dst.excludedSerialNos.Add(v.serialNum);
                }
            }
        }
コード例 #30
0
 /// <summary>
 /// Check if at least one (sync) request is ready for CompletePending to operate on
 /// </summary>
 /// <param name="currentCtx"></param>
 /// <param name="token"></param>
 /// <returns></returns>
 internal async ValueTask ReadyToCompletePendingAsync <Input, Output, Context>(FasterExecutionContext <Input, Output, Context> currentCtx, CancellationToken token = default)
 {
     if (currentCtx.SyncIoPendingCount != 0)
     {
         await currentCtx.readyResponses.WaitForEntryAsync(token).ConfigureAwait(false);
     }
 }