internal PreallocatedBufferManager(long maxMemoryToPool, int maxBufferSize)
{
// default values: maxMemoryToPool = 48MB, maxBufferSize = 64KB
// This creates the following buffers:
// max: 64KB = 256, med 16KB = 1024, small 4KB = 4096
this.maxBufferSize = maxBufferSize;
this.medBufferSize = maxBufferSize / 4;
this.smallBufferSize = maxBufferSize / 16;
long eachPoolSize = maxMemoryToPool / 3;
long numLargeBuffers = eachPoolSize / maxBufferSize;
long numMedBuffers = eachPoolSize / medBufferSize;
long numSmallBuffers = eachPoolSize / smallBufferSize;
long numBuffers = numLargeBuffers + numMedBuffers + numSmallBuffers;
this.buffersList = new byte[numBuffers][];
this.handles = new GCHandle[numBuffers];
this.freeSmallBuffers = new ConcurrentStack<byte[]>();
this.freeMedianBuffers = new ConcurrentStack<byte[]>();
this.freeLargeBuffers = new ConcurrentStack<byte[]>();
int lastLarge = 0;
for (int i = 0; i < numLargeBuffers; i++, lastLarge++)
{
buffersList[i] = new byte[maxBufferSize];
handles[i] = GCHandle.Alloc(buffersList[i], GCHandleType.Pinned);
this.freeLargeBuffers.Push(buffersList[i]);
}
int lastMed = lastLarge;
for (int i = lastLarge; i < numMedBuffers + lastLarge; i++, lastMed++)
{
buffersList[i] = new byte[this.medBufferSize];
handles[i] = GCHandle.Alloc(buffersList[i], GCHandleType.Pinned);
this.freeMedianBuffers.Push(buffersList[i]);
}
for (int i = lastMed; i < numSmallBuffers + lastMed; i++)
{
buffersList[i] = new byte[this.smallBufferSize];
handles[i] = GCHandle.Alloc(buffersList[i], GCHandleType.Pinned);
this.freeSmallBuffers.Push(buffersList[i]);
}
}