mirror of https://github.com/apache/lucene.git
LUCENE-8900: Simplify MultiSorter.
This commit is contained in:
parent
cfac486afd
commit
17f2f96a5c
|
@ -25,11 +25,11 @@ import org.apache.lucene.search.Sort;
|
||||||
import org.apache.lucene.search.SortField;
|
import org.apache.lucene.search.SortField;
|
||||||
import org.apache.lucene.util.Bits;
|
import org.apache.lucene.util.Bits;
|
||||||
import org.apache.lucene.util.LongValues;
|
import org.apache.lucene.util.LongValues;
|
||||||
|
import org.apache.lucene.util.NumericUtils;
|
||||||
import org.apache.lucene.util.PriorityQueue;
|
import org.apache.lucene.util.PriorityQueue;
|
||||||
import org.apache.lucene.util.packed.PackedInts;
|
import org.apache.lucene.util.packed.PackedInts;
|
||||||
import org.apache.lucene.util.packed.PackedLongValues;
|
import org.apache.lucene.util.packed.PackedLongValues;
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked","rawtypes"})
|
|
||||||
final class MultiSorter {
|
final class MultiSorter {
|
||||||
|
|
||||||
/** Does a merge sort of the leaves of the incoming reader, returning {@link DocMap} to map each leaf's
|
/** Does a merge sort of the leaves of the incoming reader, returning {@link DocMap} to map each leaf's
|
||||||
|
@ -53,9 +53,9 @@ final class MultiSorter {
|
||||||
@Override
|
@Override
|
||||||
public boolean lessThan(LeafAndDocID a, LeafAndDocID b) {
|
public boolean lessThan(LeafAndDocID a, LeafAndDocID b) {
|
||||||
for(int i=0;i<comparables.length;i++) {
|
for(int i=0;i<comparables.length;i++) {
|
||||||
int cmp = reverseMuls[i] * a.values[i].compareTo(b.values[i]);
|
int cmp = Long.compare(a.valuesAsComparableLongs[i], b.valuesAsComparableLongs[i]);
|
||||||
if (cmp != 0) {
|
if (cmp != 0) {
|
||||||
return cmp < 0;
|
return reverseMuls[i] * cmp < 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,8 +74,7 @@ final class MultiSorter {
|
||||||
CodecReader reader = readers.get(i);
|
CodecReader reader = readers.get(i);
|
||||||
LeafAndDocID leaf = new LeafAndDocID(i, reader.getLiveDocs(), reader.maxDoc(), comparables.length);
|
LeafAndDocID leaf = new LeafAndDocID(i, reader.getLiveDocs(), reader.maxDoc(), comparables.length);
|
||||||
for(int j=0;j<comparables.length;j++) {
|
for(int j=0;j<comparables.length;j++) {
|
||||||
leaf.values[j] = comparables[j][i].getComparable(leaf.docID);
|
leaf.valuesAsComparableLongs[j] = comparables[j][i].getAsComparableLong(leaf.docID);
|
||||||
assert leaf.values[j] != null;
|
|
||||||
}
|
}
|
||||||
queue.add(leaf);
|
queue.add(leaf);
|
||||||
builders[i] = PackedLongValues.monotonicBuilder(PackedInts.COMPACT);
|
builders[i] = PackedLongValues.monotonicBuilder(PackedInts.COMPACT);
|
||||||
|
@ -99,8 +98,7 @@ final class MultiSorter {
|
||||||
top.docID++;
|
top.docID++;
|
||||||
if (top.docID < top.maxDoc) {
|
if (top.docID < top.maxDoc) {
|
||||||
for(int j=0;j<comparables.length;j++) {
|
for(int j=0;j<comparables.length;j++) {
|
||||||
top.values[j] = comparables[j][top.readerIndex].getComparable(top.docID);
|
top.valuesAsComparableLongs[j] = comparables[j][top.readerIndex].getAsComparableLong(top.docID);
|
||||||
assert top.values[j] != null;
|
|
||||||
}
|
}
|
||||||
queue.updateTop();
|
queue.updateTop();
|
||||||
} else {
|
} else {
|
||||||
|
@ -134,20 +132,21 @@ final class MultiSorter {
|
||||||
final int readerIndex;
|
final int readerIndex;
|
||||||
final Bits liveDocs;
|
final Bits liveDocs;
|
||||||
final int maxDoc;
|
final int maxDoc;
|
||||||
final Comparable[] values;
|
final long[] valuesAsComparableLongs;
|
||||||
int docID;
|
int docID;
|
||||||
|
|
||||||
public LeafAndDocID(int readerIndex, Bits liveDocs, int maxDoc, int numComparables) {
|
public LeafAndDocID(int readerIndex, Bits liveDocs, int maxDoc, int numComparables) {
|
||||||
this.readerIndex = readerIndex;
|
this.readerIndex = readerIndex;
|
||||||
this.liveDocs = liveDocs;
|
this.liveDocs = liveDocs;
|
||||||
this.maxDoc = maxDoc;
|
this.maxDoc = maxDoc;
|
||||||
this.values = new Comparable[numComparables];
|
this.valuesAsComparableLongs = new long[numComparables];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns an object for this docID whose .compareTo represents the requested {@link SortField} sort order. */
|
/** Returns a long so that the natural ordering of long values matches the
|
||||||
|
* ordering of doc IDs for the given comparator. */
|
||||||
private interface ComparableProvider {
|
private interface ComparableProvider {
|
||||||
Comparable getComparable(int docID) throws IOException;
|
long getAsComparableLong(int docID) throws IOException;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns {@code ComparableProvider}s for the provided readers to represent the requested {@link SortField} sort order. */
|
/** Returns {@code ComparableProvider}s for the provided readers to represent the requested {@link SortField} sort order. */
|
||||||
|
@ -178,26 +177,11 @@ final class MultiSorter {
|
||||||
final SortedDocValues readerValues = values[readerIndex];
|
final SortedDocValues readerValues = values[readerIndex];
|
||||||
final LongValues globalOrds = ordinalMap.getGlobalOrds(readerIndex);
|
final LongValues globalOrds = ordinalMap.getGlobalOrds(readerIndex);
|
||||||
providers[readerIndex] = new ComparableProvider() {
|
providers[readerIndex] = new ComparableProvider() {
|
||||||
// used only by assert:
|
|
||||||
int lastDocID = -1;
|
|
||||||
private boolean docsInOrder(int docID) {
|
|
||||||
if (docID < lastDocID) {
|
|
||||||
throw new AssertionError("docs must be sent in order, but lastDocID=" + lastDocID + " vs docID=" + docID);
|
|
||||||
}
|
|
||||||
lastDocID = docID;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Comparable getComparable(int docID) throws IOException {
|
public long getAsComparableLong(int docID) throws IOException {
|
||||||
assert docsInOrder(docID);
|
if (readerValues.advanceExact(docID)) {
|
||||||
int readerDocID = readerValues.docID();
|
|
||||||
if (readerDocID < docID) {
|
|
||||||
readerDocID = readerValues.advance(docID);
|
|
||||||
}
|
|
||||||
if (readerDocID == docID) {
|
|
||||||
// translate segment's ord to global ord space:
|
// translate segment's ord to global ord space:
|
||||||
return Math.toIntExact(globalOrds.get(readerValues.ordValue()));
|
return globalOrds.get(readerValues.ordValue());
|
||||||
} else {
|
} else {
|
||||||
return missingOrd;
|
return missingOrd;
|
||||||
}
|
}
|
||||||
|
@ -208,10 +192,11 @@ final class MultiSorter {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LONG:
|
case LONG:
|
||||||
|
case INT:
|
||||||
{
|
{
|
||||||
final Long missingValue;
|
final long missingValue;
|
||||||
if (sortField.getMissingValue() != null) {
|
if (sortField.getMissingValue() != null) {
|
||||||
missingValue = (Long) sortField.getMissingValue();
|
missingValue = ((Number) sortField.getMissingValue()).longValue();
|
||||||
} else {
|
} else {
|
||||||
missingValue = 0L;
|
missingValue = 0L;
|
||||||
}
|
}
|
||||||
|
@ -220,24 +205,9 @@ final class MultiSorter {
|
||||||
final NumericDocValues values = Sorter.getOrWrapNumeric(readers.get(readerIndex), sortField);
|
final NumericDocValues values = Sorter.getOrWrapNumeric(readers.get(readerIndex), sortField);
|
||||||
|
|
||||||
providers[readerIndex] = new ComparableProvider() {
|
providers[readerIndex] = new ComparableProvider() {
|
||||||
// used only by assert:
|
|
||||||
int lastDocID = -1;
|
|
||||||
private boolean docsInOrder(int docID) {
|
|
||||||
if (docID < lastDocID) {
|
|
||||||
throw new AssertionError("docs must be sent in order, but lastDocID=" + lastDocID + " vs docID=" + docID);
|
|
||||||
}
|
|
||||||
lastDocID = docID;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Comparable getComparable(int docID) throws IOException {
|
public long getAsComparableLong(int docID) throws IOException {
|
||||||
assert docsInOrder(docID);
|
if (values.advanceExact(docID)) {
|
||||||
int readerDocID = values.docID();
|
|
||||||
if (readerDocID < docID) {
|
|
||||||
readerDocID = values.advance(docID);
|
|
||||||
}
|
|
||||||
if (readerDocID == docID) {
|
|
||||||
return values.longValue();
|
return values.longValue();
|
||||||
} else {
|
} else {
|
||||||
return missingValue;
|
return missingValue;
|
||||||
|
@ -248,50 +218,9 @@ final class MultiSorter {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INT:
|
|
||||||
{
|
|
||||||
final Integer missingValue;
|
|
||||||
if (sortField.getMissingValue() != null) {
|
|
||||||
missingValue = (Integer) sortField.getMissingValue();
|
|
||||||
} else {
|
|
||||||
missingValue = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int readerIndex=0;readerIndex<readers.size();readerIndex++) {
|
|
||||||
final NumericDocValues values = Sorter.getOrWrapNumeric(readers.get(readerIndex), sortField);
|
|
||||||
|
|
||||||
providers[readerIndex] = new ComparableProvider() {
|
|
||||||
// used only by assert:
|
|
||||||
int lastDocID = -1;
|
|
||||||
private boolean docsInOrder(int docID) {
|
|
||||||
if (docID < lastDocID) {
|
|
||||||
throw new AssertionError("docs must be sent in order, but lastDocID=" + lastDocID + " vs docID=" + docID);
|
|
||||||
}
|
|
||||||
lastDocID = docID;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Comparable getComparable(int docID) throws IOException {
|
|
||||||
assert docsInOrder(docID);
|
|
||||||
int readerDocID = values.docID();
|
|
||||||
if (readerDocID < docID) {
|
|
||||||
readerDocID = values.advance(docID);
|
|
||||||
}
|
|
||||||
if (readerDocID == docID) {
|
|
||||||
return (int) values.longValue();
|
|
||||||
} else {
|
|
||||||
return missingValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DOUBLE:
|
case DOUBLE:
|
||||||
{
|
{
|
||||||
final Double missingValue;
|
final double missingValue;
|
||||||
if (sortField.getMissingValue() != null) {
|
if (sortField.getMissingValue() != null) {
|
||||||
missingValue = (Double) sortField.getMissingValue();
|
missingValue = (Double) sortField.getMissingValue();
|
||||||
} else {
|
} else {
|
||||||
|
@ -302,28 +231,13 @@ final class MultiSorter {
|
||||||
final NumericDocValues values = Sorter.getOrWrapNumeric(readers.get(readerIndex), sortField);
|
final NumericDocValues values = Sorter.getOrWrapNumeric(readers.get(readerIndex), sortField);
|
||||||
|
|
||||||
providers[readerIndex] = new ComparableProvider() {
|
providers[readerIndex] = new ComparableProvider() {
|
||||||
// used only by assert:
|
|
||||||
int lastDocID = -1;
|
|
||||||
private boolean docsInOrder(int docID) {
|
|
||||||
if (docID < lastDocID) {
|
|
||||||
throw new AssertionError("docs must be sent in order, but lastDocID=" + lastDocID + " vs docID=" + docID);
|
|
||||||
}
|
|
||||||
lastDocID = docID;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Comparable getComparable(int docID) throws IOException {
|
public long getAsComparableLong(int docID) throws IOException {
|
||||||
assert docsInOrder(docID);
|
double value = missingValue;
|
||||||
int readerDocID = values.docID();
|
if (values.advanceExact(docID)) {
|
||||||
if (readerDocID < docID) {
|
value = Double.longBitsToDouble(values.longValue());
|
||||||
readerDocID = values.advance(docID);
|
|
||||||
}
|
|
||||||
if (readerDocID == docID) {
|
|
||||||
return Double.longBitsToDouble(values.longValue());
|
|
||||||
} else {
|
|
||||||
return missingValue;
|
|
||||||
}
|
}
|
||||||
|
return NumericUtils.doubleToSortableLong(value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -332,7 +246,7 @@ final class MultiSorter {
|
||||||
|
|
||||||
case FLOAT:
|
case FLOAT:
|
||||||
{
|
{
|
||||||
final Float missingValue;
|
final float missingValue;
|
||||||
if (sortField.getMissingValue() != null) {
|
if (sortField.getMissingValue() != null) {
|
||||||
missingValue = (Float) sortField.getMissingValue();
|
missingValue = (Float) sortField.getMissingValue();
|
||||||
} else {
|
} else {
|
||||||
|
@ -343,28 +257,13 @@ final class MultiSorter {
|
||||||
final NumericDocValues values = Sorter.getOrWrapNumeric(readers.get(readerIndex), sortField);
|
final NumericDocValues values = Sorter.getOrWrapNumeric(readers.get(readerIndex), sortField);
|
||||||
|
|
||||||
providers[readerIndex] = new ComparableProvider() {
|
providers[readerIndex] = new ComparableProvider() {
|
||||||
// used only by assert:
|
|
||||||
int lastDocID = -1;
|
|
||||||
private boolean docsInOrder(int docID) {
|
|
||||||
if (docID < lastDocID) {
|
|
||||||
throw new AssertionError("docs must be sent in order, but lastDocID=" + lastDocID + " vs docID=" + docID);
|
|
||||||
}
|
|
||||||
lastDocID = docID;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Comparable getComparable(int docID) throws IOException {
|
public long getAsComparableLong(int docID) throws IOException {
|
||||||
assert docsInOrder(docID);
|
float value = missingValue;
|
||||||
int readerDocID = values.docID();
|
if (values.advanceExact(docID)) {
|
||||||
if (readerDocID < docID) {
|
value = Float.intBitsToFloat((int) values.longValue());
|
||||||
readerDocID = values.advance(docID);
|
|
||||||
}
|
|
||||||
if (readerDocID == docID) {
|
|
||||||
return Float.intBitsToFloat((int) values.longValue());
|
|
||||||
} else {
|
|
||||||
return missingValue;
|
|
||||||
}
|
}
|
||||||
|
return NumericUtils.floatToSortableInt(value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue