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<ByteBuffer>(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;
	}
	
}
