예제 #1
0
        private ReadOnlySequence <byte> ConcactSequence(ref ReadOnlySequence <byte> first, ref ReadOnlySequence <byte> second)
        {
            SequenceSegment head = first.Start.GetObject() as SequenceSegment;
            SequenceSegment tail = first.End.GetObject() as SequenceSegment;

            if (head == null)
            {
                foreach (var segment in first)
                {
                    if (head == null)
                    {
                        tail = head = SequenceSegment.CopyFrom(segment);
                    }
                    else
                    {
                        tail = tail.SetNext(SequenceSegment.CopyFrom(segment));
                    }
                }
            }

            if (!second.IsEmpty)
            {
                foreach (var segment in second)
                {
                    tail = tail.SetNext(SequenceSegment.CopyFrom(segment));
                }
            }

            return(new ReadOnlySequence <byte>(head, 0, tail, tail.Memory.Length));
        }
예제 #2
0
        public void GlobalSetup()
        {
            var sb = new StringBuilder();

            for (var i = 0; i < S; i++)
            {
                while (true)
                {
                    sb.Append(Guid.NewGuid().ToString().Replace("-", string.Empty));

                    if (sb.Length >= N)
                    {
                        var data = _encoding.GetBytes(sb.ToString(0, N));

                        var segment = new SequenceSegment(data, data.Length);

                        if (_head == null)
                        {
                            _tail = _head = segment;
                        }
                        else
                        {
                            _tail = _tail.SetNext(segment);
                        }

                        sb.Clear();
                        break;
                    }
                }
            }
        }
예제 #3
0
        public SequenceBuffer(int length)
        {
            var bytes = this.GetBuffer(length);

            this.startSegment = new SequenceSegment <byte>(bytes);
            this.sequence     = new ReadOnlySequence <byte>(this.startSegment, 0, this.startSegment, this.startSegment.Memory.Length);
        }
예제 #4
0
    private void MoveNext()
    {
        var firstSegment = _firstSegment;

        _firstSegmentStartIndex += (int)_jsonReader.BytesConsumed;
        // release previous segments if possible
        if (!_keepBuffers)
        {
            while (firstSegment?.Memory.Length <= _firstSegmentStartIndex)
            {
                _firstSegmentStartIndex -= firstSegment.Memory.Length;
                firstSegment.Dispose();
                firstSegment = (SequenceSegment?)firstSegment.Next;
            }
        }
        // create new segment
        var newSegment = new SequenceSegment(_bufferSize, _lastSegment);

        if (firstSegment != null)
        {
            _firstSegment       = firstSegment;
            newSegment.Previous = _lastSegment;
            _lastSegment?.SetNext(newSegment);
            _lastSegment = newSegment;
        }
        else
        {
            _firstSegment           = _lastSegment = newSegment;
            _firstSegmentStartIndex = 0;
        }
        // read data from stream
        _lastSegmentEndIndex = _stream.Read(newSegment.Buffer.Memory.Span);
        _isFinalBlock        = _lastSegmentEndIndex < newSegment.Buffer.Memory.Length;
        _jsonReader          = new Utf8JsonReader(new ReadOnlySequence <byte>(_firstSegment, _firstSegmentStartIndex, _lastSegment, _lastSegmentEndIndex), _isFinalBlock, _jsonReader.CurrentState);
    }
예제 #5
0
        /// <summary>
        /// Advances the sequence to include the specified number of elements initialized into memory
        /// returned by a prior call to <see cref="GetMemory(int)"/>.
        /// </summary>
        /// <param name="count">The number of elements written into memory.</param>
        public void Advance(int count)
        {
            SequenceSegment last = this.last;

            Debug.Assert(last != null, "Cannot advance before acquiring memory.");
            last.Advance(count);
        }
