not delete filter improvements

- don't check no null for liveDocs, since we know they are not null with the check for hasDeletion
- improve iteration over liveDocs vs. innerSet, prefer to iterate over the faster one
This commit is contained in:
Shay Banon 2012-12-04 02:00:36 +01:00
parent 6cfd938dce
commit c36638d159
2 changed files with 49 additions and 11 deletions

View File

@ -23,13 +23,8 @@ import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.Filter;
/**
*
* We still need sometimes to exclude deletes, because we don't remove them always with acceptDocs on filters
*/
// LUCENE MONITOR: Against ConstantScoreQuery, basically added logic in the doc iterator to take deletions into account
// So it can basically be cached safely even with a reader that changes deletions but remain with teh same cache key
// See more: https://issues.apache.org/jira/browse/LUCENE-2468
// TODO Lucene 4.0 won't need this, since live docs are "and'ed" while scoring
// LUCENE 4 UPGRADE: we probably don't need this anymore, because of acceptDocs
public class DeletionAwareConstantScoreQuery extends ConstantScoreQuery {
private final Filter actualFilter;

View File

@ -25,6 +25,7 @@ import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.FilteredDocIdSetIterator;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.FixedBitSet;
import org.elasticsearch.common.lucene.docset.DocIdSets;
import java.io.IOException;
@ -64,7 +65,6 @@ public class NotDeletedFilter extends Filter {
static class NotDeletedDocIdSet extends DocIdSet {
private final DocIdSet innerSet;
private final Bits liveDocs;
NotDeletedDocIdSet(DocIdSet innerSet, Bits liveDocs) {
@ -72,8 +72,30 @@ public class NotDeletedFilter extends Filter {
this.liveDocs = liveDocs;
}
@Override
public boolean isCacheable() {
return innerSet.isCacheable();
}
@Override
public Bits bits() throws IOException {
Bits bits = innerSet.bits();
if (bits == null) {
return null;
}
return new NotDeleteBits(bits, liveDocs);
}
@Override
public DocIdSetIterator iterator() throws IOException {
if (!DocIdSets.isFastIterator(innerSet) && liveDocs instanceof FixedBitSet) {
// might as well iterate over the live docs..., since the iterator is not fast enough
// but we can only do that if we have Bits..., in short, we reverse the order...
Bits bits = innerSet.bits();
if (bits != null) {
return new NotDeletedDocIdSetIterator(((FixedBitSet) liveDocs).iterator(), bits);
}
}
DocIdSetIterator iterator = innerSet.iterator();
if (iterator == null) {
return null;
@ -82,18 +104,39 @@ public class NotDeletedFilter extends Filter {
}
}
static class NotDeletedDocIdSetIterator extends FilteredDocIdSetIterator {
static class NotDeleteBits implements Bits {
private final Bits bits;
private final Bits liveDocs;
NotDeletedDocIdSetIterator(DocIdSetIterator innerIter, Bits liveDocs) {
super(innerIter);
NotDeleteBits(Bits bits, Bits liveDocs) {
this.bits = bits;
this.liveDocs = liveDocs;
}
@Override
public boolean get(int index) {
return liveDocs.get(index) && bits.get(index);
}
@Override
public int length() {
return bits.length();
}
}
static class NotDeletedDocIdSetIterator extends FilteredDocIdSetIterator {
private final Bits match;
NotDeletedDocIdSetIterator(DocIdSetIterator innerIter, Bits match) {
super(innerIter);
this.match = match;
}
@Override
protected boolean match(int doc) {
return liveDocs == null || liveDocs.get(doc);
return match.get(doc);
}
}
}