Пример #1
0
        private ReadableBuffer(ref ReadableBuffer buffer)
        {
            var begin = buffer._start;
            var end   = buffer._end;

            BufferSegment segmentTail;
            var           segmentHead = BufferSegment.Clone(begin, end, out segmentTail);

            begin = new ReadCursor(segmentHead);
            end   = new ReadCursor(segmentTail, segmentTail.End);

            _start   = begin;
            _end     = end;
            _isOwner = true;
            _first   = buffer._first;

            _length = buffer._length;
        }
Пример #2
0
        public ReadableBuffer Clone()
        {
            var begin = _start;
            var end   = _end;

            var segmentHead = MemoryBlockSegment.Clone(begin, end);
            var segmentTail = segmentHead;

            while (segmentTail.Next != null)
            {
                segmentTail = segmentTail.Next;
            }

            begin = new ReadCursor(segmentHead);
            end   = new ReadCursor(segmentTail, segmentTail.End);

            return(new ReadableBuffer(_channel, begin, end, isOwner: true));
        }
Пример #3
0
        private ReadableBuffer Read()
        {
            // CompareExchange not required as its setting to current value if test fails
            if (Interlocked.Exchange(ref _consumingState, State.Active) != State.NotActive)
            {
                throw new InvalidOperationException("Already consuming.");
            }

            ReadCursor readEnd;

            // Reading commit head shared with writer
            lock (_sync)
            {
                readEnd = new ReadCursor(_commitHead, _commitHeadIndex);
            }

            return(new ReadableBuffer(new ReadCursor(_readHead), readEnd));
        }
Пример #4
0
        private ReadableBuffer(ref ReadableBuffer buffer)
        {
            var begin = buffer._start;
            var end   = buffer._end;

            BufferSegment segmentTail;
            var           segmentHead = BufferSegment.Clone(begin, end, out segmentTail);

            begin = new ReadCursor(segmentHead);
            end   = new ReadCursor(segmentTail, segmentTail.End);

            _start = begin;
            _end   = end;

            _length = buffer._length;

            begin.TryGetBuffer(end, out _first, out begin);
        }
Пример #5
0
        public void AdvanceReader(ReadCursor consumed, ReadCursor examined)
        {
            BufferSegment returnStart = null;
            BufferSegment returnEnd   = null;

            if (!consumed.IsDefault)
            {
                returnStart     = _readHead;
                returnEnd       = consumed.Segment;
                _readHead       = consumed.Segment;
                _readHead.Start = consumed.Index;
            }

            // Reading commit head shared with writer
            lock (_sync)
            {
                if (!examined.IsDefault &&
                    examined.Segment == _commitHead &&
                    examined.Index == _commitHeadIndex &&
                    Reading.Status == TaskStatus.WaitingForActivation)
                {
                    Interlocked.CompareExchange(
                        ref _awaitableState,
                        _awaitableIsNotCompleted,
                        _awaitableIsCompleted);
                }
            }

            while (returnStart != returnEnd)
            {
                var returnSegment = returnStart;
                returnStart = returnStart.Next;
                returnSegment.Dispose();
            }

#if DEBUG
            _consumingLocation = null;
#endif
            // CompareExchange not required as its setting to current value if test fails
            if (Interlocked.Exchange(ref _consumingState, State.NotActive) != State.Active)
            {
                ThrowHelper.ThrowInvalidOperationException(ExceptionResource.NotConsumingToComplete);
            }
        }
Пример #6
0
        private ReadableBuffer(ref ReadableBuffer buffer)
        {
            _channel = buffer._channel;

            var begin = buffer._start;
            var end   = buffer._end;

            MemoryBlockSegment segmentTail;
            var segmentHead = MemoryBlockSegment.Clone(begin, end, out segmentTail);

            begin = new ReadCursor(segmentHead);
            end   = new ReadCursor(segmentTail, segmentTail.End);

            _start   = begin;
            _end     = end;
            _isOwner = true;
            _span    = buffer._span;

            _length = buffer._length;
        }
Пример #7
0
        public void EndRead(
            ReadCursor consumed,
            ReadCursor examined)
        {
            MemoryBlockSegment returnStart = null;
            MemoryBlockSegment returnEnd   = null;

            lock (_sync)
            {
                if (!consumed.IsDefault)
                {
                    returnStart = _head;
                    returnEnd   = consumed.Segment;
                    _head       = consumed.Segment;
                    _head.Start = consumed.Index;
                }

                if (!examined.IsDefault &&
                    examined.IsEnd &&
                    Completion.Status == TaskStatus.WaitingForActivation)
                {
                    Interlocked.CompareExchange(
                        ref _awaitableState,
                        _awaitableIsNotCompleted,
                        _awaitableIsCompleted);
                }
            }

            while (returnStart != returnEnd)
            {
                var returnSegment = returnStart;
                returnStart = returnStart.Next;
                returnSegment.Dispose();
            }

            if (Interlocked.CompareExchange(ref _consumingState, 0, 1) != 1)
            {
                throw new InvalidOperationException("No ongoing consuming operation to complete.");
            }
        }
Пример #8
0
 internal void ClearCursors()
 {
     _start = default(ReadCursor);
     _end   = default(ReadCursor);
 }
Пример #9
0
 public void Consumed(ReadCursor consumed)
 {
     _channel.EndRead(consumed, consumed);
 }