예제 #6
0
        /// <summary>
        /// Advances the sequence to include the specified number of elements initialized into memory
        /// returned by a prior call to <see cref="GetMemory(int)"/>.
        /// </summary>
        /// <param name="count">The number of elements written into memory.</param>
        public void Advance(int count)
        {
            SequenceSegment last = this.last;

            Verify.Operation(last != null, "Cannot advance before acquiring memory.");
            last.Advance(count);
        }
예제 #7
0
        /// <summary>
        /// Advances the sequence to include the specified number of elements initialized into memory
        /// returned by a prior call to <see cref="GetMemory(int)"/>.
        /// </summary>
        /// <param name="count">The number of elements written into memory.</param>
        public void Advance(int count)
        {
            SequenceSegment last = this.last;

            Verify.Operation(last != null, "Cannot advance before acquiring memory.");
            last.Advance(count);
            this.ConsiderMinimumSizeIncrease();
        }
예제 #8
0
 private SequenceSegment RecycleAndGetNext(SequenceSegment segment)
 {
     Sequence <T> .SequenceSegment recycledSegment = segment;
     Sequence <T> .SequenceSegment nextSegment     = segment.Next;
     recycledSegment.ResetMemory(this.arrayPool);
     this.segmentPool.Push(recycledSegment);
     return(nextSegment);
 }
예제 #9
0
        private SequenceSegment RecycleAndGetNext(SequenceSegment segment)
        {
            var recycledSegment = segment;

            segment = segment.Next;
            recycledSegment.ResetMemory();
            this.segmentPool.Push(recycledSegment);
            return(segment);
        }
 public bool DeleteSequenceSegment(SequenceSegment sequencesegment)
 {
     if (_sequenceSegments.ContainsKey(sequencesegment.TrackSolutionID) &&
         _sequenceSegments[sequencesegment.TrackSolutionID].ContainsKey(sequencesegment.ID))
     {
         return(NativeMethods.mta_sequencesegment_delete(_nativeHandle, sequencesegment.ID));
     }
     return(false);
 }
예제 #11
0
            public SequenceSegment(int size, SequenceSegment previous)
            {
                Buffer = MemoryPool <byte> .Shared.Rent(size);

                Previous = previous;

                Memory       = Buffer.Memory;
                RunningIndex = previous?.RunningIndex + previous?.Memory.Length ?? 0;
            }
예제 #12
0
        /// <summary>
        /// Returns a string which represents specified SequenceSegment.
        /// </summary>
        /// <param name="segment">SequenceSegment instance.</param>
        /// <returns>Returns string.</returns>
        public static string GetSequenceSegment(SequenceSegment segment)
        {
            if (segment == null)
            {
                throw new ArgumentNullException("segment");
            }

            return(segment.Current.ToString(CultureInfo.InvariantCulture) + SegmentDelim + segment.Count.ToString(CultureInfo.InvariantCulture));
        }
예제 #13
0
        /// <summary>
        /// Clears the entire sequence and recycles associated memory into pools.
        /// This invalidates any <see cref="ReadOnlySequence{T}"/> previously produced by this instance.
        /// </summary>
        public void Reset()
        {
            Sequence <T> .SequenceSegment current = this.first;
            while (current != null)
            {
                current = this.RecycleAndGetNext(current);
            }

            this.first = this.last = null;
        }
예제 #14
0
        /// <summary>
        /// Clears the entire sequence and recycles associated memory into pools.
        /// This invalidates any <see cref="ReadOnlySequence{T}"/> previously produced by this instance.
        /// </summary>
        public void Reset()
        {
            var current = this.first;

            while (current != null)
            {
                current = this.RecycleAndGetNext(current);
            }

            this.first = this.last = null;
        }
예제 #15
0
        public new async ValueTask SendAsync(ReadOnlyMemory <byte> data)
        {
            var package = new WebSocketPackage();

            package.OpCode = OpCode.Binary;

            var sequenceElement = new SequenceSegment(data);

            package.Data = new ReadOnlySequence <byte>(sequenceElement, 0, sequenceElement, sequenceElement.Memory.Length);

            await SendAsync(_packageEncoder, package);
        }
 /// <summary>
 /// Request a modifier to change a SequenceSegment configuration
 /// </summary>
 /// <param name="sequencesegment">
 /// Instance to be updated/changed
 /// </param>
 /// <exception cref="MylapsException">
 /// Throws an exception whenever it failes to create a SequenceSegmentModifier instance
 /// </exception>
 /// <remarks>
 /// To commit the changes, use MTA.CommitChanges()
 /// </remarks>
 public SequenceSegmentModifier UpdateSequenceSegment(SequenceSegment sequencesegment)
 {
     if (_sequenceSegments.ContainsKey(sequencesegment.TrackSolutionID) &&
         _sequenceSegments[sequencesegment.TrackSolutionID].ContainsKey(sequencesegment.ID))
     {
         var p = NativeMethods.mta_sequencesegment_update(_nativeHandle, sequencesegment.ID);
         return(AddSequenceSegmentModifier(p));
     }
     throw new MylapsException("failed to create a SequenceSegmentModifier, sequencesegment ID:" +
                               sequencesegment.ID + " in tracksolution ID:" + sequencesegment.TrackSolutionID +
                               " is unknown");
 }
        public void TryParseFrame_ShouldReturnTrue_OnTwoCompleteMessage()
        {
            var firstFrame    = _createMessage(150);
            var secondFrame   = _createMessage(160);
            var firstSegment  = new SequenceSegment(firstFrame);
            var secondSegment = firstSegment.Add(secondFrame);

            var fullFrame = new ReadOnlySequence <byte>(
                firstSegment, 0,
                secondSegment, 8);

            Assert.True(_frameParser.TryParseFrame(ref fullFrame, out var firstMessage));
            Assert.True(_frameParser.TryParseFrame(ref fullFrame, out var secondMessage));
        }
예제 #18
0
        public Utf8JsonStreamReader(Stream stream, int bufferSize)
        {
            _stream     = stream;
            _bufferSize = bufferSize;

            _firstSegment           = null;
            _firstSegmentStartIndex = 0;
            _lastSegment            = null;
            _lastSegmentEndIndex    = -1;

            _jsonReader   = default;
            _keepBuffers  = false;
            _isFinalBlock = false;
        }
예제 #19
0
            /// <summary>
            /// Removes all elements from the sequence from its beginning to the specified position,
            /// considering that data to have been fully processed.
            /// </summary>
            /// <param name="position">
            /// The position of the first element that has not yet been processed.
            /// This is typically <see cref="ReadOnlySequence{T}.End"/> after reading all elements from that instance.
            /// </param>
            public void AdvanceTo(SequencePosition position)
            {
                var firstSegment = (SequenceSegment)position.GetObject();
                int firstIndex   = position.GetInteger();

                // Before making any mutations, confirm that the block specified belongs to this sequence.
                var current = this.first;

                while (current != firstSegment && current != null)
                {
                    current = current.Next;
                }

                if (current == null)
                {
                    ThrowCurrentNull();
                }
                void ThrowCurrentNull() => throw new ArgumentException("Position does not represent a valid position in this sequence.", nameof(position));

                // Also confirm that the position is not a prior position in the block.
                if (firstIndex < current.Start)
                {
                    ThrowEarlierPosition();
                }
                void ThrowEarlierPosition() => throw new ArgumentException("Position must not be earlier than current position.", nameof(position));

                // Now repeat the loop, performing the mutations.
                current = this.first;
                while (current != firstSegment)
                {
                    var next = current.Next;
                    current.ResetMemory();
                    current = next;
                }

                firstSegment.AdvanceTo(firstIndex);

                if (firstSegment.Length == 0)
                {
                    firstSegment = this.RecycleAndGetNext(firstSegment);
                }

                this.first = firstSegment;

                if (this.first == null)
                {
                    this.last = null;
                }
            }
예제 #20
0
    private void MoveNext()
    {
        _firstSegmentStartIndex += (int)_jsonReader.BytesConsumed;

        // release previous segments if possible
        while (_firstSegmentStartIndex > 0 && _firstSegment?.Memory.Length <= _firstSegmentStartIndex)
        {
            var currFirstSegment = _firstSegment;
            _firstSegmentStartIndex -= _firstSegment.Memory.Length;
            _firstSegment            = (SequenceSegment?)_firstSegment.Next;
            if (!_keepBuffers)
            {
                currFirstSegment.Dispose();
            }
        }

        // create new segment
        var newSegment = new SequenceSegment(_bufferSize, _lastSegment);

        _lastSegment?.SetNext(newSegment);
        _lastSegment = newSegment;

        if (_firstSegment == null)
        {
            _firstSegment           = newSegment;
            _firstSegmentStartIndex = 0;
        }

        // read data from stream
        _lastSegmentEndIndex = 0;
        int bytesRead;

        do
        {
#if NET
            bytesRead = _stream.Read(newSegment.Buffer.Memory.Span.Slice(_lastSegmentEndIndex));
#else
            var bytes = newSegment.Buffer.Memory.Span.Slice(_lastSegmentEndIndex).ToArray();
            bytesRead = _stream.Read(bytes, 0, bytes.Length);
#endif
            _lastSegmentEndIndex += bytesRead;
        } while (bytesRead > 0 && _lastSegmentEndIndex < newSegment.Buffer.Memory.Length);
        _isFinalBlock = _lastSegmentEndIndex < newSegment.Buffer.Memory.Length;
        var data = new ReadOnlySequence <byte>(_firstSegment, _firstSegmentStartIndex, _lastSegment,
                                               _lastSegmentEndIndex);
        _jsonReader =
            new Utf8JsonReader(data, _isFinalBlock, _jsonReader.CurrentState);
    }
예제 #21
0
        internal void ConcatSequence(ref ReadOnlySequence <byte> second)
        {
            if (Head == null)
            {
                (Head, Tail) = second.DestructSequence();
                return;
            }

            if (!second.IsEmpty)
            {
                foreach (var segment in second)
                {
                    Tail = Tail.SetNext(new SequenceSegment(segment));
                }
            }
        }
예제 #22
0
            private void Append(IMemoryOwner <T> array)
            {
                if (array == null)
                {
                    ThrowNull();
                }

                var segment = this.segmentPool.Count > 0 ? this.segmentPool.Pop() : new SequenceSegment();

                segment.SetMemory(array, 0, 0);

                if (this.last == null)
                {
                    this.first = this.last = segment;
                }
                else
                {
                    if (this.last.Length > 0)
                    {
                        // Add a new block.
                        this.last.SetNext(segment);
                    }
                    else
                    {
                        // The last block is completely unused. Replace it instead of appending to it.
                        var current = this.first;
                        if (this.first != this.last)
                        {
                            while (current.Next != this.last)
                            {
                                current = current.Next;
                            }
                        }
                        else
                        {
                            this.first = segment;
                        }

                        current.SetNext(segment);
                        this.RecycleAndGetNext(this.last);
                    }

                    this.last = segment;
                }

                void ThrowNull() => throw new ArgumentNullException(nameof(array));
            }
예제 #23
0
        internal void ConcatSequence(ref ReadOnlySequence <byte> second)
        {
            if (Head == null)
            {
                (Head, Tail) = second.DestructSequence();
                Console.WriteLine($"Reset Head:{this.GetHashCode()}");
                return;
            }

            if (!second.IsEmpty)
            {
                foreach (var segment in second)
                {
                    Tail = Tail.SetNext(new SequenceSegment(segment));
                }
            }
        }
