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(); }
internal JsonObject(ReadOnlySpan<byte> values, ReadOnlySpan<byte> db, BufferPool pool = null, OwnedMemory<byte> dbMemory = null) { _db = db; _values = values; _pool = pool; _dbMemory = dbMemory; }
public BufferSegment(OwnedMemory<byte> buffer) { _buffer = buffer; Start = 0; End = 0; _buffer.AddReference(); }
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(); }
internal JsonObject(ReadOnlySpan <byte> values, ReadOnlySpan <byte> db, BufferPool pool = null, OwnedMemory <byte> dbMemory = null) { _db = db; _values = values; _pool = pool; _dbMemory = dbMemory; }
public static void ThrowArgumentValidationException <T>(OwnedMemory <T> ownedMemory, int start) => throw CreateArgumentValidationException(ownedMemory, start);
internal ReadOnlyMemory(OwnedMemory <T> owner, long id) : this(owner, id, 0, owner.GetSpanInternal(id).Length) { }
internal ReadOnlyMemory(OwnedMemory <T> owner, int index, int length) { _owner = owner; _index = index; _length = length; }
private Memory(OwnedMemory <T> owner, int index, int length) { _owner = owner; _index = index; _length = length; }
internal Memory(OwnedMemory <T> owner, long id) : this(owner, id, 0, owner.GetSpan(id).Length) { }
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; }
public void SetMemory(OwnedMemory <byte> buffer) { SetMemory(buffer, 0, 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; }
public PooledMemory(OwnedMemory <byte> ownedMemory, TestMemoryPool pool) { _ownedMemory = ownedMemory; _pool = pool; _leaser = Environment.StackTrace; }
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); }
public abstract void Return(OwnedMemory <byte> buffer);
private KVDatabase(Span <DbRow> span, OwnedMemory <byte> memory) { _rows = span; _memory = memory; }
/// <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)); }
public void Dispose() { _pool.Return(_stateData); _stateData = null; GC.SuppressFinalize(this); }
/// <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(); } }
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; }
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; }
public Segment(OwnedMemory<byte> memory, int id) { _owned = memory; _commited = 0; Id = id; }
public void ResetMemory() { _owned.Release(); _owned = null; }
internal Memory(OwnedMemory <T> owner, int length) { _owner = owner; _index = 0; _length = length; }
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)); }
public Segment(OwnedMemory <byte> memory, int id) { _owned = memory; _commited = 0; Id = id; }
public abstract void Return(OwnedMemory<byte> buffer);
public void ResetMemory() { _ownedMemory.Release(); _ownedMemory = null; _memory = default; }