package org.kne.cloud.network; import java.nio.ByteBuffer; import java.util.Queue; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.kne.concurrent.SpinLock; import org.kne.debug.TimeDebugger; public class ByteBufferPool { private AtomicReferenceArray< ByteBuffer> rec; private volatile AtomicInteger pos=new AtomicInteger( 0); //private Lock lock=new SpinLock(); private int maxcount; private int length; private int mcj; private boolean direct; public ByteBufferPool(int maxcount, int length,boolean direct) { super(); this.maxcount = maxcount; this.length = length; this.direct=direct; rec=new AtomicReferenceArray(maxcount); mcj= rec.length()-1; } public ByteBufferPool(int maxcount, int length) { this(maxcount, length, true); } public void back(ByteBuffer b) { if(b.capacity()!=length) throw new IllegalArgumentException("wrong length"); b.clear(); if(pos.get()<=mcj) { int d=pos.getAndIncrement(); if(d>mcj) d=mcj; if(d<0) d=0; rec.compareAndSet(d,null,b); } } public ByteBuffer borrow() { ByteBuffer b=null; if(pos.get()>0) { int d=pos.decrementAndGet(); if(d>mcj) d=mcj; if(d<0) d=0; b=rec.getAndSet(d,null); } if(b==null) { if(direct) b=ByteBuffer.allocateDirect(length); else b=ByteBuffer.allocate(length); } return b; } public int getMaxCount() { return maxcount; } public int getLength() { return length; } }