예제 #24
0
        /// <summary>
        /// Removes all elements from the sequence from its beginning to the specified position,
        /// considering that data to have been fully processed.
        /// </summary>
        /// <param name="position">
        /// The position of the first element that has not yet been processed.
        /// This is typically <see cref="ReadOnlySequence{T}.End"/> after reading all elements from that instance.
        /// </param>
        public void AdvanceTo(SequencePosition position)
        {
            var firstSegment = (SequenceSegment)position.GetObject();

            if (firstSegment == null)
            {
                // Emulate PipeReader behavior which is to just return for default(SequencePosition)
                return;
            }

            if (ReferenceEquals(firstSegment, SequenceSegment.Empty) && this.Length == 0)
            {
                // We were called with our own empty buffer segment.
                return;
            }

            int firstIndex = position.GetInteger();

            // Before making any mutations, confirm that the block specified belongs to this sequence.
            Sequence <T> .SequenceSegment current = this.first;
            while (current != firstSegment && current != null)
            {
                current = current.Next;
            }

            Requires.Argument(current != null, nameof(position), "Position does not represent a valid position in this sequence.");

            // Also confirm that the position is not a prior position in the block.
            Requires.Argument(firstIndex >= current.Start, nameof(position), "Position must not be earlier than current position.");

            // Now repeat the loop, performing the mutations.
            current = this.first;
            while (current != firstSegment)
            {
                current = this.RecycleAndGetNext(current);
            }

            firstSegment.AdvanceTo(firstIndex);

            this.first = firstSegment.Length == 0 ? this.RecycleAndGetNext(firstSegment) : firstSegment;

            if (this.first == null)
            {
                this.last = null;
            }
        }
        private void NotifySequenceSegments(IntPtr handle, MDP_NOTIFY_TYPE nType, IntPtr sequencsegmentearray, uint count, IntPtr context)
        {
            var sequenceSegments = SequenceSegment.FromNativePointerArray(sequencsegmentearray, count, _mta);

            switch (nType)
            {
            case MDP_NOTIFY_TYPE.MDP_NOTIFY_SELECT:
            case MDP_NOTIFY_TYPE.MDP_NOTIFY_INSERT:
            case MDP_NOTIFY_TYPE.MDP_NOTIFY_UPDATE:
                sequenceSegments.ForEach(sequenceSegment =>
                {
                    if (!_sequenceSegments.ContainsKey(sequenceSegment.TrackSolutionID))
                    {
                        _sequenceSegments[sequenceSegment.TrackSolutionID] = new SortedDictionary <uint, SequenceSegment>();
                    }
                    _sequenceSegments[sequenceSegment.TrackSolutionID][sequenceSegment.ID] = sequenceSegment;
                });
                _allSequenceSegmentDataAvailable = true;
                break;

            case MDP_NOTIFY_TYPE.MDP_NOTIFY_DELETE:
                sequenceSegments.ForEach(sequenceSegment =>
                {
                    if (_sequenceSegments.ContainsKey(sequenceSegment.TrackSolutionID))
                    {
                        _sequenceSegments[sequenceSegment.TrackSolutionID].Remove(sequenceSegment.ID);
                        if (_sequenceSegments[sequenceSegment.TrackSolutionID].Count == 0)
                        {
                            _sequenceSegments.Remove(sequenceSegment.TrackSolutionID);
                        }
                    }
                });
                break;

            case MDP_NOTIFY_TYPE.MDP_NOTIFY_CLEAR:
                _allSequenceSegmentDataAvailable = false;
                _sequenceSegments.Clear();
                break;
            }

            if (NotifySequenceSegmentHandlers != null)
            {
                NotifySequenceSegmentHandlers(nType, sequenceSegments, _mta);
            }
        }
