package iitb.con.util;
import java.nio.ByteBuffer;
import java.util.Random;
public class Sorted2DIntArray {
private static final int COL_NUM = 2;
protected int currentIndex;
private static final int INT_SIZE = 4;
protected int[][] a;
public Sorted2DIntArray(int size) {
a = new int[size][COL_NUM];
for(int i = 0 ; i < size; i++)
a[i][0] = Integer.MAX_VALUE;
a[0][0] = -1; a[0][1] = -1;
currentIndex = 1;
}
public Sorted2DIntArray(ByteBuffer buffer) {
buffer.flip();
int size = buffer.capacity() / (INT_SIZE * COL_NUM);
if(size == 0) {
a = new int[1][COL_NUM];
a[0][0] = -1; a[0][1] = -1;
currentIndex = 1;
}
else {
a = new int[size][COL_NUM];
for(int i = 0 ; i < size; i++)
for(int j = 0 ; j < COL_NUM ;j++)
a[i][j] = buffer.getInt();
currentIndex = size;
}
}
protected void growArray(int oldCapacity) {
int size = Math.max((oldCapacity * 3)/2 + 1, 150);
int[][] grown = new int[size][COL_NUM];
for(int i = a.length ; i < size; i++)
grown[i][0] = Integer.MAX_VALUE;
System.arraycopy(a, 0, grown, 0, a.length);
a = grown;
}
public final int add(int value1, int value2) {
int index = -1;
if(isValuePairExist(value1,value2))
return -1;
try {
if(currentIndex == 0 || value1 > a[currentIndex - 1][0]) {
index = currentIndex++;
if (currentIndex > a.length) {
growArray(currentIndex);
}
a[index][0] = value1;
a[index][1] = value2;
} else {
index = Int2DBinarySearch.locate(a, value1, 0);
if(index > 0)
index++;
else
index = -index;
add(index, value1, value2);
}
}catch(ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
}
return index;
}
private void add(int index, int value1, int value2) {
if (index >= 0 && index <= currentIndex) {
if (++currentIndex > a.length) {
growArray(currentIndex);
}
if (index < currentIndex) {
System.arraycopy(a, index, a, index + 1,
currentIndex - index - 1);
}
int[][] n = new int[1][2];
n[0][0] = value1;
n[0][1] = value2;
a[index] = n[0];
} else {
System.err.println("Index: " + index + ", Current Index " + currentIndex);
throw new ArrayIndexOutOfBoundsException("Invalid index value");
}
}
public void remove(int value1) {
int index = Int2DBinarySearch.locate(a, value1, 0);
if (index >= 0 && index < currentIndex) {
if (index < --currentIndex){
System.arraycopy(a, index + 1, a, index,
currentIndex - index);
a[currentIndex][0] = 0;
a[currentIndex][1] = 0;
}
} else {
throw new ArrayIndexOutOfBoundsException("Invalid index value");
}
}
public final void ensureCapacity(int min) {
if (min > a.length) {
growArray(min);
}
}
public final void clear() {
currentIndex = 0;
}
public final int size() {
return currentIndex;
}
public void setSize(int count) {
if (count > a.length) {
growArray(count);
} else if (count < currentIndex) {
for (int i = count; i < currentIndex; i++) {
a[i][0] = 0;
a[i][1] = 0;
}
}
currentIndex = count;
}
public final int[][] get(int value1) {
int[][] r = null;
int i = 0;
int index = Int2DBinarySearch.locate(a, value1, 0);
try {
if (index > 0) {
while(((index + i) < currentIndex) && a[index + i][0] == value1)
i++;
int[][] r1 = new int[i][1];
for(int j = 0; j < i ; j++)
r1[j] = a[index + j];
i = 1;
while(((index - i) > 0) && a[index - i][0] == value1)
i++;
int[][] r2 = new int[i - 1][1];
for(int j = 0; j < i - 1 ; j++)
r2[j] = a[index - j -1];
return mergeArray(r1,r2);
}
}catch(ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
}
return r;
}
private int[][] mergeArray(int[][] r1, int[][] r2) {
int[][] r = new int[r1.length + r2.length][0];
for(int i = 0; i < r1.length; i++)
r[i] = r1[i];
for(int j=0,i = r1.length; j < r2.length; j++,i++)
r[i] = r2[j];
return r;
}
public final boolean isValuePairExist(int value1, int value2) {
int[][] r = get(value1);
if(r == null)
return false;
else {
for(int i = 0; i < r.length; i++)
if(r[i][1] == value2)
return true;
}
return false;
}
public final void set(int value1, int value2) {
int index = Int2DBinarySearch.locate(a, value1, 0);
if (index < currentIndex) {
a[index][0] = value1;
a[index][1] = value2;
} else {
throw new ArrayIndexOutOfBoundsException("Invalid index value");
}
}
public static void main(String[] args) {
Sorted2DIntArray grid = new Sorted2DIntArray(10);
Random r = new Random();
grid.add(-1, -1);
grid.add(13887, 52);
grid.add(13887, 1040);
grid.add(13887, 1011);
grid.add(13887, 322);
grid.add(13887, 738);
grid.add(13887, 1011);
grid.dump();
}
public ByteBuffer toBuffer() {
ByteBuffer buffer = ByteBuffer.allocate((currentIndex - 1) * INT_SIZE * COL_NUM);
for(int i = 0; i < currentIndex - 1; i++)
for(int j = 0 ; j < COL_NUM ;j++)
buffer.putInt(a[i][j]);
return buffer;
}
public void dump() {
for(int i = 0; i < a.length; i++) {
System.out.print("[ ");
for(int j = 0; j < a[i].length; j++)
System.out.print( a[i][j] + ",");
System.out.print(" ]\n");
}
}
}