You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ho...@apache.org on 2015/08/04 01:13:23 UTC
svn commit: r1693979 - in /lucene/dev/trunk: lucene/
lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/
lucene/queries/src/test/org/apache/lucene/queries/function/
solr/core/src/test/org/apache/solr/cloud/ solr/core/src/test/org/ap...
Author: hossman
Date: Mon Aug 3 23:13:22 2015
New Revision: 1693979
URL: http://svn.apache.org/r1693979
Log:
LUCENE-6609: Add getSortField impls to many subclasses of FieldCacheSource which return the most direct SortField implementation
Modified:
lucene/dev/trunk/lucene/CHANGES.txt
lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/DoubleFieldSource.java
lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/FloatFieldSource.java
lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/IntFieldSource.java
lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/LongFieldSource.java
lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/SortedSetFieldSource.java
lucene/dev/trunk/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionQuerySort.java
lucene/dev/trunk/lucene/queries/src/test/org/apache/lucene/queries/function/TestSortedSetFieldSource.java
lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/DistribCursorPagingTest.java
lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/function/SortByFunctionTest.java
Modified: lucene/dev/trunk/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/CHANGES.txt?rev=1693979&r1=1693978&r2=1693979&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/CHANGES.txt (original)
+++ lucene/dev/trunk/lucene/CHANGES.txt Mon Aug 3 23:13:22 2015
@@ -370,6 +370,11 @@ Changes in Runtime Behavior
TestEarlyTerminatingSortingCollector.testTerminatedEarly test added.
(Christine Poerschke)
+* LUCENE-6609: Add getSortField impls to many subclasses of FieldCacheSource which return
+ the most direct SortField implementation. In many trivial sort by ValueSource usages, this
+ will result in less RAM, and more precise sorting of extreme values due to no longer
+ converting to double. (hossman)
+
Optimizations
* LUCENE-6548: Some optimizations for BlockTree's intersect with very
Modified: lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/DoubleFieldSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/DoubleFieldSource.java?rev=1693979&r1=1693978&r2=1693979&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/DoubleFieldSource.java (original)
+++ lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/DoubleFieldSource.java Mon Aug 3 23:13:22 2015
@@ -26,6 +26,8 @@ import org.apache.lucene.index.DocValues
import org.apache.lucene.index.NumericDocValues;
import org.apache.lucene.queries.function.FunctionValues;
import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.SortField.Type;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.mutable.MutableValue;
import org.apache.lucene.util.mutable.MutableValueDouble;
@@ -46,6 +48,11 @@ public class DoubleFieldSource extends F
}
@Override
+ public SortField getSortField(boolean reverse) {
+ return new SortField(field, Type.DOUBLE, reverse);
+ }
+
+ @Override
public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
final NumericDocValues arr = DocValues.getNumeric(readerContext.reader(), field);
final Bits valid = DocValues.getDocsWithField(readerContext.reader(), field);
Modified: lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/FloatFieldSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/FloatFieldSource.java?rev=1693979&r1=1693978&r2=1693979&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/FloatFieldSource.java (original)
+++ lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/FloatFieldSource.java Mon Aug 3 23:13:22 2015
@@ -25,6 +25,8 @@ import org.apache.lucene.index.DocValues
import org.apache.lucene.index.NumericDocValues;
import org.apache.lucene.queries.function.FunctionValues;
import org.apache.lucene.queries.function.docvalues.FloatDocValues;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.SortField.Type;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.mutable.MutableValue;
import org.apache.lucene.util.mutable.MutableValueFloat;
@@ -45,6 +47,11 @@ public class FloatFieldSource extends Fi
}
@Override
+ public SortField getSortField(boolean reverse) {
+ return new SortField(field, Type.FLOAT, reverse);
+ }
+
+ @Override
public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
final NumericDocValues arr = DocValues.getNumeric(readerContext.reader(), field);
final Bits valid = DocValues.getDocsWithField(readerContext.reader(), field);
Modified: lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/IntFieldSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/IntFieldSource.java?rev=1693979&r1=1693978&r2=1693979&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/IntFieldSource.java (original)
+++ lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/IntFieldSource.java Mon Aug 3 23:13:22 2015
@@ -25,6 +25,8 @@ import org.apache.lucene.index.DocValues
import org.apache.lucene.index.NumericDocValues;
import org.apache.lucene.queries.function.FunctionValues;
import org.apache.lucene.queries.function.docvalues.IntDocValues;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.SortField.Type;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.mutable.MutableValue;
import org.apache.lucene.util.mutable.MutableValueInt;
@@ -44,7 +46,11 @@ public class IntFieldSource extends Fiel
return "int(" + field + ')';
}
-
+ @Override
+ public SortField getSortField(boolean reverse) {
+ return new SortField(field, Type.INT, reverse);
+ }
+
@Override
public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
final NumericDocValues arr = DocValues.getNumeric(readerContext.reader(), field);
Modified: lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/LongFieldSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/LongFieldSource.java?rev=1693979&r1=1693978&r2=1693979&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/LongFieldSource.java (original)
+++ lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/LongFieldSource.java Mon Aug 3 23:13:22 2015
@@ -25,6 +25,8 @@ import org.apache.lucene.index.DocValues
import org.apache.lucene.index.NumericDocValues;
import org.apache.lucene.queries.function.FunctionValues;
import org.apache.lucene.queries.function.docvalues.LongDocValues;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.SortField.Type;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.mutable.MutableValue;
import org.apache.lucene.util.mutable.MutableValueLong;
@@ -57,6 +59,11 @@ public class LongFieldSource extends Fie
}
@Override
+ public SortField getSortField(boolean reverse) {
+ return new SortField(field, Type.LONG, reverse);
+ }
+
+ @Override
public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
final NumericDocValues arr = DocValues.getNumeric(readerContext.reader(), field);
final Bits valid = DocValues.getDocsWithField(readerContext.reader(), field);
Modified: lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/SortedSetFieldSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/SortedSetFieldSource.java?rev=1693979&r1=1693978&r2=1693979&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/SortedSetFieldSource.java (original)
+++ lucene/dev/trunk/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/SortedSetFieldSource.java Mon Aug 3 23:13:22 2015
@@ -26,7 +26,9 @@ import org.apache.lucene.index.SortedDoc
import org.apache.lucene.index.SortedSetDocValues;
import org.apache.lucene.queries.function.FunctionValues;
import org.apache.lucene.queries.function.docvalues.DocTermsIndexDocValues;
+import org.apache.lucene.search.SortField;
import org.apache.lucene.search.SortedSetSelector;
+import org.apache.lucene.search.SortedSetSortField;
/**
* Retrieves {@link FunctionValues} instances for multi-valued string based fields.
@@ -47,7 +49,12 @@ public class SortedSetFieldSource extend
super(field);
this.selector = selector;
}
-
+
+ @Override
+ public SortField getSortField(boolean reverse) {
+ return new SortedSetSortField(this.field, reverse, this.selector);
+ }
+
@Override
public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
SortedSetDocValues sortedSet = DocValues.getSortedSet(readerContext.reader(), field);
Modified: lucene/dev/trunk/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionQuerySort.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionQuerySort.java?rev=1693979&r1=1693978&r2=1693979&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionQuerySort.java (original)
+++ lucene/dev/trunk/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionQuerySort.java Mon Aug 3 23:13:22 2015
@@ -26,7 +26,12 @@ import org.apache.lucene.document.Numeri
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.RandomIndexWriter;
+import org.apache.lucene.queries.function.valuesource.DoubleConstValueSource;
+import org.apache.lucene.queries.function.valuesource.DoubleFieldSource;
+import org.apache.lucene.queries.function.valuesource.FloatFieldSource;
import org.apache.lucene.queries.function.valuesource.IntFieldSource;
+import org.apache.lucene.queries.function.valuesource.LongFieldSource;
+import org.apache.lucene.queries.function.valuesource.SumFloatFunction;
import org.apache.lucene.search.FieldDoc;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchAllDocsQuery;
@@ -34,13 +39,63 @@ import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.SortField.Type;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.LuceneTestCase;
/** Test that functionquery's getSortField() actually works */
public class TestFunctionQuerySort extends LuceneTestCase {
+
+ public void testOptimizedFieldSourceFunctionSorting() throws IOException {
+ // index contents don't matter for this test.
+ Directory dir = newDirectory();
+ IndexWriterConfig iwc = newIndexWriterConfig(null);
+ RandomIndexWriter writer = new RandomIndexWriter(random(), dir, iwc);
+ IndexReader reader = writer.getReader();
+ writer.close();
+ IndexSearcher searcher = newSearcher(reader);
+ final boolean reverse = random().nextBoolean();
+ ValueSource vs;
+ SortField sf, vssf;
+
+ vs = new IntFieldSource("int_field");
+ sf = new SortField("int_field", Type.INT, reverse);
+ vssf = vs.getSortField(reverse);
+ assertEquals(sf, vssf);
+ sf = sf.rewrite(searcher);
+ vssf = vssf.rewrite(searcher);
+ assertEquals(sf, vssf);
+
+ vs = new FloatFieldSource("float_field");
+ sf = new SortField("float_field", Type.FLOAT, reverse);
+ vssf = vs.getSortField(reverse);
+ assertEquals(sf, vssf);
+ sf = sf.rewrite(searcher);
+ vssf = vssf.rewrite(searcher);
+ assertEquals(sf, vssf);
+
+ vs = new DoubleFieldSource("double_field");
+ sf = new SortField("double_field", Type.DOUBLE, reverse);
+ vssf = vs.getSortField(reverse);
+ assertEquals(sf, vssf);
+ sf = sf.rewrite(searcher);
+ vssf = vssf.rewrite(searcher);
+ assertEquals(sf, vssf);
+
+ vs = new LongFieldSource("long_field");
+ sf = new SortField("long_field", Type.LONG, reverse);
+ vssf = vs.getSortField(reverse);
+ assertEquals(sf, vssf);
+ sf = sf.rewrite(searcher);
+ vssf = vssf.rewrite(searcher);
+ assertEquals(sf, vssf);
+
+ reader.close();
+ dir.close();
+ }
+
public void testSearchAfterWhenSortingByFunctionValues() throws IOException {
Directory dir = newDirectory();
IndexWriterConfig iwc = newIndexWriterConfig(null);
@@ -66,8 +121,9 @@ public class TestFunctionQuerySort exten
writer.close();
IndexSearcher searcher = newSearcher(reader);
- // Get ValueSource from FieldCache
- IntFieldSource src = new IntFieldSource("value");
+ // Trivial ValueSource function that bypasses single field ValueSource sort optimization
+ ValueSource src = new SumFloatFunction(new ValueSource[] { new IntFieldSource("value"),
+ new DoubleConstValueSource(1.0D) });
// ...and make it a sort criterion
SortField sf = src.getSortField(false).rewrite(searcher);
Sort orderBy = new Sort(sf);
Modified: lucene/dev/trunk/lucene/queries/src/test/org/apache/lucene/queries/function/TestSortedSetFieldSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/queries/src/test/org/apache/lucene/queries/function/TestSortedSetFieldSource.java?rev=1693979&r1=1693978&r2=1693979&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/queries/src/test/org/apache/lucene/queries/function/TestSortedSetFieldSource.java (original)
+++ lucene/dev/trunk/lucene/queries/src/test/org/apache/lucene/queries/function/TestSortedSetFieldSource.java Mon Aug 3 23:13:22 2015
@@ -26,6 +26,9 @@ import org.apache.lucene.index.LeafReade
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queries.function.valuesource.SortedSetFieldSource;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.SortedSetSortField;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.LuceneTestCase;
@@ -47,12 +50,24 @@ public class TestSortedSetFieldSource ex
writer.close();
DirectoryReader ir = DirectoryReader.open(dir);
+ IndexSearcher searcher = newSearcher(ir);
LeafReader ar = getOnlySegmentReader(ir);
ValueSource vs = new SortedSetFieldSource("value");
FunctionValues values = vs.getValues(Collections.emptyMap(), ar.getContext());
assertEquals("baz", values.strVal(0));
- assertEquals("bar", values.strVal(1));
+ assertEquals("bar", values.strVal(1));
+
+ // test SortField optimization
+ final boolean reverse = random().nextBoolean();
+ SortField vssf = vs.getSortField(reverse);
+ SortField sf = new SortedSetSortField("value", reverse);
+ assertEquals(sf, vssf);
+
+ vssf = vssf.rewrite(searcher);
+ sf = sf.rewrite(searcher);
+ assertEquals(sf, vssf);
+
ir.close();
dir.close();
}
Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/DistribCursorPagingTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/DistribCursorPagingTest.java?rev=1693979&r1=1693978&r2=1693979&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/DistribCursorPagingTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/DistribCursorPagingTest.java Mon Aug 3 23:13:22 2015
@@ -376,50 +376,54 @@ public class DistribCursorPagingTest ext
assertEquals("no more docs, but cursorMark has changed",
cursorMark, assertHashNextCursorMark(rsp));
- // tri-level sort with more dups of primary then fit on a page
- cursorMark = CURSOR_MARK_START;
- params = params("q", "*:*",
- "rows","2",
- "fl", "id",
- "sort", "float asc, "+intsort+" desc, id desc");
- rsp = query(p(params, CURSOR_MARK_PARAM, cursorMark));
- assertNumFound(10, rsp);
- assertStartsAt(0, rsp);
- assertDocList(rsp, 2, 9);
- cursorMark = assertHashNextCursorMark(rsp);
- //
- rsp = query(p(params, CURSOR_MARK_PARAM, cursorMark));
- assertNumFound(10, rsp);
- assertStartsAt(0, rsp);
- assertDocList(rsp, 7, 4);
- cursorMark = assertHashNextCursorMark(rsp);
- //
- rsp = query(p(params, CURSOR_MARK_PARAM, cursorMark));
- assertNumFound(10, rsp);
- assertStartsAt(0, rsp);
- assertDocList(rsp, 3, 8);
- cursorMark = assertHashNextCursorMark(rsp);
- //
- rsp = query(p(params, CURSOR_MARK_PARAM, cursorMark));
- assertNumFound(10, rsp);
- assertStartsAt(0, rsp);
- assertDocList(rsp, 5, 6);
- cursorMark = assertHashNextCursorMark(rsp);
- //
- rsp = query(p(params, CURSOR_MARK_PARAM, cursorMark));
- assertNumFound(10, rsp);
- assertStartsAt(0, rsp);
- assertDocList(rsp, 1, 0);
- cursorMark = assertHashNextCursorMark(rsp);
- // we've exactly exhausted all the results, but solr had no way of know that
- //
- rsp = query(p(params, CURSOR_MARK_PARAM, cursorMark));
- assertNumFound(10, rsp);
- assertStartsAt(0, rsp);
- assertDocList(rsp);
- assertEquals("no more docs, but cursorMark has changed",
- cursorMark, assertHashNextCursorMark(rsp));
-
+ // tri-level sort with more dups of primary then fit on a page.
+ // also a function based sort using a simple function(s) on same field
+ // (order should be the same in all cases)
+ for (String primarysort : new String[] { "float", "field('float')", "sum(float,42)" }) {
+ cursorMark = CURSOR_MARK_START;
+ params = params("q", "*:*",
+ "rows","2",
+ "fl", "id",
+ "sort", primarysort + " asc, "+intsort+" desc, id desc");
+ rsp = query(p(params, CURSOR_MARK_PARAM, cursorMark));
+ assertNumFound(10, rsp);
+ assertStartsAt(0, rsp);
+ assertDocList(rsp, 2, 9);
+ cursorMark = assertHashNextCursorMark(rsp);
+ //
+ rsp = query(p(params, CURSOR_MARK_PARAM, cursorMark));
+ assertNumFound(10, rsp);
+ assertStartsAt(0, rsp);
+ assertDocList(rsp, 7, 4);
+ cursorMark = assertHashNextCursorMark(rsp);
+ //
+ rsp = query(p(params, CURSOR_MARK_PARAM, cursorMark));
+ assertNumFound(10, rsp);
+ assertStartsAt(0, rsp);
+ assertDocList(rsp, 3, 8);
+ cursorMark = assertHashNextCursorMark(rsp);
+ //
+ rsp = query(p(params, CURSOR_MARK_PARAM, cursorMark));
+ assertNumFound(10, rsp);
+ assertStartsAt(0, rsp);
+ assertDocList(rsp, 5, 6);
+ cursorMark = assertHashNextCursorMark(rsp);
+ //
+ rsp = query(p(params, CURSOR_MARK_PARAM, cursorMark));
+ assertNumFound(10, rsp);
+ assertStartsAt(0, rsp);
+ assertDocList(rsp, 1, 0);
+ cursorMark = assertHashNextCursorMark(rsp);
+ // we've exactly exhausted all the results, but solr had no way of know that
+ //
+ rsp = query(p(params, CURSOR_MARK_PARAM, cursorMark));
+ assertNumFound(10, rsp);
+ assertStartsAt(0, rsp);
+ assertDocList(rsp);
+ assertEquals("no more docs, but cursorMark has changed",
+ cursorMark, assertHashNextCursorMark(rsp));
+ }
+
// trivial base case: rows bigger then number of matches
cursorMark = CURSOR_MARK_START;
params = params("q", "id:3 id:7",
Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/function/SortByFunctionTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/function/SortByFunctionTest.java?rev=1693979&r1=1693978&r2=1693979&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/function/SortByFunctionTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/function/SortByFunctionTest.java Mon Aug 3 23:13:22 2015
@@ -36,7 +36,8 @@ public class SortByFunctionTest extends
@Override
public void setUp() throws Exception {
super.setUp();
-
+ assertU(delQ("*:*"));
+ assertU(commit());
}
public void test() throws Exception {
@@ -128,4 +129,75 @@ public class SortByFunctionTest extends
"//result/doc[4]/int[@name='id'][.='1']"
);
}
+
+ /**
+ * Sort by function normally compares the double value, but if a function is specified that identifies
+ * a single field, we should use the underlying field's SortField to save of a lot of type converstion
+ * (and RAM), and keep the sort precision as high as possible
+ */
+ public void testFieldSortSpecifiedAsFunction() throws Exception {
+ final long A = Long.MIN_VALUE;
+ final long B = A + 1L;
+ final long C = B + 1L;
+
+ final long Z = Long.MAX_VALUE;
+ final long Y = Z - 1L;
+ final long X = Y - 1L;
+
+ // test is predicated on the idea that if long -> double converstion is happening under the hood
+ // then we lose precision in sorting; so lets sanity check that our JVM isn't doing something wacky
+ // in converstion that violates the principle of the test
+
+ assertEquals("WTF? small longs cast to double aren't equivilent?",
+ (double)A, (double)B, 0.0D);
+ assertEquals("WTF? small longs cast to double aren't equivilent?",
+ (double)A, (double)C, 0.0D);
+
+ assertEquals("WTF? big longs cast to double aren't equivilent?",
+ (double)Z, (double)Y, 0.0D);
+ assertEquals("WTF? big longs cast to double aren't equivilent?",
+ (double)Z, (double)X, 0.0D);
+
+ int docId = 0;
+ for (int i = 0; i < 3; i++) {
+ assertU(adoc(sdoc("id", ++docId, "primary_tl1", X, "secondary_tl1", i,
+ "multi_l_dv", X, "multi_l_dv", A)));
+ assertU(adoc(sdoc("id", ++docId, "primary_tl1", Y, "secondary_tl1", i,
+ "multi_l_dv", Y, "multi_l_dv", B)));
+ assertU(adoc(sdoc("id", ++docId, "primary_tl1", Z, "secondary_tl1", i,
+ "multi_l_dv", Z, "multi_l_dv", C)));
+ }
+ assertU(commit());
+
+ // all of these sorts should result in the exact same order
+ for (String primarySort : new String[] { "primary_tl1", "field(primary_tl1)",
+ "field(multi_l_dv,max)", "field(multi_l_dv,min)" }) {
+ assertQ(req("q", "*:*",
+ "sort", primarySort + " asc, secondary_tl1 asc")
+ , "//*[@numFound='9']"
+ //
+ , "//result/doc[1]/long[@name='primary_tl1'][.='"+X+"']"
+ , "//result/doc[1]/long[@name='secondary_tl1'][.='0']"
+ , "//result/doc[2]/long[@name='primary_tl1'][.='"+X+"']"
+ , "//result/doc[2]/long[@name='secondary_tl1'][.='1']"
+ , "//result/doc[3]/long[@name='primary_tl1'][.='"+X+"']"
+ , "//result/doc[3]/long[@name='secondary_tl1'][.='2']"
+ //
+ , "//result/doc[4]/long[@name='primary_tl1'][.='"+Y+"']"
+ , "//result/doc[4]/long[@name='secondary_tl1'][.='0']"
+ , "//result/doc[5]/long[@name='primary_tl1'][.='"+Y+"']"
+ , "//result/doc[5]/long[@name='secondary_tl1'][.='1']"
+ , "//result/doc[6]/long[@name='primary_tl1'][.='"+Y+"']"
+ , "//result/doc[6]/long[@name='secondary_tl1'][.='2']"
+ //
+ , "//result/doc[7]/long[@name='primary_tl1'][.='"+Z+"']"
+ , "//result/doc[7]/long[@name='secondary_tl1'][.='0']"
+ , "//result/doc[8]/long[@name='primary_tl1'][.='"+Z+"']"
+ , "//result/doc[8]/long[@name='secondary_tl1'][.='1']"
+ , "//result/doc[9]/long[@name='primary_tl1'][.='"+Z+"']"
+ , "//result/doc[9]/long[@name='secondary_tl1'][.='2']"
+ );
+ }
+ }
+
}