예제 #1
0
 public override void Return(OwnedMemory<byte> buffer)
 {
     var ownedArray = buffer as OwnedArray<byte>;
     if (ownedArray == null) throw new InvalidOperationException("buffer not rented from this pool");
     ArrayPool<byte>.Shared.Return(ownedArray.Array);
     buffer.Dispose();
 }
예제 #2
0
 internal JsonObject(ReadOnlySpan<byte> values, ReadOnlySpan<byte> db, BufferPool pool = null, OwnedMemory<byte> dbMemory = null)
 {
     _db = db;
     _values = values;
     _pool = pool;
     _dbMemory = dbMemory;
 }
예제 #3
0
        public BufferSegment(OwnedMemory<byte> buffer)
        {
            _buffer = buffer;
            Start = 0;
            End = 0;

            _buffer.AddReference();
        }
예제 #4
0
        public BufferSegment(OwnedMemory<byte> buffer, int start, int end)
        {
            _buffer = buffer;
            Start = start;
            End = end;
            ReadOnly = true;

            // For unowned buffers, we need to make a copy here so that the caller can 
            // give up the give this buffer back to the caller
            var unowned = buffer as UnownedBuffer;
            if (unowned != null)
            {
                _buffer = unowned.MakeCopy(start, end - start, out Start, out End);
            }

            _buffer.AddReference();
        }
예제 #5
0
 internal JsonObject(ReadOnlySpan <byte> values, ReadOnlySpan <byte> db, BufferPool pool = null, OwnedMemory <byte> dbMemory = null)
 {
     _db       = db;
     _values   = values;
     _pool     = pool;
     _dbMemory = dbMemory;
 }
예제 #6
0
 public static void ThrowArgumentValidationException <T>(OwnedMemory <T> ownedMemory, int start)
 => throw CreateArgumentValidationException(ownedMemory, start);
예제 #7
0
 internal ReadOnlyMemory(OwnedMemory <T> owner, long id)
     : this(owner, id, 0, owner.GetSpanInternal(id).Length)
 {
 }
예제 #8
0
 internal ReadOnlyMemory(OwnedMemory <T> owner, int index, int length)
 {
     _owner  = owner;
     _index  = index;
     _length = length;
 }
예제 #9
0
 private Memory(OwnedMemory <T> owner, int index, int length)
 {
     _owner  = owner;
     _index  = index;
     _length = length;
 }
예제 #10
0
파일: Memory.cs 프로젝트: nekresh/corefxlab
 internal Memory(OwnedMemory <T> owner, long id)
     : this(owner, id, 0, owner.GetSpan(id).Length)
 {
 }
