package com.browseengine.bobo.facets.filter;
import java.io.IOException;
import org.apache.lucene.search.DocIdSetIterator;
import com.browseengine.bobo.api.BoboSegmentReader;
import com.browseengine.bobo.docidset.EmptyDocIdSet;
import com.browseengine.bobo.docidset.RandomAccessDocIdSet;
import com.browseengine.bobo.facets.FacetHandler;
import com.browseengine.bobo.facets.data.FacetDataCache;
import com.browseengine.bobo.util.BigSegmentedArray;
public class FacetFilter extends RandomAccessFilter {
private final FacetHandler<FacetDataCache<?>> _facetHandler;
protected final String _value;
public FacetFilter(FacetHandler<FacetDataCache<?>> facetHandler, String value) {
_facetHandler = facetHandler;
_value = value;
}
@Override
public double getFacetSelectivity(BoboSegmentReader reader) {
double selectivity = 0;
FacetDataCache<?> dataCache = _facetHandler.getFacetData(reader);
int idx = dataCache.valArray.indexOf(_value);
if (idx < 0) {
return 0.0;
}
int freq = dataCache.freqs[idx];
int total = reader.maxDoc();
selectivity = (double) freq / (double) total;
return selectivity;
}
public static class FacetDocIdSetIterator extends DocIdSetIterator {
protected int _doc;
protected final int _index;
protected final int _maxID;
protected final BigSegmentedArray _orderArray;
public FacetDocIdSetIterator(FacetDataCache<?> dataCache, int index) {
_index = index;
_doc = Math.max(-1, dataCache.minIDs[_index] - 1);
_maxID = dataCache.maxIDs[_index];
_orderArray = dataCache.orderArray;
}
@Override
final public int docID() {
return _doc;
}
@Override
public int nextDoc() throws IOException {
return (_doc = (_doc < _maxID ? _orderArray.findValue(_index, (_doc + 1), _maxID)
: NO_MORE_DOCS));
}
@Override
public int advance(int id) throws IOException {
if (_doc < id) {
return (_doc = (id <= _maxID ? _orderArray.findValue(_index, id, _maxID) : NO_MORE_DOCS));
}
return nextDoc();
}
@Override
public long cost() {
// TODO Auto-generated method stub
return 0;
}
}
@Override
public RandomAccessDocIdSet getRandomAccessDocIdSet(BoboSegmentReader reader) throws IOException {
FacetDataCache<?> dataCache = _facetHandler.getFacetData(reader);
int index = dataCache.valArray.indexOf(_value);
if (index < 0) {
return EmptyDocIdSet.getInstance();
} else {
return new FacetDataRandomAccessDocIdSet(dataCache, index);
}
}
public static class FacetDataRandomAccessDocIdSet extends RandomAccessDocIdSet {
private final FacetDataCache<?> _dataCache;
private final BigSegmentedArray _orderArray;
private final int _index;
FacetDataRandomAccessDocIdSet(FacetDataCache<?> dataCache, int index) {
_dataCache = dataCache;
_orderArray = _dataCache.orderArray;
_index = index;
}
@Override
public boolean get(int docId) {
return _orderArray.get(docId) == _index;
}
@Override
public DocIdSetIterator iterator() throws IOException {
return new FacetDocIdSetIterator(_dataCache, _index);
}
}
}