public void Dispose() { // TODO: put object disposed guards in front of operations var segment = _firstSegment; _firstSegment = null; _lastSegment = null; while (segment != null) { var nextSegment = segment.Next; segment.Dispose(); segment = nextSegment; } }
public Memory <byte> GetTrailingMemory(int sizeHint = 0) { // special case, no buffers. // allocate buffer on first read. if (_firstSegment == null && _lastSegment == null) { var rental = _memoryPool.Rent(sizeHint); var segment = new RollingMemorySegment(rental, 0); _firstSegment = segment; _lastSegment = segment; return(rental.Memory); } // special case, all occupied memory has been consumed. // drop both index to 0 so the entire page becomes trailing memory again. if (IsEmpty) { _firstIndex = 0; _lastIndex = 0; } // special case, last page does not have enough memory to hold sizeHint if (_lastIndex + sizeHint > _lastSegment.Memory.Length) { _lastSegment.Shrink(_lastIndex); } // special case, last page is completely full. // allocate and append a new unoccupied last page. if (_lastIndex == _lastSegment.Memory.Length) { var rental = _memoryPool.Rent(sizeHint); _lastSegment.Next = new RollingMemorySegment( rental, _lastSegment.RunningIndex + _lastIndex); _lastSegment = _lastSegment.Next; _lastIndex = 0; return(rental.Memory); } return(MemoryMarshal.AsMemory(_lastSegment.Memory.Slice(_lastIndex))); }
public void DisposeFirstSegment() { if (_firstSegment == null && _lastSegment == null) { return; } var disposedSegment = _firstSegment; if (_firstSegment == _lastSegment) { _firstSegment = null; _firstIndex = 0; _lastSegment = null; _lastIndex = 0; } else { _firstSegment = disposedSegment.Next; _firstIndex = 0; } disposedSegment.Dispose(); }