예제 #26
0
        public void TryRead_ShouldReturnTrue_OnSegmentSplitted()
        {
            var buffer        = _createBuffer();
            var firstSegment  = new SequenceSegment(buffer.Slice(0, 4));
            var secondSegment = firstSegment.Add(buffer.Slice(4, 4));

            var input = new ReadOnlySequence <byte>(
                firstSegment, 0,
                secondSegment, 4);

            var reader = new SequenceReader(input);

            reader.TryRead(BinaryPrimitives.ReadInt32LittleEndian, out var firstValue);
            reader.TryRead(BinaryPrimitives.ReadInt32LittleEndian, out var secondValue);

            Assert.Equal(_firstValue, firstValue);
            Assert.Equal(_secondValue, secondValue);
        }
예제 #27
0
        public void Decode(WebSocketPackage package)
        {
            if (!package.RSV1)
            {
                return;
            }

            var data = package.Data;

            data = data.ConcatSequence(new SequenceSegment(LAST_FOUR_OCTETS_REVERSE, LAST_FOUR_OCTETS_REVERSE.Length, false));

            SequenceSegment head = null;
            SequenceSegment tail = null;

            using (var stream = new DeflateStream(new ReadOnlySequenceStream(data), CompressionMode.Decompress))
            {
                while (true)
                {
                    var buffer = _arrayPool.Rent(_deflateBufferSize);
                    var read   = stream.Read(buffer, 0, buffer.Length);

                    if (read == 0)
                    {
                        break;
                    }

                    var segment = new SequenceSegment(buffer, read);

                    if (head == null)
                    {
                        tail = head = segment;
                    }
                    else
                    {
                        tail.SetNext(segment);
                    }
                }
            }

            package.Data = new ReadOnlySequence <byte>(head, 0, tail, tail.Memory.Length);
        }
예제 #28
0
        private void Append(SequenceSegment segment)
        {
            if (this.last == null)
            {
                this.first = this.last = segment;
            }
            else
            {
                if (this.last.Length > 0)
                {
                    // Add a new block.
                    this.last.SetNext(segment);
                }
                else
                {
                    // The last block is completely unused. Replace it instead of appending to it.
                    var current = this.first;
                    if (current is null)
                    {
                        throw new NullReferenceException(nameof(this.first));
                    }

                    if (this.first != this.last)
                    {
                        while (current.Next != this.last)
                        {
                            current = current.Next;
                        }
                    }
                    else
                    {
                        this.first = segment;
                    }

                    current.SetNext(segment);
                    this.RecycleAndGetNext(this.last);
                }

                this.last = segment;
            }
        }
예제 #29
0
        private ReadOnlySequence <byte> CopySequence(ref ReadOnlySequence <byte> seq)
        {
            SequenceSegment head = null;
            SequenceSegment tail = null;

            foreach (var segment in seq)
            {
                var newSegment = SequenceSegment.CopyFrom(segment);

                if (head == null)
                {
                    tail = head = newSegment;
                }
                else
                {
                    tail = tail.SetNext(newSegment);
                }
            }

            return(new ReadOnlySequence <byte>(head, 0, tail, tail.Memory.Length));
        }
예제 #30
0
        private void DeserialisePost()
        {
            // release memory if possible
            var firstSegment           = _firstSegment;
            var firstSegmentStartIndex = _firstSegmentStartIndex + (int)_jsonReader.BytesConsumed;

            while (firstSegment?.Memory.Length < firstSegmentStartIndex)
            {
                firstSegmentStartIndex -= firstSegment.Memory.Length;
                firstSegment.Dispose();
                firstSegment = (SequenceSegment)firstSegment.Next;
            }

            if (firstSegment != _firstSegment)
            {
                _firstSegment           = firstSegment;
                _firstSegmentStartIndex = firstSegmentStartIndex;
                var data = new ReadOnlySequence <byte>(_firstSegment, _firstSegmentStartIndex, _lastSegment, _lastSegmentEndIndex);
                _jsonReader = new Utf8JsonReader(data, _isFinalBlock, _jsonReader.CurrentState);
            }
        }