package mil.nga.giat.geowave.datastore.accumulo.query;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import org.apache.accumulo.core.client.ScannerBase;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Iterators;
import mil.nga.giat.geowave.core.index.ByteArrayId;
import mil.nga.giat.geowave.core.index.StringUtils;
import mil.nga.giat.geowave.core.store.CloseableIterator;
import mil.nga.giat.geowave.core.store.CloseableIteratorWrapper;
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.data.visibility.DifferingFieldVisibilityEntryCount;
import mil.nga.giat.geowave.core.store.filter.FilterList;
import mil.nga.giat.geowave.core.store.filter.QueryFilter;
import mil.nga.giat.geowave.core.store.index.PrimaryIndex;
import mil.nga.giat.geowave.core.store.query.FilteredIndexQuery;
import mil.nga.giat.geowave.datastore.accumulo.AccumuloOperations;
import mil.nga.giat.geowave.datastore.accumulo.util.AccumuloEntryIteratorWrapper;
import mil.nga.giat.geowave.datastore.accumulo.util.ScannerClosableWrapper;
public abstract class AccumuloFilteredIndexQuery extends
AccumuloQuery implements
FilteredIndexQuery
{
protected List<QueryFilter> clientFilters;
private final static Logger LOGGER = LoggerFactory.getLogger(AccumuloFilteredIndexQuery.class);
protected final ScanCallback<?> scanCallback;
public AccumuloFilteredIndexQuery(
final List<ByteArrayId> adapterIds,
final PrimaryIndex index,
final ScanCallback<?> scanCallback,
final Pair<List<String>, DataAdapter<?>> fieldIdsAdapterPair,
final DifferingFieldVisibilityEntryCount visibilityCounts,
final String... authorizations ) {
super(
adapterIds,
index,
fieldIdsAdapterPair,
visibilityCounts,
authorizations);
this.scanCallback = scanCallback;
}
protected List<QueryFilter> getClientFilters() {
return clientFilters;
}
@Override
public void setClientFilters(
final List<QueryFilter> clientFilters ) {
this.clientFilters = clientFilters;
}
protected abstract void addScanIteratorSettings(
final ScannerBase scanner );
@SuppressWarnings("rawtypes")
public CloseableIterator<Object> query(
final AccumuloOperations accumuloOperations,
final AdapterStore adapterStore,
final double[] maxResolutionSubsamplingPerDimension,
final Integer limit ) {
boolean exists = false;
try {
exists = accumuloOperations.tableExists(StringUtils.stringFromBinary(index.getId().getBytes()));
}
catch (final IOException e) {
LOGGER.error(
"Table does not exist",
e);
}
if (!exists) {
LOGGER.warn("Table does not exist " + StringUtils.stringFromBinary(index.getId().getBytes()));
return new CloseableIterator.Empty();
}
final ScannerBase scanner = getScanner(
accumuloOperations,
maxResolutionSubsamplingPerDimension,
limit);
if (scanner == null) {
LOGGER.error("Could not get scanner instance, getScanner returned null");
return new CloseableIterator.Empty();
}
addScanIteratorSettings(scanner);
Iterator it = initIterator(
adapterStore,
scanner);
if ((limit != null) && (limit > 0)) {
it = Iterators.limit(
it,
limit);
}
return initCloseableIterator(
scanner,
it);
}
protected CloseableIterator<Object> initCloseableIterator(
ScannerBase scanner,
Iterator it ) {
return new CloseableIteratorWrapper(
new ScannerClosableWrapper(
scanner),
it);
}
protected Iterator initIterator(
final AdapterStore adapterStore,
final ScannerBase scanner ) {
return new AccumuloEntryIteratorWrapper(
useWholeRowIterator(),
adapterStore,
index,
scanner.iterator(),
clientFilters.isEmpty() ? null : clientFilters.size() == 1 ? clientFilters.get(0)
: new FilterList<QueryFilter>(
clientFilters),
scanCallback);
}
}