LADXHD/GbsPlayer/ByteBufferPool.cs
2023-12-14 17:21:22 -05:00

99 lines
2.7 KiB
C#

using System.Collections.Generic;
namespace GbsPlayer
{
internal class ByteBufferPool
{
private readonly int _minBufferSize;
private readonly int _maxBuffers;
public int FreeAmount
{
get { return _freeBuffers.Count; }
}
private readonly List<byte[]> _freeBuffers;
public ByteBufferPool(int minBufferSize = 0, int maxBuffers = int.MaxValue)
{
_minBufferSize = minBufferSize;
_maxBuffers = maxBuffers;
_freeBuffers = new List<byte[]>();
}
/// <summary>
/// Get a buffer that is at least as big as size.
/// </summary>
public byte[] Get(int size)
{
if (size < _minBufferSize)
size = _minBufferSize;
byte[] result;
lock (_freeBuffers)
{
var index = FirstLargerThan(size);
if (index == -1)
{
if (_freeBuffers.Count > 0)
_freeBuffers.RemoveAt(0);
result = new byte[size];
}
else
{
result = _freeBuffers[index];
_freeBuffers.RemoveAt(index);
}
}
return result;
}
/// <summary>
/// Return the given buffer to the pool.
/// </summary>
public void Return(byte[] buffer)
{
lock (_freeBuffers)
{
if (FreeAmount >= _maxBuffers)
return;
var index = FirstLargerThan(buffer.Length);
if (index == -1)
_freeBuffers.Add(buffer);
else
_freeBuffers.Insert(index, buffer);
}
}
// Find the smallest buffer that is larger than or equally large as size or -1 if none exist
private int FirstLargerThan(int size)
{
if (_freeBuffers.Count == 0) return -1;
var l = 0;
var r = _freeBuffers.Count - 1;
while (l <= r)
{
var m = (l + r) / 2;
var buffer = _freeBuffers[m];
if (buffer.Length < size)
{
l = m + 1;
}
else if (buffer.Length > size)
{
r = m;
if (l == r) return l;
}
else
{
return m;
}
}
return -1;
}
}
}