private void testLeftOpenRange(int precisionStep) throws Exception {
    String field = "field" + precisionStep;
    int count = 3000;
    long upper = (count - 1) * distance + (distance / 3) + startOffset;
    LegacyNumericRangeQuery<Long> q =
        LegacyNumericRangeQuery.newLongRange(field, precisionStep, null, upper, true, true);
    TopDocs topDocs = searcher.search(q, noDocs, Sort.INDEXORDER);
    ScoreDoc[] sd = topDocs.scoreDocs;
    assertNotNull(sd);
    assertEquals("Score doc count", count, sd.length);
    Document doc = searcher.doc(sd[0].doc);
    assertEquals("First doc", startOffset, doc.getField(field).numericValue().longValue());
    doc = searcher.doc(sd[sd.length - 1].doc);
    assertEquals(
        "Last doc",
        (count - 1) * distance + startOffset,
        doc.getField(field).numericValue().longValue());

    q = LegacyNumericRangeQuery.newLongRange(field, precisionStep, null, upper, false, true);
    topDocs = searcher.search(q, noDocs, Sort.INDEXORDER);
    sd = topDocs.scoreDocs;
    assertNotNull(sd);
    assertEquals("Score doc count", count, sd.length);
    doc = searcher.doc(sd[0].doc);
    assertEquals("First doc", startOffset, doc.getField(field).numericValue().longValue());
    doc = searcher.doc(sd[sd.length - 1].doc);
    assertEquals(
        "Last doc",
        (count - 1) * distance + startOffset,
        doc.getField(field).numericValue().longValue());
  }
 @Test
 public void testOneMatchQuery() throws Exception {
   LegacyNumericRangeQuery<Long> q =
       LegacyNumericRangeQuery.newLongRange("ascfield8", 8, 1000L, 1000L, true, true);
   TopDocs topDocs = searcher.search(q, noDocs);
   ScoreDoc[] sd = topDocs.scoreDocs;
   assertNotNull(sd);
   assertEquals("Score doc count", 1, sd.length);
 }
 private void testRangeSplit(int precisionStep) throws Exception {
   String field = "ascfield" + precisionStep;
   // 10 random tests
   int num = TestUtil.nextInt(random(), 10, 20);
   for (int i = 0; i < num; i++) {
     long lower = (long) (random().nextDouble() * noDocs - noDocs / 2);
     long upper = (long) (random().nextDouble() * noDocs - noDocs / 2);
     if (lower > upper) {
       long a = lower;
       lower = upper;
       upper = a;
     }
     // test inclusive range
     Query tq =
         LegacyNumericRangeQuery.newLongRange(field, precisionStep, lower, upper, true, true);
     TopDocs tTopDocs = searcher.search(tq, 1);
     assertEquals(
         "Returned count of range query must be equal to inclusive range length",
         upper - lower + 1,
         tTopDocs.totalHits);
     // test exclusive range
     tq = LegacyNumericRangeQuery.newLongRange(field, precisionStep, lower, upper, false, false);
     tTopDocs = searcher.search(tq, 1);
     assertEquals(
         "Returned count of range query must be equal to exclusive range length",
         Math.max(upper - lower - 1, 0),
         tTopDocs.totalHits);
     // test left exclusive range
     tq = LegacyNumericRangeQuery.newLongRange(field, precisionStep, lower, upper, false, true);
     tTopDocs = searcher.search(tq, 1);
     assertEquals(
         "Returned count of range query must be equal to half exclusive range length",
         upper - lower,
         tTopDocs.totalHits);
     // test right exclusive range
     tq = LegacyNumericRangeQuery.newLongRange(field, precisionStep, lower, upper, true, false);
     tTopDocs = searcher.search(tq, 1);
     assertEquals(
         "Returned count of range query must be equal to half exclusive range length",
         upper - lower,
         tTopDocs.totalHits);
   }
 }
 @Test
 public void testEmptyEnums() throws Exception {
   int count = 3000;
   long lower = (distance * 3 / 2) + startOffset,
       upper = lower + count * distance + (distance / 3);
   // test empty enum
   assert lower < upper;
   assertTrue(
       0
           < countTerms(
               LegacyNumericRangeQuery.newLongRange("field4", 4, lower, upper, true, true)));
   assertEquals(
       0, countTerms(LegacyNumericRangeQuery.newLongRange("field4", 4, upper, lower, true, true)));
   // test empty enum outside of bounds
   lower = distance * noDocs + startOffset;
   upper = 2L * lower;
   assert lower < upper;
   assertEquals(
       0, countTerms(LegacyNumericRangeQuery.newLongRange("field4", 4, lower, upper, true, true)));
 }
 /**
  * test for constant score + boolean query + filter, the other tests only use the constant score
  * mode
  */
 private void testRange(int precisionStep) throws Exception {
   String field = "field" + precisionStep;
   int count = 3000;
   long lower = (distance * 3 / 2) + startOffset,
       upper = lower + count * distance + (distance / 3);
   LegacyNumericRangeQuery<Long> q =
       LegacyNumericRangeQuery.newLongRange(field, precisionStep, lower, upper, true, true);
   for (byte i = 0; i < 2; i++) {
     TopDocs topDocs;
     String type;
     switch (i) {
       case 0:
         type = " (constant score filter rewrite)";
         q.setRewriteMethod(MultiTermQuery.CONSTANT_SCORE_REWRITE);
         topDocs = searcher.search(q, noDocs, Sort.INDEXORDER);
         break;
       case 1:
         type = " (constant score boolean rewrite)";
         q.setRewriteMethod(MultiTermQuery.CONSTANT_SCORE_BOOLEAN_REWRITE);
         topDocs = searcher.search(q, noDocs, Sort.INDEXORDER);
         break;
       default:
         return;
     }
     ScoreDoc[] sd = topDocs.scoreDocs;
     assertNotNull(sd);
     assertEquals("Score doc count" + type, count, sd.length);
     Document doc = searcher.doc(sd[0].doc);
     assertEquals(
         "First doc" + type,
         2 * distance + startOffset,
         doc.getField(field).numericValue().longValue());
     doc = searcher.doc(sd[sd.length - 1].doc);
     assertEquals(
         "Last doc" + type,
         (1 + count) * distance + startOffset,
         doc.getField(field).numericValue().longValue());
   }
 }
 @Test
 public void testEqualsAndHash() throws Exception {
   QueryUtils.checkHashEquals(
       LegacyNumericRangeQuery.newLongRange("test1", 4, 10L, 20L, true, true));
   QueryUtils.checkHashEquals(
       LegacyNumericRangeQuery.newLongRange("test2", 4, 10L, 20L, false, true));
   QueryUtils.checkHashEquals(
       LegacyNumericRangeQuery.newLongRange("test3", 4, 10L, 20L, true, false));
   QueryUtils.checkHashEquals(
       LegacyNumericRangeQuery.newLongRange("test4", 4, 10L, 20L, false, false));
   QueryUtils.checkHashEquals(
       LegacyNumericRangeQuery.newLongRange("test5", 4, 10L, null, true, true));
   QueryUtils.checkHashEquals(
       LegacyNumericRangeQuery.newLongRange("test6", 4, null, 20L, true, true));
   QueryUtils.checkHashEquals(
       LegacyNumericRangeQuery.newLongRange("test7", 4, null, null, true, true));
   QueryUtils.checkEqual(
       LegacyNumericRangeQuery.newLongRange("test8", 4, 10L, 20L, true, true),
       LegacyNumericRangeQuery.newLongRange("test8", 4, 10L, 20L, true, true));
   QueryUtils.checkUnequal(
       LegacyNumericRangeQuery.newLongRange("test9", 4, 10L, 20L, true, true),
       LegacyNumericRangeQuery.newLongRange("test9", 8, 10L, 20L, true, true));
   QueryUtils.checkUnequal(
       LegacyNumericRangeQuery.newLongRange("test10a", 4, 10L, 20L, true, true),
       LegacyNumericRangeQuery.newLongRange("test10b", 4, 10L, 20L, true, true));
   QueryUtils.checkUnequal(
       LegacyNumericRangeQuery.newLongRange("test11", 4, 10L, 20L, true, true),
       LegacyNumericRangeQuery.newLongRange("test11", 4, 20L, 10L, true, true));
   QueryUtils.checkUnequal(
       LegacyNumericRangeQuery.newLongRange("test12", 4, 10L, 20L, true, true),
       LegacyNumericRangeQuery.newLongRange("test12", 4, 10L, 20L, false, true));
   QueryUtils.checkUnequal(
       LegacyNumericRangeQuery.newLongRange("test13", 4, 10L, 20L, true, true),
       LegacyNumericRangeQuery.newFloatRange("test13", 4, 10f, 20f, true, true));
   // difference to int range is tested in TestNumericRangeQuery32
 }
  private void testRandomTrieAndClassicRangeQuery(int precisionStep) throws Exception {
    String field = "field" + precisionStep;
    int totalTermCountT = 0, totalTermCountC = 0, termCountT, termCountC;
    int num = TestUtil.nextInt(random(), 10, 20);
    for (int i = 0; i < num; i++) {
      long lower = (long) (random().nextDouble() * noDocs * distance) + startOffset;
      long upper = (long) (random().nextDouble() * noDocs * distance) + startOffset;
      if (lower > upper) {
        long a = lower;
        lower = upper;
        upper = a;
      }
      final BytesRef lowerBytes, upperBytes;
      BytesRefBuilder b = new BytesRefBuilder();
      LegacyNumericUtils.longToPrefixCoded(lower, 0, b);
      lowerBytes = b.toBytesRef();
      LegacyNumericUtils.longToPrefixCoded(upper, 0, b);
      upperBytes = b.toBytesRef();

      // test inclusive range
      LegacyNumericRangeQuery<Long> tq =
          LegacyNumericRangeQuery.newLongRange(field, precisionStep, lower, upper, true, true);
      TermRangeQuery cq = new TermRangeQuery(field, lowerBytes, upperBytes, true, true);
      TopDocs tTopDocs = searcher.search(tq, 1);
      TopDocs cTopDocs = searcher.search(cq, 1);
      assertEquals(
          "Returned count for LegacyNumericRangeQuery and TermRangeQuery must be equal",
          cTopDocs.totalHits,
          tTopDocs.totalHits);
      totalTermCountT += termCountT = countTerms(tq);
      totalTermCountC += termCountC = countTerms(cq);
      checkTermCounts(precisionStep, termCountT, termCountC);
      // test exclusive range
      tq = LegacyNumericRangeQuery.newLongRange(field, precisionStep, lower, upper, false, false);
      cq = new TermRangeQuery(field, lowerBytes, upperBytes, false, false);
      tTopDocs = searcher.search(tq, 1);
      cTopDocs = searcher.search(cq, 1);
      assertEquals(
          "Returned count for LegacyNumericRangeQuery and TermRangeQuery must be equal",
          cTopDocs.totalHits,
          tTopDocs.totalHits);
      totalTermCountT += termCountT = countTerms(tq);
      totalTermCountC += termCountC = countTerms(cq);
      checkTermCounts(precisionStep, termCountT, termCountC);
      // test left exclusive range
      tq = LegacyNumericRangeQuery.newLongRange(field, precisionStep, lower, upper, false, true);
      cq = new TermRangeQuery(field, lowerBytes, upperBytes, false, true);
      tTopDocs = searcher.search(tq, 1);
      cTopDocs = searcher.search(cq, 1);
      assertEquals(
          "Returned count for LegacyNumericRangeQuery and TermRangeQuery must be equal",
          cTopDocs.totalHits,
          tTopDocs.totalHits);
      totalTermCountT += termCountT = countTerms(tq);
      totalTermCountC += termCountC = countTerms(cq);
      checkTermCounts(precisionStep, termCountT, termCountC);
      // test right exclusive range
      tq = LegacyNumericRangeQuery.newLongRange(field, precisionStep, lower, upper, true, false);
      cq = new TermRangeQuery(field, lowerBytes, upperBytes, true, false);
      tTopDocs = searcher.search(tq, 1);
      cTopDocs = searcher.search(cq, 1);
      assertEquals(
          "Returned count for LegacyNumericRangeQuery and TermRangeQuery must be equal",
          cTopDocs.totalHits,
          tTopDocs.totalHits);
      totalTermCountT += termCountT = countTerms(tq);
      totalTermCountC += termCountC = countTerms(cq);
      checkTermCounts(precisionStep, termCountT, termCountC);
    }

    checkTermCounts(precisionStep, totalTermCountT, totalTermCountC);
    if (VERBOSE && precisionStep != Integer.MAX_VALUE) {
      System.out.println("Average number of terms during random search on '" + field + "':");
      System.out.println(" Numeric query: " + (((double) totalTermCountT) / (num * 4)));
      System.out.println(" Classical query: " + (((double) totalTermCountC) / (num * 4)));
    }
  }
  @Test
  public void testInfiniteValues() throws Exception {
    Directory dir = newDirectory();
    RandomIndexWriter writer =
        new RandomIndexWriter(random(), dir, newIndexWriterConfig(new MockAnalyzer(random())));
    Document doc = new Document();
    doc.add(new LegacyDoubleField("double", Double.NEGATIVE_INFINITY, Field.Store.NO));
    doc.add(new LegacyLongField("long", Long.MIN_VALUE, Field.Store.NO));
    writer.addDocument(doc);

    doc = new Document();
    doc.add(new LegacyDoubleField("double", Double.POSITIVE_INFINITY, Field.Store.NO));
    doc.add(new LegacyLongField("long", Long.MAX_VALUE, Field.Store.NO));
    writer.addDocument(doc);

    doc = new Document();
    doc.add(new LegacyDoubleField("double", 0.0, Field.Store.NO));
    doc.add(new LegacyLongField("long", 0L, Field.Store.NO));
    writer.addDocument(doc);

    for (double d : TestLegacyNumericUtils.DOUBLE_NANs) {
      doc = new Document();
      doc.add(new LegacyDoubleField("double", d, Field.Store.NO));
      writer.addDocument(doc);
    }

    writer.close();

    IndexReader r = DirectoryReader.open(dir);
    IndexSearcher s = newSearcher(r);

    Query q = LegacyNumericRangeQuery.newLongRange("long", null, null, true, true);
    TopDocs topDocs = s.search(q, 10);
    assertEquals("Score doc count", 3, topDocs.scoreDocs.length);

    q = LegacyNumericRangeQuery.newLongRange("long", null, null, false, false);
    topDocs = s.search(q, 10);
    assertEquals("Score doc count", 3, topDocs.scoreDocs.length);

    q = LegacyNumericRangeQuery.newLongRange("long", Long.MIN_VALUE, Long.MAX_VALUE, true, true);
    topDocs = s.search(q, 10);
    assertEquals("Score doc count", 3, topDocs.scoreDocs.length);

    q = LegacyNumericRangeQuery.newLongRange("long", Long.MIN_VALUE, Long.MAX_VALUE, false, false);
    topDocs = s.search(q, 10);
    assertEquals("Score doc count", 1, topDocs.scoreDocs.length);

    q = LegacyNumericRangeQuery.newDoubleRange("double", null, null, true, true);
    topDocs = s.search(q, 10);
    assertEquals("Score doc count", 3, topDocs.scoreDocs.length);

    q = LegacyNumericRangeQuery.newDoubleRange("double", null, null, false, false);
    topDocs = s.search(q, 10);
    assertEquals("Score doc count", 3, topDocs.scoreDocs.length);

    q =
        LegacyNumericRangeQuery.newDoubleRange(
            "double", Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, true, true);
    topDocs = s.search(q, 10);
    assertEquals("Score doc count", 3, topDocs.scoreDocs.length);

    q =
        LegacyNumericRangeQuery.newDoubleRange(
            "double", Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, false, false);
    topDocs = s.search(q, 10);
    assertEquals("Score doc count", 1, topDocs.scoreDocs.length);

    q = LegacyNumericRangeQuery.newDoubleRange("double", Double.NaN, Double.NaN, true, true);
    topDocs = s.search(q, 10);
    assertEquals(
        "Score doc count", TestLegacyNumericUtils.DOUBLE_NANs.length, topDocs.scoreDocs.length);

    r.close();
    dir.close();
  }