in src/Elastic.Transport/Components/Providers/RecyclableMemoryStreamManager.cs [397:439]
internal void ReturnLargeBuffer(byte[] buffer, string tag)
{
if (buffer == null) throw new ArgumentNullException(nameof(buffer));
if (!IsLargeBufferSize(buffer.Length))
throw new ArgumentException(
string.Format("buffer did not originate from this memory manager. The size is not {0} of ",
UseExponentialLargeBuffer ? "an exponential" : "a multiple") +
LargeBufferMultiple);
var poolIndex = GetPoolIndex(buffer.Length);
if (poolIndex < _largePools.Length)
{
if ((_largePools[poolIndex].Count + 1) * buffer.Length <= MaximumFreeLargePoolBytes ||
MaximumFreeLargePoolBytes == 0)
{
_largePools[poolIndex].Push(buffer);
Interlocked.Add(ref _largeBufferFreeSize[poolIndex], buffer.Length);
}
else
{
EventsWriter.MemoryStreamDiscardBuffer(Events.MemoryStreamBufferType.Large, tag,
Events.MemoryStreamDiscardReason.EnoughFree);
ReportLargeBufferDiscarded(Events.MemoryStreamDiscardReason.EnoughFree);
}
}
else
{
// This is a non-poolable buffer, but we still want to track its size for inuse
// analysis. We have space in the inuse array for this.
poolIndex = _largeBufferInUseSize.Length - 1;
EventsWriter.MemoryStreamDiscardBuffer(Events.MemoryStreamBufferType.Large, tag,
Events.MemoryStreamDiscardReason.TooLarge);
ReportLargeBufferDiscarded(Events.MemoryStreamDiscardReason.TooLarge);
}
Interlocked.Add(ref _largeBufferInUseSize[poolIndex], -buffer.Length);
ReportUsageReport(_smallPoolInUseSize, _smallPoolFreeSize, LargePoolInUseSize,
LargePoolFreeSize);
}