/*
* Created on Nov 4, 2008
* Created by Paul Gardner
*
* Copyright 2008 Vuze, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
package org.gudy.azureus2.core3.util;
import java.util.*;
import java.nio.ByteBuffer;
public class
DirectByteBufferPoolHeap
extends DirectByteBufferPool
{
private final boolean USE_POOLS = false;
private final boolean TRACE = false;
private final int MIN_POOL;
private final int MAX_POOL;
private final LinkedList[] pools;
private final int[] pool_sizes;
private Map sizes;
protected
DirectByteBufferPoolHeap()
{
/**
* On linux (at least) JDK1.7.0 using heap buffers doesn't play well as the JVM still
* goes and creates DirectByteBuffers under the covers and things run out of control
* (after a few mins I have a 9GB VM...)
*/
if ( USE_POOLS ){
pool_sizes = new int[]{
2*1024,
4*1024+128,
8*1024+128,
16*1024+128,
32*1024+128,
64*1024+128,
128*1024+128,
256*1024 };
MIN_POOL = pool_sizes[0];
MAX_POOL = pool_sizes[pool_sizes.length-1];
pools = new LinkedList[ pool_sizes.length ];
for (int i=0;i<pools.length;i++){
pools[i] = new LinkedList();
}
if ( TRACE ){
sizes = new TreeMap();
SimpleTimer.addPeriodicEvent(
"HeapPoolDumper",
5000,
new TimerEventPerformer()
{
public void
perform(
TimerEvent event )
{
synchronized( sizes ){
String str = "";
Iterator it = sizes.entrySet().iterator();
while( it.hasNext()){
Map.Entry entry = (Map.Entry)it.next();
str += (str.length()==0?"":",") + entry.getKey() + "->" + entry.getValue();
}
System.out.println( "HB allocs: " + str );
}
}
});
}
}else{
MIN_POOL = MAX_POOL = 0;
pools = null;
pool_sizes = null;
}
}
protected DirectByteBuffer
getBufferSupport(
byte allocator,
int length )
{
if ( USE_POOLS ){
if ( TRACE ){
synchronized( sizes ){
Integer key = new Integer( length/32*32 );
Integer count = (Integer)sizes.get( key );
if ( count == null ){
sizes.put( key, new Integer(1));
}else{
sizes.put( key, new Integer( count.intValue() + 1 ));
}
}
}
int pool_index = getPoolIndex( length );
if ( pool_index != -1 ){
LinkedList pool = pools[pool_index];
synchronized( pool ){
if ( !pool.isEmpty()){
Object[] entry = (Object[])pool.removeLast();
ByteBuffer buff = (ByteBuffer)entry[0];
buff.clear();
buff.limit( length );
return( new DirectByteBuffer( allocator, buff, this ));
}
}
DirectByteBuffer buffer = new DirectByteBuffer( allocator, ByteBuffer.allocate( pool_sizes[pool_index] ), this );
ByteBuffer buff = buffer.getBufferInternal();
buff.limit( length );
return( buffer );
}else{
return( new DirectByteBuffer( allocator, ByteBuffer.allocate( length ), this ));
}
}else{
return( new DirectByteBuffer( allocator, ByteBuffer.allocate( length ), this ));
}
}
protected void
returnBufferSupport(
DirectByteBuffer buffer )
{
if ( USE_POOLS ){
ByteBuffer buff = buffer.getBufferInternal();
int length = buff.capacity();
int pool_index = getPoolIndex( length );
if ( pool_index != -1 ){
LinkedList pool = pools[pool_index];
synchronized( pool ){
pool.addLast( new Object[]{ buff });
}
}
}
}
protected int
getPoolIndex(
int length )
{
if ( length < MIN_POOL|| length > MAX_POOL ){
return( -1 );
}
for (int i=0;i<pool_sizes.length;i++){
if ( length <= pool_sizes[i] ){
return( i );
}
}
return( -1 );
}
}