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); } } }