Skip to content

Commit

Permalink
Implement filtering functionality in DocComparator
Browse files Browse the repository at this point in the history
  • Loading branch information
mayya-sharipova committed Aug 20, 2020
1 parent 5fcddf7 commit 8616330
Show file tree
Hide file tree
Showing 10 changed files with 282 additions and 286 deletions.
74 changes: 7 additions & 67 deletions lucene/core/src/java/org/apache/lucene/search/FieldComparator.java
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,13 @@ public int compareValues(T first, T second) {
}
}

/**
* Informs the comparator that sorting is done in reverse.
* This is necessary only for skipping functionality.
*/
public void setReverse() {
}


/**
* Base FieldComparator class for numeric types
Expand Down Expand Up @@ -485,73 +492,6 @@ public int compareTop(int doc) throws IOException {
return Float.compare(docValue, topValue);
}
}

/** Sorts by ascending docID */
public static final class DocComparator extends FieldComparator<Integer> implements LeafFieldComparator {
private final int[] docIDs;
private int docBase;
private int bottom;
private int topValue;

/** Creates a new comparator based on document ids for {@code numHits} */
public DocComparator(int numHits) {
docIDs = new int[numHits];
}

@Override
public int compare(int slot1, int slot2) {
// No overflow risk because docIDs are non-negative
return docIDs[slot1] - docIDs[slot2];
}

@Override
public int compareBottom(int doc) {
// No overflow risk because docIDs are non-negative
return bottom - (docBase + doc);
}

@Override
public void copy(int slot, int doc) {
docIDs[slot] = docBase + doc;
}

@Override
public LeafFieldComparator getLeafComparator(LeafReaderContext context) {
// TODO: can we "map" our docIDs to the current
// reader? saves having to then subtract on every
// compare call
this.docBase = context.docBase;
return this;
}

@Override
public void setBottom(final int bottom) {
this.bottom = docIDs[bottom];
}

@Override
public void setTopValue(Integer value) {
topValue = value;
}

public int getTopValue() {
return topValue;
}

@Override
public Integer value(int slot) {
return Integer.valueOf(docIDs[slot]);
}

@Override
public int compareTop(int doc) {
int docValue = docBase + doc;
return Integer.compare(topValue, docValue);
}

@Override
public void setScorer(Scorable scorer) {}
}

/** Sorts by field's natural Term sort order, using
* ordinals. This is functionally equivalent to {@link
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ private static final class OneComparatorFieldValueHitQueue<T extends FieldValueH
private final int oneReverseMul;
private final FieldComparator<?> oneComparator;

public OneComparatorFieldValueHitQueue(SortField[] fields, int size, boolean filterNonCompetitiveDocs, boolean hasAfter) {
super(fields, size, filterNonCompetitiveDocs, hasAfter);
public OneComparatorFieldValueHitQueue(SortField[] fields, int size, boolean filterNonCompetitiveDocs) {
super(fields, size, filterNonCompetitiveDocs);

assert fields.length == 1;
oneComparator = comparators[0];
Expand Down Expand Up @@ -95,8 +95,8 @@ protected boolean lessThan(final Entry hitA, final Entry hitB) {
*/
private static final class MultiComparatorsFieldValueHitQueue<T extends FieldValueHitQueue.Entry> extends FieldValueHitQueue<T> {

public MultiComparatorsFieldValueHitQueue(SortField[] fields, int size, boolean filterNonCompetitiveDocs, boolean hasAfter) {
super(fields, size, filterNonCompetitiveDocs, hasAfter);
public MultiComparatorsFieldValueHitQueue(SortField[] fields, int size, boolean filterNonCompetitiveDocs) {
super(fields, size, filterNonCompetitiveDocs);
}

@Override
Expand All @@ -119,9 +119,9 @@ protected boolean lessThan(final Entry hitA, final Entry hitB) {
}

}

// prevent instantiation and extension.
private FieldValueHitQueue(SortField[] fields, int size, boolean filterNonCompetitiveDocs, boolean hasAfter) {
private FieldValueHitQueue(SortField[] fields, int size, boolean filterNonCompetitiveDocs) {
super(size);
// When we get here, fields.length is guaranteed to be > 0, therefore no
// need to check it again.
Expand All @@ -140,10 +140,11 @@ private FieldValueHitQueue(SortField[] fields, int size, boolean filterNonCompet
// try to rewrite the 1st comparator to the comparator that can skip non-competitive documents
// skipping functionality is beneficial only for the 1st comparator
comparators[i] = FilteringFieldComparator.wrapToFilteringComparator(field.getComparator(size, i),
field.reverse, numComparators == 1, hasAfter);
field.reverse, numComparators == 1);
} else {
comparators[i] = field.getComparator(size, i);
}
if (field.reverse) comparators[i].setReverse();
}
}

