package mergeSortParallel;

import java.util.Arrays;

import jsr166y.RecursiveAction;

public class MergeSort extends RecursiveAction {
    private static final int SEQUENTIAL_THRESHOLD = 50000;
	private final int[] numbers;
    private final int startPos, endPos;
    private int[] result;

    public MergeSort(int[] numbers, int startPos, int endPos) {
		this.numbers=numbers;
		this.startPos = startPos;
		this.endPos = endPos;
		this.result = new int[numbers.length];
	}

	private void merge(MergeSort left, MergeSort right) {
        int i=0, leftPos=0, rightPos=0, leftSize = left.size(), rightSize = right.size();
        
        while (leftPos < leftSize && rightPos < rightSize)
            result[i++] = (left.result[leftPos] <= right.result[rightPos])
                    ? left.result[leftPos++]
                    : right.result[rightPos++];
        
        while (leftPos < leftSize)
            result[i++] = left.result[leftPos++];
        
        while (rightPos < rightSize)
            result[i++] = right.result[rightPos++];
        
        System.out.println(Thread.currentThread().getName());
    }

    public int size() {
        return endPos-startPos;
    }

    protected void compute() {
        if (size() < SEQUENTIAL_THRESHOLD) {
            System.arraycopy(numbers, startPos, result, 0, size());
            Arrays.sort(result, 0, size());
        }
        else {
            int midpoint = size() / 2;
            MergeSort left = new MergeSort(numbers, startPos, startPos+midpoint);
            MergeSort right = new MergeSort(numbers, startPos+midpoint, endPos);
            invokeAll(left, right);
            merge(left, right);
        }
    }
    
    public int[] getResult() {
		return result;
	}
}
