package mil.nga.giat.geowave.datastore.hbase.util;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.hadoop.hbase.client.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import mil.nga.giat.geowave.core.index.ByteArrayId;
import mil.nga.giat.geowave.core.index.IndexUtils;
import mil.nga.giat.geowave.core.store.adapter.AdapterStore;
import mil.nga.giat.geowave.core.store.adapter.DataAdapter;
import mil.nga.giat.geowave.core.store.callback.ScanCallback;
import mil.nga.giat.geowave.core.store.filter.QueryFilter;
import mil.nga.giat.geowave.core.store.flatten.BitmaskUtils;
import mil.nga.giat.geowave.core.store.index.PrimaryIndex;
import mil.nga.giat.geowave.core.store.util.EntryIteratorWrapper;
public class HBaseEntryIteratorWrapper<T> extends
EntryIteratorWrapper<T>
{
private final static Logger LOGGER = LoggerFactory.getLogger(HBaseEntryIteratorWrapper.class);
private boolean decodePersistenceEncoding = true;
private byte[] fieldSubsetBitmask;
private Integer bitPosition;
private ByteArrayId skipUntilRow;
private boolean reachedEnd = false;
private boolean hasSkippingFilter = false;
public HBaseEntryIteratorWrapper(
final AdapterStore adapterStore,
final PrimaryIndex index,
final Iterator<Result> scannerIt,
final QueryFilter clientFilter,
final Pair<List<String>, DataAdapter<?>> fieldIds,
final double[] maxResolutionSubsamplingPerDimension,
final boolean decodePersistenceEncoding,
final boolean hasSkippingFilter ) {
this(
adapterStore,
index,
scannerIt,
clientFilter,
null,
fieldIds,
maxResolutionSubsamplingPerDimension,
decodePersistenceEncoding,
hasSkippingFilter);
}
public HBaseEntryIteratorWrapper(
final AdapterStore adapterStore,
final PrimaryIndex index,
final Iterator<Result> scannerIt,
final QueryFilter clientFilter,
final ScanCallback<T> scanCallback,
final Pair<List<String>, DataAdapter<?>> fieldIds,
final double[] maxResolutionSubsamplingPerDimension,
final boolean decodePersistenceEncoding,
final boolean hasSkippingFilter ) {
super(
true,
adapterStore,
index,
scannerIt,
clientFilter,
scanCallback);
this.decodePersistenceEncoding = decodePersistenceEncoding;
this.hasSkippingFilter = hasSkippingFilter;
if (!this.hasSkippingFilter) {
initializeBitPosition(maxResolutionSubsamplingPerDimension);
}
else {
bitPosition = null;
}
if (fieldIds != null) {
fieldSubsetBitmask = BitmaskUtils.generateFieldSubsetBitmask(
index.getIndexModel(),
fieldIds.getLeft(),
fieldIds.getRight());
}
}
@Override
protected T decodeRow(
final Object row,
final QueryFilter clientFilter,
final PrimaryIndex index,
final boolean wholeRowEncoding ) {
Result result = null;
try {
result = (Result) row;
}
catch (final ClassCastException e) {
LOGGER.error(
"Row is not an HBase row Result.",
e);
return null;
}
if (passesResolutionSkippingFilter(result)) {
return HBaseUtils.decodeRow(
result,
adapterStore,
clientFilter,
index,
scanCallback,
fieldSubsetBitmask,
decodePersistenceEncoding);
}
return null;
}
private boolean passesResolutionSkippingFilter(
final Result result ) {
if (hasSkippingFilter) {
return true;
}
if ((reachedEnd == true) || ((skipUntilRow != null) && (skipUntilRow.compareTo(new ByteArrayId(
result.getRow())) > 0))) {
return false;
}
incrementSkipRow(result);
return true;
}
private void incrementSkipRow(
final Result result ) {
if (bitPosition != null) {
final byte[] nextRow = IndexUtils.getNextRowForSkip(
result.getRow(),
bitPosition);
if (nextRow == null) {
reachedEnd = true;
}
else {
skipUntilRow = new ByteArrayId(
nextRow);
}
}
}
private void initializeBitPosition(
final double[] maxResolutionSubsamplingPerDimension ) {
if ((maxResolutionSubsamplingPerDimension != null) && (maxResolutionSubsamplingPerDimension.length > 0)) {
bitPosition = IndexUtils.getBitPositionFromSubsamplingArray(
index.getIndexStrategy(),
maxResolutionSubsamplingPerDimension);
}
}
}