/*
* JLibs: Common Utilities for Java
* Copyright (C) 2009 Santhosh Kumar T <santhosh.tekuri@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*/
package jlibs.nio.util;
import jlibs.core.util.LongTreeMap;
import java.lang.ref.SoftReference;
import java.nio.ByteBuffer;
import static jlibs.nio.Debugger.DEBUG;
import static jlibs.nio.Debugger.println;
/**
* @author Santhosh Kumar Tekuri
*/
public class PooledBufferAllocator implements BufferAllocator{
private boolean directPreferred;
public PooledBufferAllocator(boolean directPreferred){
this.directPreferred = directPreferred;
}
@SuppressWarnings("unchecked")
private LongTreeMap<SoftReference<Buffers>> map[] = new LongTreeMap[]{ new LongTreeMap<>(), new LongTreeMap<>() };
private Buffers get(LongTreeMap<SoftReference<Buffers>> map, int size, boolean create){
LongTreeMap.Entry<SoftReference<Buffers>> entry = map.getEntry(size);
Buffers bytes = null;
if(entry!=null){
bytes = entry.value.get();
if(bytes==null){
if(create)
entry.value = new SoftReference<>(bytes=new Buffers());
else
map.deleteEntry(entry);
}
}else if(create)
map.put(size, new SoftReference<>(bytes=new Buffers()));
return bytes;
}
@Override
public boolean directPreferred(){
return directPreferred;
}
@Override
public ByteBuffer allocateHeap(int size){
Buffers buffers = get(map[0], size, false);
if(buffers==null || buffers.length==0){
if(DEBUG)
println("pool.allocate("+size+")");
return ByteBuffer.allocate(size);
}else{
return buffers.removeLast();
}
}
@Override
public ByteBuffer allocateDirect(int size){
Buffers buffers = get(map[1], size, false);
if(buffers==null || buffers.length==0){
if(DEBUG)
println("pool.allocateDirect("+size+")");
return ByteBuffer.allocateDirect(size);
}else
return buffers.removeLast();
}
public void free(ByteBuffer buffer){
buffer.clear();
get(map[buffer.isDirect() ? 1 : 0], buffer.capacity(), true).append(buffer);
}
}