You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by jp...@apache.org on 2019/07/09 15:05:37 UTC

[lucene-solr] 02/02: LUCENE-8900: Simplify MultiSorter.

This is an automated email from the ASF dual-hosted git repository.

jpountz pushed a commit to branch branch_8x
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit aad4b411cdd2d517328a2444147b407d4a38343d
Author: Adrien Grand <jp...@gmail.com>
AuthorDate: Tue Jul 9 16:18:47 2019 +0200

    LUCENE-8900: Simplify MultiSorter.
---
 .../java/org/apache/lucene/index/MultiSorter.java  | 161 ++++-----------------
 1 file changed, 30 insertions(+), 131 deletions(-)

diff --git a/lucene/core/src/java/org/apache/lucene/index/MultiSorter.java b/lucene/core/src/java/org/apache/lucene/index/MultiSorter.java
index d81ac75..2348701 100644
--- a/lucene/core/src/java/org/apache/lucene/index/MultiSorter.java
+++ b/lucene/core/src/java/org/apache/lucene/index/MultiSorter.java
@@ -25,11 +25,11 @@ import org.apache.lucene.search.Sort;
 import org.apache.lucene.search.SortField;
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.LongValues;
+import org.apache.lucene.util.NumericUtils;
 import org.apache.lucene.util.PriorityQueue;
 import org.apache.lucene.util.packed.PackedInts;
 import org.apache.lucene.util.packed.PackedLongValues;
 
-@SuppressWarnings({"unchecked","rawtypes"})
 final class MultiSorter {
   
   /** 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
         public boolean lessThan(LeafAndDocID a, LeafAndDocID b) {
           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) {
-              return cmp < 0;
+              return reverseMuls[i] * cmp < 0;
             }
           }
 
@@ -74,8 +74,7 @@ final class MultiSorter {
       CodecReader reader = readers.get(i);
       LeafAndDocID leaf = new LeafAndDocID(i, reader.getLiveDocs(), reader.maxDoc(), comparables.length);
       for(int j=0;j<comparables.length;j++) {
-        leaf.values[j] = comparables[j][i].getComparable(leaf.docID);
-        assert leaf.values[j] != null;
+        leaf.valuesAsComparableLongs[j] = comparables[j][i].getAsComparableLong(leaf.docID);
       }
       queue.add(leaf);
       builders[i] = PackedLongValues.monotonicBuilder(PackedInts.COMPACT);
@@ -99,8 +98,7 @@ final class MultiSorter {
       top.docID++;
       if (top.docID < top.maxDoc) {
         for(int j=0;j<comparables.length;j++) {
-          top.values[j] = comparables[j][top.readerIndex].getComparable(top.docID);
-          assert top.values[j] != null;
+          top.valuesAsComparableLongs[j] = comparables[j][top.readerIndex].getAsComparableLong(top.docID);
         }
         queue.updateTop();
       } else {
@@ -134,20 +132,21 @@ final class MultiSorter {
     final int readerIndex;
     final Bits liveDocs;
     final int maxDoc;
-    final Comparable[] values;
+    final long[] valuesAsComparableLongs;
     int docID;
 
     public LeafAndDocID(int readerIndex, Bits liveDocs, int maxDoc, int numComparables) {
       this.readerIndex = readerIndex;
       this.liveDocs = liveDocs;
       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 {
-    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. */
@@ -178,26 +177,11 @@ final class MultiSorter {
           final SortedDocValues readerValues = values[readerIndex];
           final LongValues globalOrds = ordinalMap.getGlobalOrds(readerIndex);
           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 = readerValues.docID();
-                if (readerDocID < docID) {
-                  readerDocID = readerValues.advance(docID);
-                }
-                if (readerDocID == docID) {
+              public long getAsComparableLong(int docID) throws IOException {
+                if (readerValues.advanceExact(docID)) {
                   // translate segment's ord to global ord space:
-                  return Math.toIntExact(globalOrds.get(readerValues.ordValue()));
+                  return globalOrds.get(readerValues.ordValue());
                 } else {
                   return missingOrd;
                 }
@@ -208,10 +192,11 @@ final class MultiSorter {
       break;
 
     case LONG:
+    case INT:
       {
-        final Long missingValue;
+        final long missingValue;
         if (sortField.getMissingValue() != null) {
-          missingValue = (Long) sortField.getMissingValue();
+          missingValue = ((Number) sortField.getMissingValue()).longValue();
         } else {
           missingValue = 0L;
         }
@@ -220,24 +205,9 @@ final class MultiSorter {
           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) {
+              public long getAsComparableLong(int docID) throws IOException {
+                if (values.advanceExact(docID)) {
                   return values.longValue();
                 } else {
                   return missingValue;
@@ -248,50 +218,9 @@ final class MultiSorter {
       }
       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:
       {
-        final Double missingValue;
+        final double missingValue;
         if (sortField.getMissingValue() != null) {
           missingValue = (Double) sortField.getMissingValue();
         } else {
@@ -302,28 +231,13 @@ final class MultiSorter {
           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 Double.longBitsToDouble(values.longValue());
-                } else {
-                  return missingValue;
+              public long getAsComparableLong(int docID) throws IOException {
+                double value = missingValue;
+                if (values.advanceExact(docID)) {
+                  value = Double.longBitsToDouble(values.longValue());
                 }
+                return NumericUtils.doubleToSortableLong(value);
               }
             };
         }
@@ -332,7 +246,7 @@ final class MultiSorter {
 
     case FLOAT:
       {
-        final Float missingValue;
+        final float missingValue;
         if (sortField.getMissingValue() != null) {
           missingValue = (Float) sortField.getMissingValue();
         } else {
@@ -343,28 +257,13 @@ final class MultiSorter {
           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 Float.intBitsToFloat((int) values.longValue());
-                } else {
-                  return missingValue;
+              public long getAsComparableLong(int docID) throws IOException {
+                float value = missingValue;
+                if (values.advanceExact(docID)) {
+                  value = Float.intBitsToFloat((int) values.longValue());
                 }
+                return NumericUtils.floatToSortableInt(value);
               }
             };
         }