blob: f56d0d9259af5bea4662ae8308e6903d7ce69bc0 [file] [log] [blame]
//
// ========================================================================
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.io;
import java.nio.ByteBuffer;
public class ArrayByteBufferPool implements ByteBufferPool
{
private final int _min;
private final int _maxQueue;
private final ByteBufferPool.Bucket[] _direct;
private final ByteBufferPool.Bucket[] _indirect;
private final int _inc;
public ArrayByteBufferPool()
{
this(-1,-1,-1,-1);
}
public ArrayByteBufferPool(int minSize, int increment, int maxSize)
{
this(minSize,increment,maxSize,-1);
}
public ArrayByteBufferPool(int minSize, int increment, int maxSize, int maxQueue)
{
if (minSize<=0)
minSize=0;
if (increment<=0)
increment=1024;
if (maxSize<=0)
maxSize=64*1024;
if (minSize>=increment)
throw new IllegalArgumentException("minSize >= increment");
if ((maxSize%increment)!=0 || increment>=maxSize)
throw new IllegalArgumentException("increment must be a divisor of maxSize");
_min=minSize;
_inc=increment;
_direct=new ByteBufferPool.Bucket[maxSize/increment];
_indirect=new ByteBufferPool.Bucket[maxSize/increment];
_maxQueue=maxQueue;
int size=0;
for (int i=0;i<_direct.length;i++)
{
size+=_inc;
_direct[i]=new ByteBufferPool.Bucket(this,size,_maxQueue);
_indirect[i]=new ByteBufferPool.Bucket(this,size,_maxQueue);
}
}
@Override
public ByteBuffer acquire(int size, boolean direct)
{
ByteBufferPool.Bucket bucket = bucketFor(size,direct);
if (bucket==null)
return newByteBuffer(size,direct);
return bucket.acquire(direct);
}
@Override
public void release(ByteBuffer buffer)
{
if (buffer!=null)
{
ByteBufferPool.Bucket bucket = bucketFor(buffer.capacity(),buffer.isDirect());
if (bucket!=null)
bucket.release(buffer);
}
}
public void clear()
{
for (int i=0;i<_direct.length;i++)
{
_direct[i].clear();
_indirect[i].clear();
}
}
private ByteBufferPool.Bucket bucketFor(int size,boolean direct)
{
if (size<=_min)
return null;
int b=(size-1)/_inc;
if (b>=_direct.length)
return null;
ByteBufferPool.Bucket bucket = direct?_direct[b]:_indirect[b];
return bucket;
}
// Package local for testing
ByteBufferPool.Bucket[] bucketsFor(boolean direct)
{
return direct ? _direct : _indirect;
}
}