public override long GetRemainingCapacity() { long consumed = SequenceGroupManager.GetMinimumSequence(GatingSequences, Cursor.GetValue()); long produced = Cursor.GetValue(); return(BufferSize - (produced - consumed)); }
public override long Next(int n) { if (n < 1) { throw new ArgumentException($"{nameof(n)} must greater than 1."); } long nextValue = NextValue; long nextSequence = nextValue + n; long wrapPoint = nextSequence - BufferSize; long cachedGatingSequence = CachedValue; if (wrapPoint > cachedGatingSequence || cachedGatingSequence > nextValue) { Cursor.SetVolatileValue(nextValue); // StoreLoad fence long minSequence; var spinWait = default(AggressiveSpinWait); while (wrapPoint > (minSequence = SequenceGroupManager.GetMinimumSequence(GatingSequences, nextValue))) { // Use waitStrategy to spin? spinWait.SpinOnce(); } CachedValue = minSequence; } NextValue = nextSequence; return(nextSequence); }
/// <summary> /// Create a group of event processors to be used as a dependency. /// </summary> /// <param name="processors">the event processors, previously set up with <see cref="HandleEventsWith(Disruptor.IEventProcessor[]) "/>, that will form the barrier for subsequent handlers or processors.</param> /// <returns>an <see cref="EventHandlerGroup{T}"/> that can be used to setup a {@link SequenceBarrier} over the specified event processors.</returns> public EventHandlerGroup <T> After(params IEventProcessor[] processors) { foreach (var processor in processors) { _consumerRepository.Add(processor); } return(new EventHandlerGroup <T>(this, _consumerRepository, SequenceGroupManager.GetSequencesFor(processors))); }
public override long GetRemainingCapacity() { long nextValue = CachedValue; long consumed = SequenceGroupManager.GetMinimumSequence(GatingSequences, nextValue); long produced = nextValue; return(BufferSize - (produced - consumed)); }
/// <summary> /// Wait for the <see cref="RingBuffer{TEvent}"/> to drain of published events then halt the workers. /// </summary> public void DrainAndHalt() { var workerSequences = GetWorkerSequences(); while (_ringBuffer.GetCursor() > SequenceGroupManager.GetMinimumSequence(workerSequences)) { Thread.Yield(); } foreach (var processor in _workProcessors) { processor.Halt(); } _started = 0; }
private bool HasAvailableCapacity(ISequence[] gatingSequences, int requiredCapacity, long cursorValue) { long wrapPoint = (cursorValue + requiredCapacity) - BufferSize; long cachedGatingSequence = _gatingSequenceCache.GetValue(); if (wrapPoint > cachedGatingSequence || cachedGatingSequence > cursorValue) { long minSequence = SequenceGroupManager.GetMinimumSequence(gatingSequences, cursorValue); _gatingSequenceCache.SetValue(minSequence); if (wrapPoint > minSequence) { return(false); } } return(true); }
public override long Next(int n) { if (n < 1) { throw new ArgumentException($"{nameof(n)} must be > 0"); } long next; long current; var spinWait = default(AggressiveSpinWait); do { current = Cursor.GetValue(); next = current + n; var wrapPoint = next - BufferSize; var cachedGatingSequence = _gatingSequenceCache.GetValue(); if (wrapPoint > cachedGatingSequence || cachedGatingSequence > current) { var gatingSequence = SequenceGroupManager.GetMinimumSequence(GatingSequences, current); if (wrapPoint > gatingSequence) { //should we spin based on the wait strategy? spinWait.SpinOnce(); continue; } _gatingSequenceCache.SetValue(gatingSequence); } else if (Cursor.CompareAndSet(current, next)) { break; } } while (true); return(next); }
/// <summary> /// Set up custom event processors to handle events from the ring buffer. The Disruptor will automatically start these processors when <see cref="StartAsync"/> is called. /// </summary> /// <param name="processors">the event processors that will process events.</param> /// <returns>a <see cref="EventHandlerGroup{T}"/> that can be used to chain dependencies.</returns> public EventHandlerGroup <T> HandleEventsWith(params IEventProcessor[] processors) { if (processors == null) { return(null); } foreach (var processor in processors) { _consumerRepository.Add(processor); } var sequences = new ISequence[processors.Length]; for (var i = 0; i < processors.Length; i++) { sequences[i] = processors[i].GetSequence(); } _ringBuffer.AddGatingSequences(sequences); return(new EventHandlerGroup <T>(this, _consumerRepository, SequenceGroupManager.GetSequencesFor(processors))); }
private bool HasAvailableCapacity(int requiredCapacity, bool doStore) { var nextValue = NextValue; var wrapPoint = (nextValue + requiredCapacity) - BufferSize; var cachedGatingSequence = CachedValue; if (wrapPoint > cachedGatingSequence || cachedGatingSequence > nextValue) { if (doStore) { Cursor.SetVolatileValue(nextValue); // StoreLoad fence } long minSequence = SequenceGroupManager.GetMinimumSequence(GatingSequences, nextValue); CachedValue = minSequence; if (wrapPoint > minSequence) { return(false); } } return(true); }
public long GetMinimumSequence() { return(SequenceGroupManager.GetMinimumSequence(_sequences)); }
public bool Remove(ISequence sequence) { return(SequenceGroupManager.RemoveSequence(ref _sequences, sequence)); }
public void AddWhileRunning(ICursored cursored, ISequence sequence) { SequenceGroupManager.AddSequences(ref _sequences, cursored, sequence); }
public virtual bool RemoveGatingSequence(ISequence sequence) { return(SequenceGroupManager.RemoveSequence(ref GatingSequences, sequence)); }
public virtual long GetMinimumSequence() { return(SequenceGroupManager.GetMinimumSequence(GatingSequences, Cursor.GetValue())); }
public virtual void AddGatingSequences(params ISequence[] gatingSequences) { SequenceGroupManager.AddSequences(ref GatingSequences, this, gatingSequences); }