Пример #10
0
 /// <summary>
 /// Forms a slice out of the given <see cref="ReadableBuffer"/>, beginning at 'start', and is at most length bytes
 /// </summary>
 /// <param name="start">The starting (inclusive) <see cref="ReadCursor"/> at which to begin this slice.</param>
 /// <param name="length">The length of the slice</param>
 public ReadableBuffer Slice(ReadCursor start, int length)
 {
     return(Slice(start, start.Seek(length)));
 }
Пример #11
0
 /// <summary>
 /// Forms a slice out of the given <see cref="ReadableBuffer"/>, beginning at 'start', ending at the existing <see cref="ReadableBuffer"/>'s end.
 /// </summary>
 /// <param name="start">The starting (inclusive) <see cref="ReadCursor"/> at which to begin this slice.</param>
 public ReadableBuffer Slice(ReadCursor start)
 {
     return(new ReadableBuffer(start, _end));
 }
Пример #12
0
        /// <summary>
        /// Searches for a byte in the <see cref="ReadableBuffer"/> and returns a sliced <see cref="ReadableBuffer"/> that
        /// contains all data up to and excluding the byte, and a <see cref="ReadCursor"/> that points to the byte.
        /// </summary>
        /// <param name="b1">The first byte to search for</param>
        /// <param name="slice">A <see cref="ReadableBuffer"/> slice that contains all data up to and excluding the first byte.</param>
        /// <param name="cursor">A <see cref="ReadCursor"/> that points to the second byte</param>
        /// <returns>True if the byte sequence was found, false if not found</returns>
        public bool TrySliceTo(byte b1, out ReadableBuffer slice, out ReadCursor cursor)
        {
            if (IsEmpty)
            {
                slice  = default(ReadableBuffer);
                cursor = default(ReadCursor);
                return(false);
            }

            var byte0Vector = CommonVectors.GetVector(b1);

            var seek = 0;

            foreach (var memory in this)
            {
                var currentSpan = memory.Span;
                var found       = false;

                if (Vector.IsHardwareAccelerated)
                {
                    while (currentSpan.Length >= VectorWidth)
                    {
                        var data        = currentSpan.Read <Vector <byte> >();
                        var byte0Equals = Vector.Equals(data, byte0Vector);

                        if (byte0Equals.Equals(Vector <byte> .Zero))
                        {
                            currentSpan = currentSpan.Slice(VectorWidth);
                            seek       += VectorWidth;
                        }
                        else
                        {
                            var index = FindFirstEqualByte(ref byte0Equals);
                            seek += index;
                            found = true;
                            break;
                        }
                    }
                }

                if (!found)
                {
                    // Slow search
                    for (int i = 0; i < currentSpan.Length; i++)
                    {
                        if (currentSpan[i] == b1)
                        {
                            found = true;
                            break;
                        }
                        seek++;
                    }
                }

                if (found)
                {
                    cursor = _start.Seek(seek);
                    slice  = Slice(_start, cursor);
                    return(true);
                }
            }

            slice  = default(ReadableBuffer);
            cursor = default(ReadCursor);
            return(false);
        }
Пример #13
0
 /// <summary>
 /// Forms a slice out of the given <see cref="ReadableBuffer"/>, beginning at 'start', ending at 'end' (inclusive).
 /// </summary>
 /// <param name="start">The index at which to begin this slice.</param>
 /// <param name="end">The end (inclusive) of the slice</param>
 public ReadableBuffer Slice(int start, ReadCursor end)
 {
     return(Slice(_start.Seek(start), end));
 }
Пример #14
0
 internal ReadableBuffer(Channel channel, ReadCursor start, ReadCursor end) :
     this(channel, start, end, isOwner : false)
 {
 }
Пример #15
0
 public static void Advance(this IReadableChannel input, ReadCursor cursor)
 {
     input.Advance(cursor, cursor);
 }
Пример #16
0
 /// <summary>
 /// Moves forward the channels read cursor to after the consumed data.
 /// </summary>
 /// <param name="consumed">Marks the extent of the data that has been succesfully proceesed.</param>
 /// <param name="examined">Marks the extent of the data that has been read and examined.</param>
 /// <remarks>
 /// The memory for the consumed data will be released and no longer available.
 /// The examined data communicates to the channel when it should signal more data is available.
 /// </remarks>
 public void Advance(ReadCursor consumed, ReadCursor examined) => _channel.AdvanceReader(consumed, examined);
Пример #17
0
 public void EndRead(ReadCursor end)
 {
     EndRead(end, end);
 }
Пример #18
0
 public ReadableBuffer Slice(ReadCursor start, ReadCursor end)
 {
     return(new ReadableBuffer(_channel, start, end));
 }
Пример #19
0
 internal void EndRead(ReadCursor end)
 {
     EndRead(end, end);
 }
Пример #20
0
 void IReadableChannel.Advance(ReadCursor consumed, ReadCursor examined) => AdvanceReader(consumed, examined);
Пример #21
0
 public void Consumed(ReadCursor consumed, ReadCursor examined)
 {
     _channel.EndRead(consumed, examined);
 }
Пример #22
0
 internal ReadableBuffer(ReadCursor start, ReadCursor end) :
     this(start, end, isOwner : false)
 {
 }