/// <inheritdoc/> public void CompleteRead(int processedCount, ref ChannelReaderBufferSlice <T> slice) { if ((processedCount < 0) || (processedCount > slice.Length)) { throw new ArgumentOutOfRangeException( nameof(processedCount), "processedCount should be non-negative and less than allocated count"); } using (var guard = new StateReadGuard <TSyncObject>(_syncObject, _owner)) { if (!_owner._idToSliceEntries.TryGetValue(slice.Id, out var sliceEntryNode)) { throw new ArgumentException("Wrong slice variable."); } if (!_readInProgress) { throw new InvalidOperationException("CompleteWrite operation has not been started."); } var sliceEntry = sliceEntryNode.Value; if (slice.Length != sliceEntry.Length) { throw new ArgumentException("The provided slice have an invalid state", nameof(slice)); } guard.NotifyRead(processedCount, sliceEntry.Length); int nonProcessedCount = sliceEntry.Length - processedCount; if (processedCount == 0) { sliceEntry.Status = SliceEntryStatus.Data; } else if (nonProcessedCount == 0) { _owner._sliceEntries.Remove(sliceEntryNode); } else { sliceEntry.Length = nonProcessedCount; sliceEntry.Start += processedCount; sliceEntry.Status = SliceEntryStatus.Data; } _readInProgress = false; } }
/// <inheritdoc/> public void PartialFree(int newCount, ref ChannelReaderBufferSlice <T> slice) { if ((newCount < 1) || (newCount > slice.Length)) { throw new ArgumentOutOfRangeException( nameof(newCount), "New count should be greater than zero and less or equal to already allocated length."); } using (var guard = new StateReadGuard <TSyncObject>()) { if (!_owner._idToSliceEntries.TryGetValue(slice.Id, out var sliceEntryNode)) { throw new ArgumentException("Wrong slice variable."); } if (!_readInProgress) { throw new InvalidOperationException("PartialFree operation has not been started."); } if (slice.Length != sliceEntryNode.Value.Length) { throw new ArgumentException("The provided slice have an invalid state", nameof(slice)); } int decreaseSize = sliceEntryNode.Value.Length - newCount; if (decreaseSize == 0) { // Shit it - shit out return; } slice.DecreaseLength(decreaseSize); var sliceEntry = sliceEntryNode.Value; sliceEntry.Length = newCount; // Splitting released part to the new entry. var newEntry = _owner.AllocateEmptyEntryAfter(sliceEntryNode); newEntry.Buffer = sliceEntry.Buffer; newEntry.Start = sliceEntry.Start + sliceEntry.Length; newEntry.Length = decreaseSize; newEntry.Status = SliceEntryStatus.Data; guard.NotifyRead(0, decreaseSize); } }
/// <inheritdoc/> public abstract void PartialFree(int newCount, ref ChannelReaderBufferSlice <T> slice);
/// <inheritdoc/> public abstract void CompleteRead(int processedCount, ref ChannelReaderBufferSlice <T> slice);
/// <inheritdoc/> public void PartialFree(int newCount, ref ChannelReaderBufferSlice <T> slice) => throw new NotImplementedException();
/// <inheritdoc/> public void CompleteRead(int processedCount, ref ChannelReaderBufferSlice <T> slice) => throw new NotImplementedException();
void IChannelReader <T> .PartialFree(int newCount, ref ChannelReaderBufferSlice <T> slice) => throw new NotSupportedException();
void IChannelReader <T> .CompleteRead(int processedCount, ref ChannelReaderBufferSlice <T> slice) => throw new NotSupportedException();