예제 #11
0
        public JsonObject Parse(ReadOnlySpan<byte> utf8Json, BufferPool pool = null)
        {
            _pool = pool;
            if (_pool == null) _pool = ManagedBufferPool.Shared;
            _scratchManager = _pool.Rent(utf8Json.Length * 4);
            _scratchMemory = _scratchManager.Memory;

            int dbLength = _scratchMemory.Length / 2;
            _db = _scratchMemory.Slice(0, dbLength);
            _stack = new TwoStacks(_scratchMemory.Slice(dbLength));

            _values = utf8Json;
            _insideObject = 0;
            _insideArray = 0;
            _tokenType = 0;
            _valuesIndex = 0;
            _dbIndex = 0;
            _jsonStartIsObject = false;

            SkipWhitespace();

            _jsonStartIsObject = _values[_valuesIndex] == '{';

            int arrayItemsCount = 0;
            int numberOfRowsForMembers = 0;

            while (Read()) {
                var tokenType = _tokenType;
                switch (tokenType) {
                    case JsonTokenType.ObjectStart:
                        AppendDbRow(JsonObject.JsonValueType.Object, _valuesIndex);
                        while(!_stack.TryPushObject(numberOfRowsForMembers)) {
                            ResizeDb();
                        }
                        numberOfRowsForMembers = 0;
                        break;
                    case JsonTokenType.ObjectEnd:
                        _db.Span.Slice(FindLocation(_stack.ObjectStackCount - 1, true)).Write<int>(numberOfRowsForMembers);
                        numberOfRowsForMembers += _stack.PopObject();
                        break;
                    case JsonTokenType.ArrayStart:
                        AppendDbRow(JsonObject.JsonValueType.Array, _valuesIndex);
                        while (!_stack.TryPushArray(arrayItemsCount)) {
                            ResizeDb();
                        }
                        arrayItemsCount = 0;
                        break;
                    case JsonTokenType.ArrayEnd:
                        _db.Span.Slice(FindLocation(_stack.ArrayStackCount - 1, false)).Write<int>(arrayItemsCount);
                        arrayItemsCount += _stack.PopArray();
                        break;
                    case JsonTokenType.Property:
                        ParsePropertyName();
                        ParseValue();
                        numberOfRowsForMembers++;
                        numberOfRowsForMembers++;
                        break;
                    case JsonTokenType.Value:
                        ParseValue();
                        arrayItemsCount++;
                        numberOfRowsForMembers++;
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }

            var result =  new JsonObject(_values, _db.Slice(0, _dbIndex).Span, _pool, _scratchManager);
            _scratchManager = null;
            return result;
        }
예제 #12
0
 public void SetMemory(OwnedMemory <byte> buffer)
 {
     SetMemory(buffer, 0, 0);
 }
예제 #13
0
 /// <summary>
 /// Wraps a rented buffer and returns it to the shared pool on Dispose
 /// </summary>
 /// <param name="rentedBuffer">A buffer that was previously rented from the shared BufferPool</param>
 /// <param name="count"></param>
 public RentedBufferStream(OwnedMemory <byte> rentedBuffer, int count) : base(GetSegment(rentedBuffer).Array, 0, count)
 {
     _rentedBuffer = rentedBuffer;
 }
예제 #14
0
 public PooledMemory(OwnedMemory <byte> ownedMemory, TestMemoryPool pool)
 {
     _ownedMemory = ownedMemory;
     _pool        = pool;
     _leaser      = Environment.StackTrace;
 }
예제 #15
0
        public JsonObject Parse(ReadOnlySpan <byte> utf8Json, BufferPool pool = null)
        {
            _pool = pool;
            if (_pool == null)
            {
                _pool = ManagedBufferPool.Shared;
            }
            _scratchManager = _pool.Rent(utf8Json.Length * 4);
            _scratchMemory  = _scratchManager.Memory;

            int dbLength = _scratchMemory.Length / 2;

            _db    = _scratchMemory.Slice(0, dbLength);
            _stack = new TwoStacks(_scratchMemory.Slice(dbLength));

            _values            = utf8Json;
            _insideObject      = 0;
            _insideArray       = 0;
            _tokenType         = 0;
            _valuesIndex       = 0;
            _dbIndex           = 0;
            _jsonStartIsObject = false;

            SkipWhitespace();

            _jsonStartIsObject = _values[_valuesIndex] == '{';

            int arrayItemsCount        = 0;
            int numberOfRowsForMembers = 0;

            while (Read())
            {
                var tokenType = _tokenType;
                switch (tokenType)
                {
                case JsonTokenType.ObjectStart:
                    AppendDbRow(JsonObject.JsonValueType.Object, _valuesIndex);
                    while (!_stack.TryPushObject(numberOfRowsForMembers))
                    {
                        ResizeDb();
                    }
                    numberOfRowsForMembers = 0;
                    break;

                case JsonTokenType.ObjectEnd:
                    _db.Span.Slice(FindLocation(_stack.ObjectStackCount - 1, true)).Write <int>(numberOfRowsForMembers);
                    numberOfRowsForMembers += _stack.PopObject();
                    break;

                case JsonTokenType.ArrayStart:
                    AppendDbRow(JsonObject.JsonValueType.Array, _valuesIndex);
                    while (!_stack.TryPushArray(arrayItemsCount))
                    {
                        ResizeDb();
                    }
                    arrayItemsCount = 0;
                    break;

                case JsonTokenType.ArrayEnd:
                    _db.Span.Slice(FindLocation(_stack.ArrayStackCount - 1, false)).Write <int>(arrayItemsCount);
                    arrayItemsCount += _stack.PopArray();
                    break;

                case JsonTokenType.Property:
                    ParsePropertyName();
                    ParseValue();
                    numberOfRowsForMembers++;
                    numberOfRowsForMembers++;
                    break;

                case JsonTokenType.Value:
                    ParseValue();
                    arrayItemsCount++;
                    numberOfRowsForMembers++;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            var result = new JsonObject(_values, _db.Slice(0, _dbIndex).Span, _pool, _scratchManager);

            _scratchManager = null;
            return(result);
        }
예제 #16
0
 public abstract void Return(OwnedMemory <byte> buffer);
예제 #17
0
 private KVDatabase(Span <DbRow> span, OwnedMemory <byte> memory)
 {
     _rows   = span;
     _memory = memory;
 }
예제 #18
0
 /// <summary>
 /// Get <see cref="OwnedMemory{T}"/> from the underlying <see cref="ReadOnlySequence{T}"/>.
 /// If unable to get the <see cref="OwnedMemory{T}"/>, return false.
 /// </summary>
 public static bool TryGetOwnedMemory <T>(ReadOnlySequence <T> sequence, out OwnedMemory <T> ownedMemory, out int start, out int length)
 {
     return(sequence.TryGetOwnedMemory(out ownedMemory, out start, out length));
 }
예제 #19
0
 public void Dispose()
 {
     _pool.Return(_stateData);
     _stateData = null;
     GC.SuppressFinalize(this);
 }
예제 #20
0
        /// <summary>
        /// Writes a new buffer into the pipeline. The task returned by this operation only completes when the next
        /// Read has been queued, or the Reader has completed, since the buffer provided here needs to be kept alive
        /// until the matching Read finishes (because we don't have ownership tracking when working with unowned buffers)
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        // Called by the WRITER
        public async Task WriteAsync(OwnedMemory<byte> buffer, CancellationToken cancellationToken)
        {
            // If Writing has stopped, why is the caller writing??
            if (Writing.Status != TaskStatus.WaitingForActivation)
            {
                throw new OperationCanceledException("Writing has ceased on this pipeline");
            }

            // If Reading has stopped, we cancel. We don't write unless there's a reader ready in this pipeline.
            if (Reading.Status != TaskStatus.WaitingForActivation)
            {
                throw new OperationCanceledException("Reading has ceased on this pipeline");
            }

            // Register for cancellation on this token for the duration of the write
            using (cancellationToken.Register(state => ((UnownedBufferReader)state).CancelWriter(), this))
            {
                // Wait for reading to start
                await ReadingStarted;

                // Cancel this task if this write is cancelled
                cancellationToken.ThrowIfCancellationRequested();

                // Allocate a new segment to hold the buffer being written.
                using (var segment = new BufferSegment(buffer))
                {
                    segment.End = buffer.Memory.Length;

                    if (_head == null || _head.ReadableBytes == 0)
                    {
                        // Update the head to point to the head of the buffer.
                        _head = segment;
                    }
                    else if (_tail != null)
                    {
                        // Add this segment to the end of the chain
                        _tail.Next = segment;
                    }

                    // Always update tail to the buffer's tail
                    _tail = segment;

                    // Trigger the continuation
                    Complete();

                    // Wait for another read to come (or for the end of Reading, which will also trigger this gate to open) in before returning
                    await _readWaiting;

                    if (_head.ReadableBytes > 0)
                    {
                        // We need to preserve any buffers that haven't been consumed
                        _head = BufferSegment.Clone(new ReadCursor(_head), new ReadCursor(_tail, _tail?.End ?? 0), out _tail);
                    }
                }

                // Cancel this task if this write is cancelled
                cancellationToken.ThrowIfCancellationRequested();
            }
        }
예제 #21
0
 public void Dispose()
 {
     if (_pool == null) throw new InvalidOperationException("only root object can (and should) be disposed.");
     _db = ReadOnlySpan<byte>.Empty;
     _values = ReadOnlySpan<byte>.Empty;
     _pool.Return(_dbMemory);
     _dbMemory = null;
 }
예제 #22
0
        private void ResizeDb()
        {
            var oldData = _scratchMemory.Span;
            var newScratch = _pool.Rent(_scratchMemory.Length * 2);
            int dbLength = newScratch.Length / 2;

            var newDb = newScratch.Memory.Slice(0, dbLength);
            _db.Slice(0, _valuesIndex).Span.CopyTo(newDb.Span);
            _db = newDb;

            var newStackMemory = newScratch.Memory.Slice(dbLength);
            _stack.Resize(newStackMemory);
            _pool.Return(_scratchManager);
            _scratchManager = newScratch;
        }
예제 #23
0
 public Segment(OwnedMemory<byte> memory, int id)
 {
     _owned = memory;
     _commited = 0;
     Id = id;
 }
예제 #24
0
 public void ResetMemory()
 {
     _owned.Release();
     _owned = null;
 }
예제 #25
0
 internal Memory(OwnedMemory <T> owner, int length)
 {
     _owner  = owner;
     _index  = 0;
     _length = length;
 }
예제 #26
0
        private static ReadOnlyMemoryContent CreateContent(int contentLength, bool useArray, out Memory <byte> memory, out OwnedMemory <byte> ownedMemory)
        {
            if (useArray)
            {
                memory      = new byte[contentLength];
                ownedMemory = null;
            }
            else
            {
                ownedMemory = new NativeOwnedMemory(contentLength);
                memory      = ownedMemory.Memory;
            }

            new Random(contentLength).NextBytes(memory.Span);

            return(new ReadOnlyMemoryContent(memory));
        }
예제 #27
0
 public Segment(OwnedMemory <byte> memory, int id)
 {
     _owned    = memory;
     _commited = 0;
     Id        = id;
 }
예제 #28
0
 public abstract void Return(OwnedMemory<byte> buffer);
예제 #29
0
 public void ResetMemory()
 {
     _ownedMemory.Release();
     _ownedMemory = null;
     _memory      = default;
 }