GetMinimumSequence() public static method

Get the minimum sequence from an array of Sequences.
public static GetMinimumSequence ( ISequence sequences, long minimum = long.MaxValue ) : long
sequences ISequence sequences to compare.
minimum long an initial default minimum. If the array is empty this value will returned.
return long
Esempio n. 1
0
        public long RemainingCapacity()
        {
            long consumed = Util.GetMinimumSequence(_gatingSequences);
            long produced = _cursor.Value;

            return(BufferSize - (produced - consumed));
        }
Esempio n. 2
0
        private bool HasAvailableCapacity(int requiredCapacity, bool doStore)
        {
            long nextValue = _nextValue;

            long wrapPoint            = (nextValue + requiredCapacity) - _bufferSize;
            long cachedGatingSequence = _cachedValue;

            if (wrapPoint > cachedGatingSequence || cachedGatingSequence > nextValue)
            {
                if (doStore)
                {
                    _cursor.SetValueVolatile(nextValue);
                }

                long minSequence = Util.GetMinimumSequence(Volatile.Read(ref _gatingSequences), nextValue);
                _cachedValue = minSequence;

                if (wrapPoint > minSequence)
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 3
0
        internal long NextInternal(int n)
        {
            long current;
            long next;

            var spinWait = default(AggressiveSpinWait);

            do
            {
                current = _cursor.Value;
                next    = current + n;

                long wrapPoint            = next - _bufferSize;
                long cachedGatingSequence = _gatingSequenceCache.Value;

                if (wrapPoint > cachedGatingSequence || cachedGatingSequence > current)
                {
                    long gatingSequence = Util.GetMinimumSequence(Volatile.Read(ref _gatingSequences), current);

                    if (wrapPoint > gatingSequence)
                    {
                        spinWait.SpinOnce();
                        continue;
                    }

                    _gatingSequenceCache.SetValue(gatingSequence);
                }
                else if (_cursor.CompareAndSet(current, next))
                {
                    break;
                }
            } while (true);

            return(next);
        }
Esempio n. 4
0
        public long GetRemainingCapacity()
        {
            var consumed = Util.GetMinimumSequence(Volatile.Read(ref _gatingSequences), _cursor.Value);
            var produced = _cursor.Value;

            return(BufferSize - (produced - consumed));
        }
Esempio n. 5
0
        /// <summary>
        /// Wait for the given sequence to be available
        /// </summary>
        /// <param name="sequence">sequence to be waited on.</param>
        /// <param name="cursor">Ring buffer cursor on which to wait.</param>
        /// <param name="dependents">dependents further back the chain that must advance first</param>
        /// <param name="barrier">barrier the <see cref="IEventProcessor"/> is waiting on.</param>
        /// <returns>the sequence that is available which may be greater than the requested sequence.</returns>
        public long WaitFor(long sequence, Sequence cursor, Sequence[] dependents, ISequenceBarrier barrier)
        {
            long availableSequence;
            var  spinWait = default(SpinWait);

            if (dependents.Length == 0)
            {
                while ((availableSequence = cursor.Value) < sequence) // volatile read
                {
                    barrier.CheckAlert();
                    spinWait.SpinOnce();
                    if (spinWait.Count > 5000)
                    {
                        break;
                    }
                }
            }
            else
            {
                while ((availableSequence = Util.GetMinimumSequence(dependents)) < sequence)
                {
                    barrier.CheckAlert();
                    spinWait.SpinOnce();
                    if (spinWait.Count > 5000)
                    {
                        break;
                    }
                }
            }

            return(availableSequence);
        }
Esempio n. 6
0
        /// <summary>
        /// Claim the next n events in sequence for publishing.  This is for batch event producing.  Using batch producing requires a little care and some math.
        /// <code>
        ///     int n = 10;
        ///     long hi = sequencer.next(n);
        ///     long lo = hi - (n - 1);
        ///     for (long sequence = lo; sequence &lt;= hi; sequence++) {
        ///        // Do work.
        ///     }
        ///     sequencer.publish(lo, hi);
        /// </code>
        /// </summary>
        /// <param name="n">the number of sequences to claim</param>
        /// <returns>the highest claimed sequence value</returns>
        public override long Next(int n)
        {
            if (n < 1)
            {
                throw new ArgumentException("n must be > 0");
            }

            long nextValue = _fields.NextValue;

            long nextSequence         = nextValue + n;
            long wrapPoint            = nextSequence - _bufferSize;
            long cachedGatingSequence = _fields.CachedValue;

            if (wrapPoint > cachedGatingSequence || cachedGatingSequence > nextValue)
            {
                _cursor.SetValueVolatile(nextValue);

                var  spinWait = default(SpinWait);
                long minSequence;
                while (wrapPoint > (minSequence = Util.GetMinimumSequence(Volatile.Read(ref _gatingSequences), nextValue)))
                {
                    _waitStrategy.SignalAllWhenBlocking();
                    spinWait.SpinOnce(); // LockSupport.parkNanos(1L);
                }

                _fields.CachedValue = minSequence;
            }

            _fields.NextValue = nextSequence;

            return(nextSequence);
        }
Esempio n. 7
0
        public long WaitFor(IConsumer[] consumers, IRingBuffer <T> ringBuffer, IConsumerBarrier <T> barrier, long sequence)
        {
            long availableSequence;

            if (0 == consumers.Length)
            {
                while ((availableSequence = ringBuffer.Cursor) < sequence)
                {
                    if (barrier.IsAlerted())
                    {
                        throw AlertException.ALERT_EXCEPTION;
                    }
                }
            }
            else
            {
                while ((availableSequence = Util.GetMinimumSequence(consumers)) < sequence)
                {
                    if (barrier.IsAlerted())
                    {
                        throw AlertException.ALERT_EXCEPTION;
                    }
                }
            }

            return(availableSequence);
        }
Esempio n. 8
0
        public long NextInternal(int n)
        {
            long nextValue = _nextValue;

            long nextSequence         = nextValue + n;
            long wrapPoint            = nextSequence - _bufferSize;
            long cachedGatingSequence = _cachedValue;

            if (wrapPoint > cachedGatingSequence || cachedGatingSequence > nextValue)
            {
                _cursor.SetValueVolatile(nextValue);

                var  spinWait = default(AggressiveSpinWait);
                long minSequence;
                while (wrapPoint > (minSequence = Util.GetMinimumSequence(Volatile.Read(ref _gatingSequences), nextValue)))
                {
                    spinWait.SpinOnce();
                }

                _cachedValue = minSequence;
            }

            _nextValue = nextSequence;

            return(nextSequence);
        }
Esempio n. 9
0
        /// <summary>
        /// Wait for the given sequence to be available with a timeout specified.
        /// </summary>
        /// <param name="sequence">sequence to be waited on.</param>
        /// <param name="cursor">cursor on which to wait.</param>
        /// <param name="dependents">dependents further back the chain that must advance first</param>
        /// <param name="barrier">barrier the processor is waiting on.</param>
        /// <param name="timeout">timeout value to abort after.</param>
        /// <returns>the sequence that is available which may be greater than the requested sequence.</returns>
        /// <exception cref="AlertException">AlertException if the status of the Disruptor has changed.</exception>
        public long WaitFor(long sequence, Sequence cursor, Sequence[] dependents, ISequenceBarrier barrier, TimeSpan timeout)
        {
            long availableSequence;
            var  counter = SpinTries;
            var  sw      = Stopwatch.StartNew();

            if (dependents.Length == 0)
            {
                while ((availableSequence = cursor.Value) < sequence) // volatile read
                {
                    counter = ApplyWaitMethod(barrier, counter);
                    if (sw.Elapsed > timeout)
                    {
                        break;
                    }
                }
            }
            else
            {
                while ((availableSequence = Util.GetMinimumSequence(dependents)) < sequence)
                {
                    counter = ApplyWaitMethod(barrier, counter);
                    if (sw.Elapsed > timeout)
                    {
                        break;
                    }
                }
            }

            return(availableSequence);
        }
        /// <summary>
        /// Wait for the given sequence to be available
        /// </summary>
        /// <param name="sequence">sequence to be waited on.</param>
        /// <param name="cursor">Ring buffer cursor on which to wait.</param>
        /// <param name="dependents">dependents further back the chain that must advance first</param>
        /// <param name="barrier">barrier the <see cref="IEventProcessor"/> is waiting on.</param>
        /// <returns>the sequence that is available which may be greater than the requested sequence.</returns>
        public long WaitFor(long sequence, Sequence cursor, Sequence[] dependents, ISequenceBarrier barrier)
        {
            var availableSequence = cursor.Value; // volatile read

            if (availableSequence < sequence)
            {
                Monitor.Enter(_gate);
                try
                {
                    ++_numWaiters;
                    while ((availableSequence = cursor.Value) < sequence) // volatile read
                    {
                        barrier.CheckAlert();
                        Monitor.Wait(_gate);
                    }
                }
                finally
                {
                    --_numWaiters;
                    Monitor.Exit(_gate);
                }
            }

            if (dependents.Length != 0)
            {
                while ((availableSequence = Util.GetMinimumSequence(dependents)) < sequence)
                {
                    barrier.CheckAlert();
                }
            }

            return(availableSequence);
        }
Esempio n. 11
0
        /// <summary>
        /// Wait for the given sequence to be available with a timeout specified.
        /// </summary>
        /// <param name="sequence">sequence to be waited on.</param>
        /// <param name="cursor">cursor on which to wait.</param>
        /// <param name="dependents">dependents further back the chain that must advance first</param>
        /// <param name="barrier">barrier the processor is waiting on.</param>
        /// <param name="timeout">timeout value to abort after.</param>
        /// <returns>the sequence that is available which may be greater than the requested sequence.</returns>
        /// <exception cref="AlertException">AlertException if the status of the Disruptor has changed.</exception>
        public long WaitFor(long sequence, Sequence cursor, Sequence[] dependents, ISequenceBarrier barrier, TimeSpan timeout)
        {
            long availableSequence;
            var  spinWait = new SpinWait();
            var  sw       = Stopwatch.StartNew();

            if (dependents.Length == 0)
            {
                while ((availableSequence = cursor.Value) < sequence) // volatile read
                {
                    barrier.CheckAlert();
                    spinWait.SpinOnce();

                    if (sw.Elapsed > timeout)
                    {
                        break;
                    }
                }
            }
            else
            {
                while ((availableSequence = Util.GetMinimumSequence(dependents)) < sequence)
                {
                    barrier.CheckAlert();
                    spinWait.SpinOnce();

                    if (sw.Elapsed > timeout)
                    {
                        break;
                    }
                }
            }

            return(availableSequence);
        }
        public override long RemainingCapacity()
        {
            var consumed = Util.GetMinimumSequence(sequencesRef.ReadFullFence(), cursor.Value);
            var produced = cursor.Value;

            return(GetBufferSize - (produced - consumed));
        }
Esempio n. 13
0
        public override long Next(int n)
        {
            if (n < 1)
            {
                throw new ArgumentOutOfRangeException("n must be > 0");
            }
            SpinWait spinWait  = new SpinWait();
            long     nextValue = this.nextValue;

            long nextSequence         = nextValue + n;
            long wrapPoint            = nextSequence - bufferSize;
            long cachedGatingSequence = this.cachedValue;

            if (wrapPoint > cachedGatingSequence || cachedGatingSequence > nextValue)
            {
                long minSequence;
                while (wrapPoint > (minSequence = Util.GetMinimumSequence(/*sequencesRef.ReadFullFence()*/ sequencesRef.ReadCompilerOnlyFence(), nextValue)))
                {
                    spinWait.SpinOnce();
                }
                this.cachedValue = minSequence;
            }
            this.nextValue = nextSequence;

            return(nextSequence);
        }
Esempio n. 14
0
        public override long RemainingCapacity()
        {
            long nextValue = this.nextValue;

            long consumed = Util.GetMinimumSequence(/*sequencesRef.ReadFullFence()*/ sequencesRef.ReadCompilerOnlyFence(), nextValue);
            long produced = nextValue;

            return(GetBufferSize - (produced - consumed));
        }
Esempio n. 15
0
        /// <summary>
        /// Get the remaining capacity for this sequencer. return The number of slots remaining.
        /// </summary>
        public override long GetRemainingCapacity()
        {
            var nextValue = _fields.NextValue;

            var consumed = Util.GetMinimumSequence(Volatile.Read(ref _gatingSequences), nextValue);
            var produced = nextValue;

            return(BufferSize - (produced - consumed));
        }
Esempio n. 16
0
            private void EnsureConsumersAreInRange(long sequence)
            {
                while ((sequence - Util.GetMinimumSequence(_consumers)) >= _ringBuffer._entries.Length)
                {
#if CSHARP30
                    Thread.Sleep(0);
#else
                    Thread.Yield();
#endif
                }
            }
        private void NextInternalWrap(long nextValue, long wrapPoint)
        {
            _cursor.SetValueVolatile(nextValue);

            var  spinWait = default(AggressiveSpinWait);
            long minSequence;

            while (wrapPoint > (minSequence = Util.GetMinimumSequence(Volatile.Read(ref _gatingSequences), nextValue)))
            {
                spinWait.SpinOnce();
            }

            _cachedValue = minSequence;
        }
Esempio n. 18
0
        private void WaitForFreeSlotAt(long sequence, Sequence[] dependentSequences)
        {
            long wrapPoint = sequence - _bufferSize;

            if (wrapPoint > _minGatingSequence.Value)
            {
                long minSequence;
                while (wrapPoint > (minSequence = Util.GetMinimumSequence(dependentSequences)))
                {
                    // TODO LockSupport.parkNanos(1L);
                }

                _minGatingSequence.Value = minSequence;
            }
        }
        private void WaitForCapacity(Sequence[] dependentSequences, MutableLong minGatingSequence)
        {
            long wrapPoint = (_claimSequence.Value + 1L) - _bufferSize;

            if (wrapPoint > minGatingSequence.Value)
            {
                long minSequence;
                while (wrapPoint > (minSequence = Util.GetMinimumSequence(dependentSequences)))
                {
                    //TODO LockSupport.parkNanos(1L);
                }

                minGatingSequence.Value = minSequence;
            }
        }
Esempio n. 20
0
        /// <summary>
        /// Wait for the <see cref="RingBuffer{T}"/> to drain of published events then halt the workers.
        /// </summary>
        public void DrainAndHalt()
        {
            var workerSequences = GetWorkerSequences();

            while (_ringBuffer.Cursor > Util.GetMinimumSequence(workerSequences))
            {
                Thread.Sleep(0);
            }

            foreach (var workProcessor in _workProcessors)
            {
                workProcessor.Halt();
            }

            _running = 0;
        }
        private void WaitForFreeSlotAt(long sequence, Sequence[] dependentSequences, MutableLong minGatingSequence)
        {
            long wrapPoint = sequence - _bufferSize;

            if (wrapPoint > minGatingSequence.Value)
            {
                var  spinWait = default(SpinWait);
                long minSequence;
                while (wrapPoint > (minSequence = Util.GetMinimumSequence(dependentSequences)))
                {
                    spinWait.SpinOnce(); //Java version uses LockSupport.parkNanos(1L);
                }

                minGatingSequence.Value = minSequence;
            }
        }
        /// <summary>
        /// Wait for the <see cref="RingBuffer"/> to drain of published events then halt the workers.
        /// </summary>
        public void drainAndHalt()
        {
            var workerSequences = getWorkerSequences();

            while (ringBuffer.GetCursor > Util.GetMinimumSequence(workerSequences))
            {
                Thread.Sleep(0);
            }

            foreach (WorkProcessor <T> processor in workProcessors)
            {
                processor.Halt();
            }

            started.WriteFullFence(false);
        }
        private void WaitForCapacity(Sequence[] dependentSequences, MutableLong minGatingSequence)
        {
            long wrapPoint = (_claimSequence.ReadFullFence() + 1L) - _bufferSize;

            if (wrapPoint > minGatingSequence.Value)
            {
                long minSequence;
                var  spinWait = default(SpinWait);
                while (wrapPoint > (minSequence = Util.GetMinimumSequence(dependentSequences)))
                {
                    spinWait.SpinOnce(); //LockSupport.parkNanos(1L);
                }

                minGatingSequence.Value = minSequence;
            }
        }
        private void WaitForFreeSlotAt(long sequence, Sequence[] dependentSequences)
        {
            long wrapPoint = sequence - _bufferSize;

            if (wrapPoint > _minGatingSequence.ReadUnfenced())
            {
                long minSequence;
                var  spinWait = default(SpinWait);
                while (wrapPoint > (minSequence = Util.GetMinimumSequence(dependentSequences)))
                {
                    spinWait.SpinOnce(); // LockSupport.parkNanos(1L);
                }

                _minGatingSequence.WriteUnfenced(minSequence);
            }
        }
Esempio n. 25
0
        /// <summary>
        /// Wait for the <see cref="RingBuffer{T}"/> to drain of published events then halt the workers.
        /// </summary>
        public void DrainAndHalt()
        {
            var workerSequences = WorkerSequences;

            while (_ringBuffer.Cursor > Util.GetMinimumSequence(workerSequences))
            {
                Thread.Sleep(0);
            }

            for (int i = 0; i < _workProcessors.Length; i++)
            {
                var workProcessor = _workProcessors[i];
                workProcessor.Halt();
            }

            _running.WriteFullFence(Stopped);
        }
Esempio n. 26
0
        /// <summary>
        /// Wait for the <see cref="RingBuffer{T}"/> to drain of published events then halt the workers.
        /// </summary>
        public void DrainAndHalt()
        {
            var workerSequences = WorkerSequences;

            while (_ringBuffer.Cursor > Util.GetMinimumSequence(workerSequences))
            {
                Thread.Sleep(0);
            }

            for (int i = 0; i < _workProcessors.Length; i++)
            {
                var workProcessor = _workProcessors[i];
                workProcessor.Halt();
            }

            _started.Value = false;
        }
        /// <summary>
        /// Is there available capacity in the buffer for the requested sequence.
        /// </summary>
        /// <param name="availableCapacity">availableCapacity remaining in the buffer.</param>
        /// <param name="dependentSequences">dependentSequences to be checked for range.</param>
        /// <returns>true if the buffer has capacity for the requested sequence.</returns>
        public bool HasAvailableCapacity(int availableCapacity, Sequence[] dependentSequences)
        {
            long wrapPoint = (_claimSequence.ReadUnfenced() + availableCapacity) - _bufferSize;

            if (wrapPoint > _minGatingSequence.ReadUnfenced())
            {
                long minSequence = Util.GetMinimumSequence(dependentSequences);
                _minGatingSequence.WriteUnfenced(minSequence);

                if (wrapPoint > minSequence)
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 28
0
        private bool HasAvailableCapacity(ISequence[] gatingSequences, int requiredCapacity, long cursorValue)
        {
            var wrapPoint            = (cursorValue + requiredCapacity) - _bufferSize;
            var cachedGatingSequence = _gatingSequenceCache.Value;

            if (wrapPoint > cachedGatingSequence || cachedGatingSequence > cursorValue)
            {
                long minSequence = Util.GetMinimumSequence(gatingSequences, cursorValue);
                _gatingSequenceCache.SetValue(minSequence);

                if (wrapPoint > minSequence)
                {
                    return(false);
                }
            }

            return(true);
        }
        private bool HasAvailableCapacity(long sequence, int availableCapacity, Sequence[] dependentSequences)
        {
            long        wrapPoint         = (sequence + availableCapacity) - _bufferSize;
            MutableLong minGatingSequence = _minGatingSequenceThreadLocal.Value;

            if (wrapPoint > minGatingSequence.Value)
            {
                long minSequence = Util.GetMinimumSequence(dependentSequences);
                minGatingSequence.Value = minSequence;

                if (wrapPoint > minSequence)
                {
                    return(false);
                }
            }

            return(true);
        }
        private bool HasAvailableCapacity(Sequence[] gatingSequences, int requiredCapacity, long cursorValue)
        {
            var wrapPoint            = (cursorValue + requiredCapacity) - bufferSize;
            var cachedGatingSequence = gatingSequenceCache.Value;

            if (wrapPoint > cachedGatingSequence || cachedGatingSequence > cursorValue)
            {
                var minSequence = Util.GetMinimumSequence(sequencesRef.ReadFullFence(), cursorValue);
                gatingSequenceCache.Value = minSequence;

                if (wrapPoint > minSequence)
                {
                    return(false);
                }
            }

            return(true);
        }