package mil.nga.giat.geowave.core.index;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
public class MultiDimensionalCoordinateRanges implements
Persistable
{
// this is a generic placeholder for "tiers"
private byte[] multiDimensionalId;
private CoordinateRange[][] coordinateRangesPerDimension;
public MultiDimensionalCoordinateRanges() {
coordinateRangesPerDimension = new CoordinateRange[][] {};
}
public MultiDimensionalCoordinateRanges(
final byte[] multiDimensionalPrefix,
final CoordinateRange[][] coordinateRangesPerDimension ) {
multiDimensionalId = multiDimensionalPrefix;
this.coordinateRangesPerDimension = coordinateRangesPerDimension;
}
public byte[] getMultiDimensionalId() {
return multiDimensionalId;
}
public int getNumDimensions() {
return coordinateRangesPerDimension.length;
}
public CoordinateRange[] getRangeForDimension(
final int dimension ) {
return coordinateRangesPerDimension[dimension];
}
@Override
public byte[] toBinary() {
final List<byte[]> serializedRanges = new ArrayList<>();
final int idLength = (multiDimensionalId == null ? 0 : multiDimensionalId.length);
int byteLength = (4 * getNumDimensions()) + 8 + idLength;
final int[] numPerDimension = new int[getNumDimensions()];
int d = 0;
for (final CoordinateRange[] dim : coordinateRangesPerDimension) {
numPerDimension[d++] = dim.length;
for (final CoordinateRange range : dim) {
final byte[] serializedRange = range.toBinary();
byteLength += (serializedRange.length + 4);
serializedRanges.add(serializedRange);
}
}
final ByteBuffer buf = ByteBuffer.allocate(byteLength);
buf.putInt(idLength);
if (idLength > 0) {
buf.put(multiDimensionalId);
}
buf.putInt(coordinateRangesPerDimension.length);
for (final int num : numPerDimension) {
buf.putInt(num);
}
for (final byte[] serializedRange : serializedRanges) {
buf.putInt(serializedRange.length);
buf.put(serializedRange);
}
return buf.array();
}
@Override
public void fromBinary(
final byte[] bytes ) {
final ByteBuffer buf = ByteBuffer.wrap(bytes);
final int idLength = buf.getInt();
if (idLength > 0) {
multiDimensionalId = new byte[idLength];
buf.get(multiDimensionalId);
}
else {
multiDimensionalId = null;
}
coordinateRangesPerDimension = new CoordinateRange[buf.getInt()][];
for (int d = 0; d < coordinateRangesPerDimension.length; d++) {
coordinateRangesPerDimension[d] = new CoordinateRange[buf.getInt()];
}
for (int d = 0; d < coordinateRangesPerDimension.length; d++) {
for (int i = 0; i < coordinateRangesPerDimension[d].length; i++) {
final byte[] serializedRange = new byte[buf.getInt()];
buf.get(serializedRange);
coordinateRangesPerDimension[d][i] = new CoordinateRange();
coordinateRangesPerDimension[d][i].fromBinary(serializedRange);
}
}
}
}