package mil.nga.giat.geowave.datastore.hbase.query;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.exceptions.DeserializationException;
import org.apache.hadoop.hbase.filter.FilterBase;
import org.apache.hadoop.hbase.util.Bytes;
import mil.nga.giat.geowave.core.index.IndexUtils;
public class FixedCardinalitySkippingFilter extends
FilterBase
{
private Integer bitPosition;
private byte[] nextRow = null;
private ReturnCode returnCode;
private boolean init = false;
public FixedCardinalitySkippingFilter() {}
public FixedCardinalitySkippingFilter(
final Integer bitPosition ) {
this.bitPosition = bitPosition;
}
@Override
public ReturnCode filterKeyValue(
final Cell cell )
throws IOException {
// Make sure we have the next row to include
if (!init) {
init = true;
getNextRowKey(cell);
}
// Compare current row w/ next row
returnCode = checkNextRow(cell);
// If we're at or past the next row, advance it
if (returnCode != ReturnCode.SKIP) {
getNextRowKey(cell);
}
return returnCode;
}
private ReturnCode checkNextRow(
final Cell cell ) {
final byte[] row = CellUtil.cloneRow(cell);
final byte[] rowCopy = new byte[nextRow.length];
System.arraycopy(
row,
0,
rowCopy,
0,
rowCopy.length);
final int cmp = Bytes.compareTo(
rowCopy,
nextRow);
if (cmp < 0) {
return ReturnCode.SKIP;
}
else {
return ReturnCode.INCLUDE;
}
}
private void getNextRowKey(
final Cell currentCell ) {
final byte[] row = CellUtil.cloneRow(currentCell);
nextRow = IndexUtils.getNextRowForSkip(
row,
bitPosition);
}
@Override
public byte[] toByteArray()
throws IOException {
final ByteBuffer buf = ByteBuffer.allocate(Integer.BYTES);
buf.putInt(bitPosition);
return buf.array();
}
public static FixedCardinalitySkippingFilter parseFrom(
final byte[] bytes )
throws DeserializationException {
final ByteBuffer buf = ByteBuffer.wrap(bytes);
final int bitpos = buf.getInt();
return new FixedCardinalitySkippingFilter(
bitpos);
}
}