package dotnet54.measures.univariate;

import java.util.concurrent.ConcurrentLinkedQueue;

public class MemorySpaceProvider {
	private static MemorySpaceProvider singleton = null;
	
	ConcurrentLinkedQueue<double[][]>dblMatrices;
	ConcurrentLinkedQueue<int[][]>intMatrices;
	ConcurrentLinkedQueue<double[]>dblArrays;
	
	int size;
	
	
	private MemorySpaceProvider(int length){
		int nThreads = Runtime.getRuntime().availableProcessors();
		this.size = length+10;//+10 to be sure we have enough
		dblMatrices = new ConcurrentLinkedQueue<>();
		intMatrices = new ConcurrentLinkedQueue<>();
		dblArrays = new ConcurrentLinkedQueue<>();
//		System.out.println("Creating memory space provider with size="+size);
		for (int i = 0; i < 2*nThreads;i++) {
			dblMatrices.add(new double[size][size]);
			intMatrices.add(new int[size][size]);
		}
		for (int i = 0; i < 10*nThreads; i++) {
			dblArrays.add(new double[size]);
		}
		
	}

	public static MemorySpaceProvider getInstance(int length) {
		if (singleton == null || length>singleton.size) {
			synchronized (MemorySpaceProvider.class) {
				if (singleton == null|| length>singleton.size) {
					singleton = new MemorySpaceProvider(length);
				}
			}
		}
		return singleton;
	}
	
	public static MemorySpaceProvider getInstance() {
		if (singleton == null) {
			synchronized (MemorySpaceProvider.class) {
				if (singleton == null) {
					singleton = new MemorySpaceProvider(3000);
				}
			}
		}
		return singleton;
	}
	
	public double[][] getDoubleMatrix(){
		return dblMatrices.poll();
	}
	
	public void returnDoubleMatrix(double[][]m){
		dblMatrices.add(m);
	}
	
	public int[][] getIntMatrix(){
		return intMatrices.poll();
	}
	
	public void returnIntMatrix(int[][]m){
		intMatrices.add(m);
	}
	
	public double[] getDoubleArray(){
		return dblArrays.poll();
	}
	
	public void returnDoubleArray(double[]t){
		dblArrays.add(t);
	}

}