Expand All @@ -160,20 +161,18 @@ private FieldValueHitQueue(SortField[] fields, int size, boolean filterNonCompet
* The number of hits to retain. Must be greater than zero.
* @param filterNonCompetitiveDocs
* {@code true} If comparators should be allowed to filter non-competitive documents, {@code false} otherwise
* @param hasAfter
* {@code true} If this sort has "after" FieldDoc
*/
public static <T extends FieldValueHitQueue.Entry> FieldValueHitQueue<T> create(SortField[] fields, int size,
boolean filterNonCompetitiveDocs, boolean hasAfter) {
boolean filterNonCompetitiveDocs) {

if (fields.length == 0) {
throw new IllegalArgumentException("Sort must contain at least one field");
}

if (fields.length == 1) {
return new OneComparatorFieldValueHitQueue<>(fields, size, filterNonCompetitiveDocs, hasAfter);
return new OneComparatorFieldValueHitQueue<>(fields, size, filterNonCompetitiveDocs);
} else {
return new MultiComparatorsFieldValueHitQueue<>(fields, size, filterNonCompetitiveDocs, hasAfter);
return new MultiComparatorsFieldValueHitQueue<>(fields, size, filterNonCompetitiveDocs);
}
}

Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,10 @@ public int compareValues(T first, T second) {
* @param comparator – comparator to wrap
* @param reverse – if this sort is reverse
* @param singleSort – true if this sort is based on a single field and there are no other sort fields for tie breaking
* @param hasAfter – true if this sort has after FieldDoc
* @return comparator wrapped as a filtering comparator or the original comparator if the filtering functionality
* is not implemented for it
*/
public static FieldComparator<?> wrapToFilteringComparator(FieldComparator<?> comparator, boolean reverse, boolean singleSort,
boolean hasAfter) {
public static FieldComparator<?> wrapToFilteringComparator(FieldComparator<?> comparator, boolean reverse, boolean singleSort) {
Class<?> comparatorClass = comparator.getClass();
if (comparatorClass == FieldComparator.LongComparator.class){
return new FilteringNumericComparator<>((FieldComparator.LongComparator) comparator, reverse, singleSort);
Expand All @@ -87,9 +85,6 @@ public static FieldComparator<?> wrapToFilteringComparator(FieldComparator<?> co
if (comparatorClass == FieldComparator.FloatComparator.class){
return new FilteringNumericComparator<>((FieldComparator.FloatComparator) comparator, reverse, singleSort);
}
if (comparatorClass == FieldComparator.DocComparator.class && hasAfter && reverse == false) { // if SortField.DOC with after
return new FilteringAfterDocComparator<>((FieldComparator.DocComparator) comparator, reverse, singleSort);
}
return comparator;
}

Expand Down
3 changes: 2 additions & 1 deletion lucene/core/src/java/org/apache/lucene/search/SortField.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.IndexSorter;
import org.apache.lucene.index.SortFieldProvider;
import org.apache.lucene.search.comparators.DocComparator;
import org.apache.lucene.store.DataInput;
import org.apache.lucene.store.DataOutput;
import org.apache.lucene.util.BytesRef;
Expand Down Expand Up @@ -452,7 +453,7 @@ public FieldComparator<?> getComparator(final int numHits, final int sortPos) {
return new FieldComparator.RelevanceComparator(numHits);

case DOC:
return new FieldComparator.DocComparator(numHits);
return new DocComparator(numHits);

case INT:
return new FieldComparator.IntComparator(numHits, field, (Integer) missingValue);
Expand Down
Loading

0 comments on commit 8616330

Please sign in to comment.