lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nkn...@apache.org
Subject [1/4] lucene-solr:branch_6x: LUCENE-7740: Refactor Range Fields to remove Field suffix (e.g., DoubleRange), move InetAddressRange and InetAddressPoint from sandbox to misc module, and refactor all other range fields from sandbox to core.
Date Mon, 13 Mar 2017 07:26:18 GMT
Repository: lucene-solr
Updated Branches:
  refs/heads/branch_6x f171d181c -> f277ebd25


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f277ebd2/lucene/sandbox/src/test/org/apache/lucene/search/TestDoubleRangeFieldQueries.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/test/org/apache/lucene/search/TestDoubleRangeFieldQueries.java b/lucene/sandbox/src/test/org/apache/lucene/search/TestDoubleRangeFieldQueries.java
deleted file mode 100644
index 43630e3..0000000
--- a/lucene/sandbox/src/test/org/apache/lucene/search/TestDoubleRangeFieldQueries.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.search;
-
-import java.util.Arrays;
-
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.DoubleRangeField;
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.RandomIndexWriter;
-import org.apache.lucene.store.Directory;
-
-/**
- * Random testing for RangeFieldQueries.
- */
-public class TestDoubleRangeFieldQueries extends BaseRangeFieldQueryTestCase {
-  private static final String FIELD_NAME = "doubleRangeField";
-
-  private double nextDoubleInternal() {
-    if (rarely()) {
-      return random().nextBoolean() ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY;
-    }
-    double max = Double.MAX_VALUE / 2;
-    return (max + max) * random().nextDouble() - max;
-  }
-
-  @Override
-  protected Range nextRange(int dimensions) {
-    double[] min = new double[dimensions];
-    double[] max = new double[dimensions];
-
-    double minV, maxV;
-    for (int d=0; d<dimensions; ++d) {
-      minV = nextDoubleInternal();
-      maxV = nextDoubleInternal();
-      min[d] = Math.min(minV, maxV);
-      max[d] = Math.max(minV, maxV);
-    }
-    return new DoubleRange(min, max);
-  }
-
-  @Override
-  protected DoubleRangeField newRangeField(Range r) {
-    return new DoubleRangeField(FIELD_NAME, ((DoubleRange)r).min, ((DoubleRange)r).max);
-  }
-
-  @Override
-  protected Query newIntersectsQuery(Range r) {
-    return DoubleRangeField.newIntersectsQuery(FIELD_NAME, ((DoubleRange)r).min, ((DoubleRange)r).max);
-  }
-
-  @Override
-  protected Query newContainsQuery(Range r) {
-    return DoubleRangeField.newContainsQuery(FIELD_NAME, ((DoubleRange)r).min, ((DoubleRange)r).max);
-  }
-
-  @Override
-  protected Query newWithinQuery(Range r) {
-    return DoubleRangeField.newWithinQuery(FIELD_NAME, ((DoubleRange)r).min, ((DoubleRange)r).max);
-  }
-
-  @Override
-  protected Query newCrossesQuery(Range r) {
-    return DoubleRangeField.newCrossesQuery(FIELD_NAME, ((DoubleRange)r).min, ((DoubleRange)r).max);
-  }
-
-  /** Basic test */
-  public void testBasics() throws Exception {
-    Directory dir = newDirectory();
-    RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
-
-    // intersects (within)
-    Document document = new Document();
-    document.add(new DoubleRangeField(FIELD_NAME, new double[] {-10.0, -10.0}, new double[] {9.1, 10.1}));
-    writer.addDocument(document);
-
-    // intersects (crosses)
-    document = new Document();
-    document.add(new DoubleRangeField(FIELD_NAME, new double[] {10.0, -10.0}, new double[] {20.0, 10.0}));
-    writer.addDocument(document);
-
-    // intersects (contains, crosses)
-    document = new Document();
-    document.add(new DoubleRangeField(FIELD_NAME, new double[] {-20.0, -20.0}, new double[] {30.0, 30.1}));
-    writer.addDocument(document);
-
-    // intersects (crosses)
-    document = new Document();
-    document.add(new DoubleRangeField(FIELD_NAME, new double[] {-11.1, -11.2}, new double[] {1.23, 11.5}));
-    writer.addDocument(document);
-
-    // intersects (crosses)
-    document = new Document();
-    document.add(new DoubleRangeField(FIELD_NAME, new double[] {12.33, 1.2}, new double[] {15.1, 29.9}));
-    writer.addDocument(document);
-
-    // disjoint
-    document = new Document();
-    document.add(new DoubleRangeField(FIELD_NAME, new double[] {-122.33, 1.2}, new double[] {-115.1, 29.9}));
-    writer.addDocument(document);
-
-    // intersects (crosses)
-    document = new Document();
-    document.add(new DoubleRangeField(FIELD_NAME, new double[] {Double.NEGATIVE_INFINITY, 1.2}, new double[] {-11.0, 29.9}));
-    writer.addDocument(document);
-
-    // equal (within, contains, intersects)
-    document = new Document();
-    document.add(new DoubleRangeField(FIELD_NAME, new double[] {-11, -15}, new double[] {15, 20}));
-    writer.addDocument(document);
-
-    // search
-    IndexReader reader = writer.getReader();
-    IndexSearcher searcher = newSearcher(reader);
-    assertEquals(7, searcher.count(DoubleRangeField.newIntersectsQuery(FIELD_NAME,
-        new double[] {-11.0, -15.0}, new double[] {15.0, 20.0})));
-    assertEquals(2, searcher.count(DoubleRangeField.newWithinQuery(FIELD_NAME,
-        new double[] {-11.0, -15.0}, new double[] {15.0, 20.0})));
-    assertEquals(2, searcher.count(DoubleRangeField.newContainsQuery(FIELD_NAME,
-        new double[] {-11.0, -15.0}, new double[] {15.0, 20.0})));
-    assertEquals(5, searcher.count(DoubleRangeField.newCrossesQuery(FIELD_NAME,
-        new double[] {-11.0, -15.0}, new double[] {15.0, 20.0})));
-
-    reader.close();
-    writer.close();
-    dir.close();
-  }
-
-  /** DoubleRange test class implementation - use to validate DoubleRangeField */
-  private class DoubleRange extends Range {
-    double[] min;
-    double[] max;
-
-    DoubleRange(double[] min, double[] max) {
-      assert min != null && max != null && min.length > 0 && max.length > 0
-          : "test box: min/max cannot be null or empty";
-      assert min.length == max.length : "test box: min/max length do not agree";
-      this.min = min;
-      this.max = max;
-    }
-
-    @Override
-    protected int numDimensions() {
-      return min.length;
-    }
-
-    @Override
-    protected Double getMin(int dim) {
-      return min[dim];
-    }
-
-    @Override
-    protected void setMin(int dim, Object val) {
-      double v = (Double)val;
-      if (min[dim] < v) {
-        max[dim] = v;
-      } else {
-        min[dim] = v;
-      }
-    }
-
-    @Override
-    protected Double getMax(int dim) {
-      return max[dim];
-    }
-
-    @Override
-    protected void setMax(int dim, Object val) {
-      double v = (Double)val;
-      if (max[dim] > v) {
-        min[dim] = v;
-      } else {
-        max[dim] = v;
-      }
-    }
-
-    @Override
-    protected boolean isEqual(Range other) {
-      DoubleRange o = (DoubleRange)other;
-      return Arrays.equals(min, o.min) && Arrays.equals(max, o.max);
-    }
-
-    @Override
-    protected boolean isDisjoint(Range o) {
-      DoubleRange other = (DoubleRange)o;
-      for (int d=0; d<this.min.length; ++d) {
-        if (this.min[d] > other.max[d] || this.max[d] < other.min[d]) {
-          // disjoint:
-          return true;
-        }
-      }
-      return false;
-    }
-
-    @Override
-    protected boolean isWithin(Range o) {
-      DoubleRange other = (DoubleRange)o;
-      for (int d=0; d<this.min.length; ++d) {
-        if ((this.min[d] >= other.min[d] && this.max[d] <= other.max[d]) == false) {
-          // not within:
-          return false;
-        }
-      }
-      return true;
-    }
-
-    @Override
-    protected boolean contains(Range o) {
-      DoubleRange other = (DoubleRange) o;
-      for (int d=0; d<this.min.length; ++d) {
-        if ((this.min[d] <= other.min[d] && this.max[d] >= other.max[d]) == false) {
-          // not contains:
-          return false;
-        }
-      }
-      return true;
-    }
-
-    @Override
-    public String toString() {
-      StringBuilder b = new StringBuilder();
-      b.append("Box(");
-      b.append(min[0]);
-      b.append(" TO ");
-      b.append(max[0]);
-      for (int d=1; d<min.length; ++d) {
-        b.append(", ");
-        b.append(min[d]);
-        b.append(" TO ");
-        b.append(max[d]);
-      }
-      b.append(")");
-
-      return b.toString();
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f277ebd2/lucene/sandbox/src/test/org/apache/lucene/search/TestFloatRangeFieldQueries.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/test/org/apache/lucene/search/TestFloatRangeFieldQueries.java b/lucene/sandbox/src/test/org/apache/lucene/search/TestFloatRangeFieldQueries.java
deleted file mode 100644
index 3509e35..0000000
--- a/lucene/sandbox/src/test/org/apache/lucene/search/TestFloatRangeFieldQueries.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.search;
-
-import java.util.Arrays;
-
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.FloatRangeField;
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.RandomIndexWriter;
-import org.apache.lucene.store.Directory;
-
-/**
- * Random testing for FloatRangeField Queries.
- */
-public class TestFloatRangeFieldQueries extends BaseRangeFieldQueryTestCase {
-  private static final String FIELD_NAME = "floatRangeField";
-
-  private float nextFloatInternal() {
-    if (rarely()) {
-      return random().nextBoolean() ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;
-    }
-    float max = Float.MAX_VALUE / 2;
-    return (max + max) * random().nextFloat() - max;
-  }
-
-  @Override
-  protected Range nextRange(int dimensions) {
-    float[] min = new float[dimensions];
-    float[] max = new float[dimensions];
-
-    float minV, maxV;
-    for (int d=0; d<dimensions; ++d) {
-      minV = nextFloatInternal();
-      maxV = nextFloatInternal();
-      min[d] = Math.min(minV, maxV);
-      max[d] = Math.max(minV, maxV);
-    }
-    return new FloatRange(min, max);
-  }
-
-  @Override
-  protected FloatRangeField newRangeField(Range r) {
-    return new FloatRangeField(FIELD_NAME, ((FloatRange)r).min, ((FloatRange)r).max);
-  }
-
-  @Override
-  protected Query newIntersectsQuery(Range r) {
-    return FloatRangeField.newIntersectsQuery(FIELD_NAME, ((FloatRange)r).min, ((FloatRange)r).max);
-  }
-
-  @Override
-  protected Query newContainsQuery(Range r) {
-    return FloatRangeField.newContainsQuery(FIELD_NAME, ((FloatRange)r).min, ((FloatRange)r).max);
-  }
-
-  @Override
-  protected Query newWithinQuery(Range r) {
-    return FloatRangeField.newWithinQuery(FIELD_NAME, ((FloatRange)r).min, ((FloatRange)r).max);
-  }
-
-  @Override
-  protected Query newCrossesQuery(Range r) {
-    return FloatRangeField.newCrossesQuery(FIELD_NAME, ((FloatRange)r).min, ((FloatRange)r).max);
-  }
-
-  /** Basic test */
-  public void testBasics() throws Exception {
-    Directory dir = newDirectory();
-    RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
-
-    // intersects (within)
-    Document document = new Document();
-    document.add(new FloatRangeField(FIELD_NAME, new float[] {-10.0f, -10.0f}, new float[] {9.1f, 10.1f}));
-    writer.addDocument(document);
-
-    // intersects (crosses)
-    document = new Document();
-    document.add(new FloatRangeField(FIELD_NAME, new float[] {10.0f, -10.0f}, new float[] {20.0f, 10.0f}));
-    writer.addDocument(document);
-
-    // intersects (contains, crosses)
-    document = new Document();
-    document.add(new FloatRangeField(FIELD_NAME, new float[] {-20.0f, -20.0f}, new float[] {30.0f, 30.1f}));
-    writer.addDocument(document);
-
-    // intersects (crosses)
-    document = new Document();
-    document.add(new FloatRangeField(FIELD_NAME, new float[] {-11.1f, -11.2f}, new float[] {1.23f, 11.5f}));
-    writer.addDocument(document);
-
-    // intersects (crosses)
-    document = new Document();
-    document.add(new FloatRangeField(FIELD_NAME, new float[] {12.33f, 1.2f}, new float[] {15.1f, 29.9f}));
-    writer.addDocument(document);
-
-    // disjoint
-    document = new Document();
-    document.add(new FloatRangeField(FIELD_NAME, new float[] {-122.33f, 1.2f}, new float[] {-115.1f, 29.9f}));
-    writer.addDocument(document);
-
-    // intersects (crosses)
-    document = new Document();
-    document.add(new FloatRangeField(FIELD_NAME, new float[] {Float.NEGATIVE_INFINITY, 1.2f}, new float[] {-11.0f, 29.9f}));
-    writer.addDocument(document);
-
-    // equal (within, contains, intersects)
-    document = new Document();
-    document.add(new FloatRangeField(FIELD_NAME, new float[] {-11f, -15f}, new float[] {15f, 20f}));
-    writer.addDocument(document);
-
-    // search
-    IndexReader reader = writer.getReader();
-    IndexSearcher searcher = newSearcher(reader);
-    assertEquals(7, searcher.count(FloatRangeField.newIntersectsQuery(FIELD_NAME,
-        new float[] {-11.0f, -15.0f}, new float[] {15.0f, 20.0f})));
-    assertEquals(2, searcher.count(FloatRangeField.newWithinQuery(FIELD_NAME,
-        new float[] {-11.0f, -15.0f}, new float[] {15.0f, 20.0f})));
-    assertEquals(2, searcher.count(FloatRangeField.newContainsQuery(FIELD_NAME,
-        new float[] {-11.0f, -15.0f}, new float[] {15.0f, 20.0f})));
-    assertEquals(5, searcher.count(FloatRangeField.newCrossesQuery(FIELD_NAME,
-        new float[] {-11.0f, -15.0f}, new float[] {15.0f, 20.0f})));
-
-    reader.close();
-    writer.close();
-    dir.close();
-  }
-
-  /** FloatRange test class implementation - use to validate FloatRangeField */
-  private class FloatRange extends Range {
-    float[] min;
-    float[] max;
-
-    FloatRange(float[] min, float[] max) {
-      assert min != null && max != null && min.length > 0 && max.length > 0
-          : "test box: min/max cannot be null or empty";
-      assert min.length == max.length : "test box: min/max length do not agree";
-      this.min = min;
-      this.max = max;
-    }
-
-    @Override
-    protected int numDimensions() {
-      return min.length;
-    }
-
-    @Override
-    protected Float getMin(int dim) {
-      return min[dim];
-    }
-
-    @Override
-    protected void setMin(int dim, Object val) {
-      float v = (Float)val;
-      if (min[dim] < v) {
-        max[dim] = v;
-      } else {
-        min[dim] = v;
-      }
-    }
-
-    @Override
-    protected Float getMax(int dim) {
-      return max[dim];
-    }
-
-    @Override
-    protected void setMax(int dim, Object val) {
-      float v = (Float)val;
-      if (max[dim] > v) {
-        min[dim] = v;
-      } else {
-        max[dim] = v;
-      }
-    }
-
-    @Override
-    protected boolean isEqual(Range other) {
-      FloatRange o = (FloatRange)other;
-      return Arrays.equals(min, o.min) && Arrays.equals(max, o.max);
-    }
-
-    @Override
-    protected boolean isDisjoint(Range o) {
-      FloatRange other = (FloatRange)o;
-      for (int d=0; d<this.min.length; ++d) {
-        if (this.min[d] > other.max[d] || this.max[d] < other.min[d]) {
-          // disjoint:
-          return true;
-        }
-      }
-      return false;
-    }
-
-    @Override
-    protected boolean isWithin(Range o) {
-      FloatRange other = (FloatRange)o;
-      for (int d=0; d<this.min.length; ++d) {
-        if ((this.min[d] >= other.min[d] && this.max[d] <= other.max[d]) == false) {
-          // not within:
-          return false;
-        }
-      }
-      return true;
-    }
-
-    @Override
-    protected boolean contains(Range o) {
-      FloatRange other = (FloatRange) o;
-      for (int d=0; d<this.min.length; ++d) {
-        if ((this.min[d] <= other.min[d] && this.max[d] >= other.max[d]) == false) {
-          // not contains:
-          return false;
-        }
-      }
-      return true;
-    }
-
-    @Override
-    public String toString() {
-      StringBuilder b = new StringBuilder();
-      b.append("Box(");
-      b.append(min[0]);
-      b.append(" TO ");
-      b.append(max[0]);
-      for (int d=1; d<min.length; ++d) {
-        b.append(", ");
-        b.append(min[d]);
-        b.append(" TO ");
-        b.append(max[d]);
-      }
-      b.append(")");
-
-      return b.toString();
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f277ebd2/lucene/sandbox/src/test/org/apache/lucene/search/TestIntRangeFieldQueries.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/test/org/apache/lucene/search/TestIntRangeFieldQueries.java b/lucene/sandbox/src/test/org/apache/lucene/search/TestIntRangeFieldQueries.java
deleted file mode 100644
index 0bb782e..0000000
--- a/lucene/sandbox/src/test/org/apache/lucene/search/TestIntRangeFieldQueries.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.search;
-
-import java.util.Arrays;
-
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.IntRangeField;
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.RandomIndexWriter;
-import org.apache.lucene.store.Directory;
-
-/**
- * Random testing for IntRangeField Queries.
- */
-public class TestIntRangeFieldQueries extends BaseRangeFieldQueryTestCase {
-  private static final String FIELD_NAME = "intRangeField";
-
-  private int nextIntInternal() {
-    if (rarely()) {
-      return random().nextBoolean() ? Integer.MAX_VALUE : Integer.MIN_VALUE;
-    }
-    int max = Integer.MAX_VALUE / 2;
-    return (max + max) * random().nextInt() - max;
-  }
-
-  @Override
-  protected Range nextRange(int dimensions) {
-    int[] min = new int[dimensions];
-    int[] max = new int[dimensions];
-
-    int minV, maxV;
-    for (int d=0; d<dimensions; ++d) {
-      minV = nextIntInternal();
-      maxV = nextIntInternal();
-      min[d] = Math.min(minV, maxV);
-      max[d] = Math.max(minV, maxV);
-    }
-    return new IntRange(min, max);
-  }
-
-  @Override
-  protected IntRangeField newRangeField(Range r) {
-    return new IntRangeField(FIELD_NAME, ((IntRange)r).min, ((IntRange)r).max);
-  }
-
-  @Override
-  protected Query newIntersectsQuery(Range r) {
-    return IntRangeField.newIntersectsQuery(FIELD_NAME, ((IntRange)r).min, ((IntRange)r).max);
-  }
-
-  @Override
-  protected Query newContainsQuery(Range r) {
-    return IntRangeField.newContainsQuery(FIELD_NAME, ((IntRange)r).min, ((IntRange)r).max);
-  }
-
-  @Override
-  protected Query newWithinQuery(Range r) {
-    return IntRangeField.newWithinQuery(FIELD_NAME, ((IntRange)r).min, ((IntRange)r).max);
-  }
-
-  @Override
-  protected Query newCrossesQuery(Range r) {
-    return IntRangeField.newCrossesQuery(FIELD_NAME, ((IntRange)r).min, ((IntRange)r).max);
-  }
-
-  /** Basic test */
-  public void testBasics() throws Exception {
-    Directory dir = newDirectory();
-    RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
-
-    // intersects (within)
-    Document document = new Document();
-    document.add(new IntRangeField(FIELD_NAME, new int[] {-10, -10}, new int[] {9, 10}));
-    writer.addDocument(document);
-
-    // intersects (crosses)
-    document = new Document();
-    document.add(new IntRangeField(FIELD_NAME, new int[] {10, -10}, new int[] {20, 10}));
-    writer.addDocument(document);
-
-    // intersects (contains / crosses)
-    document = new Document();
-    document.add(new IntRangeField(FIELD_NAME, new int[] {-20, -20}, new int[] {30, 30}));
-    writer.addDocument(document);
-
-    // intersects (within)
-    document = new Document();
-    document.add(new IntRangeField(FIELD_NAME, new int[] {-11, -11}, new int[] {1, 11}));
-    writer.addDocument(document);
-
-    // intersects (crosses)
-    document = new Document();
-    document.add(new IntRangeField(FIELD_NAME, new int[] {12, 1}, new int[] {15, 29}));
-    writer.addDocument(document);
-
-    // disjoint
-    document = new Document();
-    document.add(new IntRangeField(FIELD_NAME, new int[] {-122, 1}, new int[] {-115, 29}));
-    writer.addDocument(document);
-
-    // intersects (crosses)
-    document = new Document();
-    document.add(new IntRangeField(FIELD_NAME, new int[] {Integer.MIN_VALUE, 1}, new int[] {-11, 29}));
-    writer.addDocument(document);
-
-    // equal (within, contains, intersects)
-    document = new Document();
-    document.add(new IntRangeField(FIELD_NAME, new int[] {-11, -15}, new int[] {15, 20}));
-    writer.addDocument(document);
-
-    // search
-    IndexReader reader = writer.getReader();
-    IndexSearcher searcher = newSearcher(reader);
-    assertEquals(7, searcher.count(IntRangeField.newIntersectsQuery(FIELD_NAME,
-        new int[] {-11, -15}, new int[] {15, 20})));
-    assertEquals(3, searcher.count(IntRangeField.newWithinQuery(FIELD_NAME,
-        new int[] {-11, -15}, new int[] {15, 20})));
-    assertEquals(2, searcher.count(IntRangeField.newContainsQuery(FIELD_NAME,
-        new int[] {-11, -15}, new int[] {15, 20})));
-    assertEquals(4, searcher.count(IntRangeField.newCrossesQuery(FIELD_NAME,
-        new int[] {-11, -15}, new int[] {15, 20})));
-
-    reader.close();
-    writer.close();
-    dir.close();
-  }
-
-  /** IntRange test class implementation - use to validate IntRangeField */
-  private class IntRange extends Range {
-    int[] min;
-    int[] max;
-
-    IntRange(int[] min, int[] max) {
-      assert min != null && max != null && min.length > 0 && max.length > 0
-          : "test box: min/max cannot be null or empty";
-      assert min.length == max.length : "test box: min/max length do not agree";
-      this.min = min;
-      this.max = max;
-    }
-
-    @Override
-    protected int numDimensions() {
-      return min.length;
-    }
-
-    @Override
-    protected Integer getMin(int dim) {
-      return min[dim];
-    }
-
-    @Override
-    protected void setMin(int dim, Object val) {
-      int v = (Integer)val;
-      if (min[dim] < v) {
-        max[dim] = v;
-      } else {
-        min[dim] = v;
-      }
-    }
-
-    @Override
-    protected Integer getMax(int dim) {
-      return max[dim];
-    }
-
-    @Override
-    protected void setMax(int dim, Object val) {
-      int v = (Integer)val;
-      if (max[dim] > v) {
-        min[dim] = v;
-      } else {
-        max[dim] = v;
-      }
-    }
-
-    @Override
-    protected boolean isEqual(Range other) {
-      IntRange o = (IntRange)other;
-      return Arrays.equals(min, o.min) && Arrays.equals(max, o.max);
-    }
-
-    @Override
-    protected boolean isDisjoint(Range o) {
-      IntRange other = (IntRange)o;
-      for (int d=0; d<this.min.length; ++d) {
-        if (this.min[d] > other.max[d] || this.max[d] < other.min[d]) {
-          // disjoint:
-          return true;
-        }
-      }
-      return false;
-    }
-
-    @Override
-    protected boolean isWithin(Range o) {
-      IntRange other = (IntRange)o;
-      for (int d=0; d<this.min.length; ++d) {
-        if ((this.min[d] >= other.min[d] && this.max[d] <= other.max[d]) == false) {
-          // not within:
-          return false;
-        }
-      }
-      return true;
-    }
-
-    @Override
-    protected boolean contains(Range o) {
-      IntRange other = (IntRange) o;
-      for (int d=0; d<this.min.length; ++d) {
-        if ((this.min[d] <= other.min[d] && this.max[d] >= other.max[d]) == false) {
-          // not contains:
-          return false;
-        }
-      }
-      return true;
-    }
-
-    @Override
-    public String toString() {
-      StringBuilder b = new StringBuilder();
-      b.append("Box(");
-      b.append(min[0]);
-      b.append(" TO ");
-      b.append(max[0]);
-      for (int d=1; d<min.length; ++d) {
-        b.append(", ");
-        b.append(min[d]);
-        b.append(" TO ");
-        b.append(max[d]);
-      }
-      b.append(")");
-
-      return b.toString();
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f277ebd2/lucene/sandbox/src/test/org/apache/lucene/search/TestIpRangeFieldQueries.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/test/org/apache/lucene/search/TestIpRangeFieldQueries.java b/lucene/sandbox/src/test/org/apache/lucene/search/TestIpRangeFieldQueries.java
deleted file mode 100644
index 1563584..0000000
--- a/lucene/sandbox/src/test/org/apache/lucene/search/TestIpRangeFieldQueries.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.search;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-import org.apache.lucene.document.InetAddressRangeField;
-import org.apache.lucene.util.StringHelper;
-
-/**
- * Random testing for {@link InetAddressRangeField}
- */
-public class TestIpRangeFieldQueries extends BaseRangeFieldQueryTestCase {
-  private static final String FIELD_NAME = "ipRangeField";
-
-  private IPVersion ipVersion;
-
-  private enum IPVersion {IPv4, IPv6}
-
-  @Override
-  protected Range nextRange(int dimensions) {
-    try {
-      InetAddress min = nextInetaddress();
-      byte[] bMin = min.getAddress();
-      InetAddress max = nextInetaddress();
-      byte[] bMax = max.getAddress();
-      if (StringHelper.compare(bMin.length, bMin, 0, bMax, 0) > 0) {
-        return new IpRange(max, min);
-      }
-      return new IpRange(min, max);
-    } catch (UnknownHostException e) {
-      e.printStackTrace();
-    }
-    return null;
-  }
-
-  /** return random IPv4 or IPv6 address */
-  private InetAddress nextInetaddress() throws UnknownHostException {
-    byte[] b;
-    switch (ipVersion) {
-      case IPv4:
-        b = new byte[4];
-        break;
-      case IPv6:
-        b = new byte[16];
-        break;
-      default:
-        throw new IllegalArgumentException("incorrect IP version: " + ipVersion);
-    }
-    random().nextBytes(b);
-    return InetAddress.getByAddress(b);
-  }
-
-  /** randomly select version across tests */
-  private IPVersion ipVersion() {
-    return random().nextBoolean() ? IPVersion.IPv4 : IPVersion.IPv6;
-  }
-
-  @Override
-  public void testRandomTiny() throws Exception {
-    ipVersion = ipVersion();
-    super.testRandomTiny();
-  }
-
-  @Override
-  public void testMultiValued() throws Exception {
-    ipVersion = ipVersion();
-    super.testRandomMedium();
-  }
-
-  @Override
-  public void testRandomMedium() throws Exception {
-    ipVersion = ipVersion();
-    super.testMultiValued();
-  }
-
-  @Nightly
-  @Override
-  public void testRandomBig() throws Exception {
-    ipVersion = ipVersion();
-    super.testRandomBig();
-  }
-
-  /** return random range */
-  @Override
-  protected InetAddressRangeField newRangeField(Range r) {
-    return new InetAddressRangeField(FIELD_NAME, ((IpRange)r).min, ((IpRange)r).max);
-  }
-
-  /** return random intersects query */
-  @Override
-  protected Query newIntersectsQuery(Range r) {
-    return InetAddressRangeField.newIntersectsQuery(FIELD_NAME, ((IpRange)r).min, ((IpRange)r).max);
-  }
-
-  /** return random contains query */
-  @Override
-  protected Query newContainsQuery(Range r) {
-    return InetAddressRangeField.newContainsQuery(FIELD_NAME, ((IpRange)r).min, ((IpRange)r).max);
-  }
-
-  /** return random within query */
-  @Override
-  protected Query newWithinQuery(Range r) {
-    return InetAddressRangeField.newWithinQuery(FIELD_NAME, ((IpRange)r).min, ((IpRange)r).max);
-  }
-
-  /** return random crosses query */
-  @Override
-  protected Query newCrossesQuery(Range r) {
-    return InetAddressRangeField.newCrossesQuery(FIELD_NAME, ((IpRange)r).min, ((IpRange)r).max);
-  }
-
-  /** encapsulated IpRange for test validation */
-  private class IpRange extends Range {
-    InetAddress min;
-    InetAddress max;
-
-    IpRange(InetAddress min, InetAddress max) {
-      this.min = min;
-      this.max = max;
-    }
-
-    @Override
-    protected int numDimensions() {
-      return 1;
-    }
-
-    @Override
-    protected InetAddress getMin(int dim) {
-      return min;
-    }
-
-    @Override
-    protected void setMin(int dim, Object val) {
-      byte[] v = ((InetAddress)val).getAddress();
-
-      if (StringHelper.compare(v.length, min.getAddress(), 0, v, 0) < 0) {
-        max = (InetAddress)val;
-      } else {
-        min = (InetAddress) val;
-      }
-    }
-
-    @Override
-    protected InetAddress getMax(int dim) {
-      return max;
-    }
-
-    @Override
-    protected void setMax(int dim, Object val) {
-      byte[] v = ((InetAddress)val).getAddress();
-
-      if (StringHelper.compare(v.length, max.getAddress(), 0, v, 0) > 0) {
-        min = (InetAddress)val;
-      } else {
-        max = (InetAddress) val;
-      }
-    }
-
-    @Override
-    protected boolean isEqual(Range o) {
-      IpRange other = (IpRange)o;
-      return this.min.equals(other.min) && this.max.equals(other.max);
-    }
-
-    @Override
-    protected boolean isDisjoint(Range o) {
-      IpRange other = (IpRange)o;
-      byte[] bMin = min.getAddress();
-      byte[] bMax = max.getAddress();
-      return StringHelper.compare(bMin.length, bMin, 0, other.max.getAddress(), 0) > 0 ||
-          StringHelper.compare(bMax.length, bMax, 0, other.min.getAddress(), 0) < 0;
-    }
-
-    @Override
-    protected boolean isWithin(Range o) {
-      IpRange other = (IpRange)o;
-      byte[] bMin = min.getAddress();
-      byte[] bMax = max.getAddress();
-      return StringHelper.compare(bMin.length, bMin, 0, other.min.getAddress(), 0) >= 0 &&
-          StringHelper.compare(bMax.length, bMax, 0, other.max.getAddress(), 0) <= 0;
-    }
-
-    @Override
-    protected boolean contains(Range o) {
-      IpRange other = (IpRange)o;
-      byte[] bMin = min.getAddress();
-      byte[] bMax = max.getAddress();
-      return StringHelper.compare(bMin.length, bMin, 0, other.min.getAddress(), 0) <= 0 &&
-          StringHelper.compare(bMax.length, bMax, 0, other.max.getAddress(), 0) >= 0;
-    }
-
-    @Override
-    public String toString() {
-      StringBuilder b = new StringBuilder();
-      b.append("Box(");
-      b.append(min.getHostAddress());
-      b.append(" TO ");
-      b.append(max.getHostAddress());
-      b.append(")");
-      return b.toString();
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f277ebd2/lucene/sandbox/src/test/org/apache/lucene/search/TestLongRangeFieldQueries.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/test/org/apache/lucene/search/TestLongRangeFieldQueries.java b/lucene/sandbox/src/test/org/apache/lucene/search/TestLongRangeFieldQueries.java
deleted file mode 100644
index fc21a64..0000000
--- a/lucene/sandbox/src/test/org/apache/lucene/search/TestLongRangeFieldQueries.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.search;
-
-import java.util.Arrays;
-
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.LongRangeField;
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.RandomIndexWriter;
-import org.apache.lucene.store.Directory;
-
-/**
- * Random testing for LongRangeField Queries.
- */
-public class TestLongRangeFieldQueries extends BaseRangeFieldQueryTestCase {
-  private static final String FIELD_NAME = "longRangeField";
-
-  private long nextLongInternal() {
-    if (rarely()) {
-      return random().nextBoolean() ? Long.MAX_VALUE : Long.MIN_VALUE;
-    }
-    long max = Long.MAX_VALUE / 2;
-    return (max + max) * random().nextLong() - max;
-  }
-
-  @Override
-  protected Range nextRange(int dimensions) {
-    long[] min = new long[dimensions];
-    long[] max = new long[dimensions];
-
-    long minV, maxV;
-    for (int d=0; d<dimensions; ++d) {
-      minV = nextLongInternal();
-      maxV = nextLongInternal();
-      min[d] = Math.min(minV, maxV);
-      max[d] = Math.max(minV, maxV);
-    }
-    return new LongRange(min, max);
-  }
-
-  @Override
-  protected LongRangeField newRangeField(Range r) {
-    return new LongRangeField(FIELD_NAME, ((LongRange)r).min, ((LongRange)r).max);
-  }
-
-  @Override
-  protected Query newIntersectsQuery(Range r) {
-    return LongRangeField.newIntersectsQuery(FIELD_NAME, ((LongRange)r).min, ((LongRange)r).max);
-  }
-
-  @Override
-  protected Query newContainsQuery(Range r) {
-    return LongRangeField.newContainsQuery(FIELD_NAME, ((LongRange)r).min, ((LongRange)r).max);
-  }
-
-  @Override
-  protected Query newWithinQuery(Range r) {
-    return LongRangeField.newWithinQuery(FIELD_NAME, ((LongRange)r).min, ((LongRange)r).max);
-  }
-
-  @Override
-  protected Query newCrossesQuery(Range r) {
-    return LongRangeField.newCrossesQuery(FIELD_NAME, ((LongRange)r).min, ((LongRange)r).max);
-  }
-
-  /** Basic test */
-  public void testBasics() throws Exception {
-    Directory dir = newDirectory();
-    RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
-
-    // intersects (within)
-    Document document = new Document();
-    document.add(new LongRangeField(FIELD_NAME, new long[] {-10, -10}, new long[] {9, 10}));
-    writer.addDocument(document);
-
-    // intersects (crosses)
-    document = new Document();
-    document.add(new LongRangeField(FIELD_NAME, new long[] {10, -10}, new long[] {20, 10}));
-    writer.addDocument(document);
-
-    // intersects (contains, crosses)
-    document = new Document();
-    document.add(new LongRangeField(FIELD_NAME, new long[] {-20, -20}, new long[] {30, 30}));
-    writer.addDocument(document);
-
-    // intersects (within)
-    document = new Document();
-    document.add(new LongRangeField(FIELD_NAME, new long[] {-11, -11}, new long[] {1, 11}));
-    writer.addDocument(document);
-
-    // intersects (crosses)
-    document = new Document();
-    document.add(new LongRangeField(FIELD_NAME, new long[] {12, 1}, new long[] {15, 29}));
-    writer.addDocument(document);
-
-    // disjoint
-    document = new Document();
-    document.add(new LongRangeField(FIELD_NAME, new long[] {-122, 1}, new long[] {-115, 29}));
-    writer.addDocument(document);
-
-    // intersects (crosses)
-    document = new Document();
-    document.add(new LongRangeField(FIELD_NAME, new long[] {Long.MIN_VALUE, 1}, new long[] {-11, 29}));
-    writer.addDocument(document);
-
-    // equal (within, contains, intersects)
-    document = new Document();
-    document.add(new LongRangeField(FIELD_NAME, new long[] {-11, -15}, new long[] {15, 20}));
-    writer.addDocument(document);
-
-    // search
-    IndexReader reader = writer.getReader();
-    IndexSearcher searcher = newSearcher(reader);
-    assertEquals(7, searcher.count(LongRangeField.newIntersectsQuery(FIELD_NAME,
-        new long[] {-11, -15}, new long[] {15, 20})));
-    assertEquals(3, searcher.count(LongRangeField.newWithinQuery(FIELD_NAME,
-        new long[] {-11, -15}, new long[] {15, 20})));
-    assertEquals(2, searcher.count(LongRangeField.newContainsQuery(FIELD_NAME,
-        new long[] {-11, -15}, new long[] {15, 20})));
-    assertEquals(4, searcher.count(LongRangeField.newCrossesQuery(FIELD_NAME,
-        new long[] {-11, -15}, new long[] {15, 20})));
-
-    reader.close();
-    writer.close();
-    dir.close();
-  }
-
-  /** LongRange test class implementation - use to validate LongRangeField */
-  private class LongRange extends Range {
-    long[] min;
-    long[] max;
-
-    LongRange(long[] min, long[] max) {
-      assert min != null && max != null && min.length > 0 && max.length > 0
-          : "test box: min/max cannot be null or empty";
-      assert min.length == max.length : "test box: min/max length do not agree";
-      this.min = min;
-      this.max = max;
-    }
-
-    @Override
-    protected int numDimensions() {
-      return min.length;
-    }
-
-    @Override
-    protected Long getMin(int dim) {
-      return min[dim];
-    }
-
-    @Override
-    protected void setMin(int dim, Object val) {
-      long v = (Long)val;
-      if (min[dim] < v) {
-        max[dim] = v;
-      } else {
-        min[dim] = v;
-      }
-    }
-
-    @Override
-    protected Long getMax(int dim) {
-      return max[dim];
-    }
-
-    @Override
-    protected void setMax(int dim, Object val) {
-      long v = (Long)val;
-      if (max[dim] > v) {
-        min[dim] = v;
-      } else {
-        max[dim] = v;
-      }
-    }
-
-    @Override
-    protected boolean isEqual(Range other) {
-      LongRange o = (LongRange)other;
-      return Arrays.equals(min, o.min) && Arrays.equals(max, o.max);
-    }
-
-    @Override
-    protected boolean isDisjoint(Range o) {
-      LongRange other = (LongRange)o;
-      for (int d=0; d<this.min.length; ++d) {
-        if (this.min[d] > other.max[d] || this.max[d] < other.min[d]) {
-          // disjoint:
-          return true;
-        }
-      }
-      return false;
-    }
-
-    @Override
-    protected boolean isWithin(Range o) {
-      LongRange other = (LongRange)o;
-      for (int d=0; d<this.min.length; ++d) {
-        if ((this.min[d] >= other.min[d] && this.max[d] <= other.max[d]) == false) {
-          // not within:
-          return false;
-        }
-      }
-      return true;
-    }
-
-    @Override
-    protected boolean contains(Range o) {
-      LongRange other = (LongRange) o;
-      for (int d=0; d<this.min.length; ++d) {
-        if ((this.min[d] <= other.min[d] && this.max[d] >= other.max[d]) == false) {
-          // not contains:
-          return false;
-        }
-      }
-      return true;
-    }
-
-    @Override
-    public String toString() {
-      StringBuilder b = new StringBuilder();
-      b.append("Box(");
-      b.append(min[0]);
-      b.append(" TO ");
-      b.append(max[0]);
-      for (int d=1; d<min.length; ++d) {
-        b.append(", ");
-        b.append(min[d]);
-        b.append(" TO ");
-        b.append(max[d]);
-      }
-      b.append(")");
-
-      return b.toString();
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f277ebd2/lucene/test-framework/src/java/org/apache/lucene/search/BaseRangeFieldQueryTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/BaseRangeFieldQueryTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/search/BaseRangeFieldQueryTestCase.java
new file mode 100644
index 0000000..1ca8c64
--- /dev/null
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/BaseRangeFieldQueryTestCase.java
@@ -0,0 +1,345 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.search;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.NumericDocValuesField;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.MultiDocValues;
+import org.apache.lucene.index.MultiFields;
+import org.apache.lucene.index.NumericDocValues;
+import org.apache.lucene.index.SerialMergeScheduler;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.util.Bits;
+import org.apache.lucene.util.FixedBitSet;
+import org.apache.lucene.util.IOUtils;
+import org.apache.lucene.util.LuceneTestCase;
+
+/**
+ * Abstract class to do basic tests for a RangeField query. Testing rigor inspired by {@code BaseGeoPointTestCase}
+ */
+public abstract class BaseRangeFieldQueryTestCase extends LuceneTestCase {
+  protected abstract Field newRangeField(Range box);
+
+  protected abstract Query newIntersectsQuery(Range box);
+
+  protected abstract Query newContainsQuery(Range box);
+
+  protected abstract Query newWithinQuery(Range box);
+
+  protected abstract Query newCrossesQuery(Range box);
+
+  protected abstract Range nextRange(int dimensions) throws Exception;
+
+  protected int dimension() {
+    return random().nextInt(4) + 1;
+  }
+
+  public void testRandomTiny() throws Exception {
+    // Make sure single-leaf-node case is OK:
+    doTestRandom(10, false);
+  }
+
+  public void testRandomMedium() throws Exception {
+    doTestRandom(10000, false);
+  }
+
+  @Nightly
+  public void testRandomBig() throws Exception {
+    doTestRandom(200000, false);
+  }
+
+  public void testMultiValued() throws Exception {
+    doTestRandom(10000, true);
+  }
+
+  private void doTestRandom(int count, boolean multiValued) throws Exception {
+    int numDocs = atLeast(count);
+    int dimensions = dimension();
+
+    if (VERBOSE) {
+      System.out.println("TEST: numDocs=" + numDocs);
+    }
+
+    Range[][] ranges = new Range[numDocs][];
+
+    boolean haveRealDoc = true;
+
+    nextdoc: for (int id=0; id<numDocs; ++id) {
+      int x = random().nextInt(20);
+      if (ranges[id] == null) {
+        ranges[id] = new Range[] {nextRange(dimensions)};
+      }
+      if (x == 17) {
+        // some docs don't have a box:
+        ranges[id][0].isMissing = true;
+        if (VERBOSE) {
+          System.out.println("  id=" + id + " is missing");
+        }
+        continue;
+      }
+
+      if (multiValued == true && random().nextBoolean()) {
+        // randomly add multi valued documents (up to 2 fields)
+        int n = random().nextInt(2) + 1;
+        ranges[id] = new Range[n];
+        for (int i=0; i<n; ++i) {
+          ranges[id][i] = nextRange(dimensions);
+        }
+      }
+
+      if (id > 0 && x < 9 && haveRealDoc) {
+        int oldID;
+        int i=0;
+        // don't step on missing ranges:
+        while (true) {
+          oldID = random().nextInt(id);
+          if (ranges[oldID][0].isMissing == false) {
+            break;
+          } else if (++i > id) {
+            continue nextdoc;
+          }
+        }
+
+        if (x == dimensions*2) {
+          // Fully identical box (use first box in case current is multivalued but old is not)
+          for (int d=0; d<dimensions; ++d) {
+            ranges[id][0].setMin(d, ranges[oldID][0].getMin(d));
+            ranges[id][0].setMax(d, ranges[oldID][0].getMax(d));
+          }
+          if (VERBOSE) {
+            System.out.println("  id=" + id + " box=" + ranges[id] + " (same box as doc=" + oldID + ")");
+          }
+        } else {
+          for (int m = 0, even = dimensions % 2; m < dimensions * 2; ++m) {
+            if (x == m) {
+              int d = (int)Math.floor(m/2);
+              // current could be multivalue but old may not be, so use first box
+              if (even == 0) {
+                ranges[id][0].setMin(d, ranges[oldID][0].getMin(d));
+                if (VERBOSE) {
+                  System.out.println("  id=" + id + " box=" + ranges[id] + " (same min[" + d + "] as doc=" + oldID + ")");
+                }
+              } else {
+                ranges[id][0].setMax(d, ranges[oldID][0].getMax(d));
+                if (VERBOSE) {
+                  System.out.println("  id=" + id + " box=" + ranges[id] + " (same max[" + d + "] as doc=" + oldID + ")");
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+    verify(ranges);
+  }
+
+  private void verify(Range[][] ranges) throws Exception {
+    IndexWriterConfig iwc = newIndexWriterConfig();
+    // Else seeds may not reproduce:
+    iwc.setMergeScheduler(new SerialMergeScheduler());
+    // Else we can get O(N^2) merging
+    int mbd = iwc.getMaxBufferedDocs();
+    if (mbd != -1 && mbd < ranges.length/100) {
+      iwc.setMaxBufferedDocs(ranges.length/100);
+    }
+    Directory dir;
+    if (ranges.length > 50000) {
+      dir = newFSDirectory(createTempDir(getClass().getSimpleName()));
+    } else {
+      dir = newDirectory();
+    }
+
+    Set<Integer> deleted = new HashSet<>();
+    IndexWriter w = new IndexWriter(dir, iwc);
+    for (int id=0; id < ranges.length; ++id) {
+      Document doc = new Document();
+      doc.add(newStringField("id", ""+id, Field.Store.NO));
+      doc.add(new NumericDocValuesField("id", id));
+      if (ranges[id][0].isMissing == false) {
+        for (int n=0; n<ranges[id].length; ++n) {
+          doc.add(newRangeField(ranges[id][n]));
+        }
+      }
+      w.addDocument(doc);
+      if (id > 0 && random().nextInt(100) == 1) {
+        int idToDelete = random().nextInt(id);
+        w.deleteDocuments(new Term("id", ""+idToDelete));
+        deleted.add(idToDelete);
+        if (VERBOSE) {
+          System.out.println("  delete id=" + idToDelete);
+        }
+      }
+    }
+
+    if (random().nextBoolean()) {
+      w.forceMerge(1);
+    }
+    final IndexReader r = DirectoryReader.open(w);
+    w.close();
+    IndexSearcher s = newSearcher(r);
+
+    int dimensions = ranges[0][0].numDimensions();
+    int iters = atLeast(25);
+    NumericDocValues docIDToID = MultiDocValues.getNumericValues(r, "id");
+    Bits liveDocs = MultiFields.getLiveDocs(s.getIndexReader());
+    int maxDoc = s.getIndexReader().maxDoc();
+
+    for (int iter=0; iter<iters; ++iter) {
+      if (VERBOSE) {
+        System.out.println("\nTEST: iter=" + iter + " s=" + s);
+      }
+
+      // occasionally test open ended bounding ranges
+      Range queryRange = nextRange(dimensions);
+      int rv = random().nextInt(4);
+      Query query;
+      Range.QueryType queryType;
+      if (rv == 0) {
+        queryType = Range.QueryType.INTERSECTS;
+        query = newIntersectsQuery(queryRange);
+      } else if (rv == 1)  {
+        queryType = Range.QueryType.CONTAINS;
+        query = newContainsQuery(queryRange);
+      } else if (rv == 2) {
+        queryType = Range.QueryType.WITHIN;
+        query = newWithinQuery(queryRange);
+      } else {
+        queryType = Range.QueryType.CROSSES;
+        query = newCrossesQuery(queryRange);
+      }
+
+      if (VERBOSE) {
+        System.out.println("  query=" + query);
+      }
+
+      final FixedBitSet hits = new FixedBitSet(maxDoc);
+      s.search(query, new SimpleCollector() {
+        private int docBase;
+
+        @Override
+        public void collect(int doc) {
+          hits.set(docBase + doc);
+        }
+
+        @Override
+        protected void doSetNextReader(LeafReaderContext context) throws IOException {
+          docBase = context.docBase;
+        }
+
+        @Override
+        public boolean needsScores() { return false; }
+      });
+
+      for (int docID=0; docID<maxDoc; ++docID) {
+        int id = (int) docIDToID.get(docID);
+        boolean expected;
+        if (liveDocs != null && liveDocs.get(docID) == false) {
+          // document is deleted
+          expected = false;
+        } else if (ranges[id][0].isMissing) {
+          expected = false;
+        } else {
+          expected = expectedResult(queryRange, ranges[id], queryType);
+        }
+
+        if (hits.get(docID) != expected) {
+          StringBuilder b = new StringBuilder();
+          b.append("FAIL (iter " + iter + "): ");
+          if (expected == true) {
+            b.append("id=" + id + (ranges[id].length > 1 ? " (MultiValue) " : " ") + "should match but did not\n");
+          } else {
+            b.append("id=" + id + " should not match but did\n");
+          }
+          b.append(" queryRange=" + queryRange + "\n");
+          b.append(" box" + ((ranges[id].length > 1) ? "es=" : "=" ) + ranges[id][0]);
+          for (int n=1; n<ranges[id].length; ++n) {
+            b.append(", ");
+            b.append(ranges[id][n]);
+          }
+          b.append("\n queryType=" + queryType + "\n");
+          b.append(" deleted?=" + (liveDocs != null && liveDocs.get(docID) == false));
+          fail("wrong hit (first of possibly more):\n\n" + b);
+        }
+      }
+    }
+    IOUtils.close(r, dir);
+  }
+
+  protected boolean expectedResult(Range queryRange, Range[] range, Range.QueryType queryType) {
+    for (int i=0; i<range.length; ++i) {
+      if (expectedBBoxQueryResult(queryRange, range[i], queryType) == true) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  protected boolean expectedBBoxQueryResult(Range queryRange, Range range, Range.QueryType queryType) {
+    if (queryRange.isEqual(range) && queryType != Range.QueryType.CROSSES) {
+      return true;
+    }
+    Range.QueryType relation = range.relate(queryRange);
+    if (queryType == Range.QueryType.INTERSECTS) {
+      return relation != null;
+    } else if (queryType == Range.QueryType.CROSSES) {
+      // by definition, RangeFields that CONTAIN the query are also considered to cross
+      return relation == queryType || relation == Range.QueryType.CONTAINS;
+    }
+    return relation == queryType;
+  }
+
+  /** base class for range verification */
+  protected abstract static class Range {
+    protected boolean isMissing = false;
+
+    /** supported query relations */
+    protected enum QueryType { INTERSECTS, WITHIN, CONTAINS, CROSSES }
+
+    protected abstract int numDimensions();
+    protected abstract Object getMin(int dim);
+    protected abstract void setMin(int dim, Object val);
+    protected abstract Object getMax(int dim);
+    protected abstract void setMax(int dim, Object val);
+    protected abstract boolean isEqual(Range other);
+    protected abstract boolean isDisjoint(Range other);
+    protected abstract boolean isWithin(Range other);
+    protected abstract boolean contains(Range other);
+
+    protected QueryType relate(Range other) {
+      if (isDisjoint(other)) {
+        // if disjoint; return null:
+        return null;
+      } else if (isWithin(other)) {
+        return QueryType.WITHIN;
+      } else if (contains(other)) {
+        return QueryType.CONTAINS;
+      }
+      return QueryType.CROSSES;
+    }
+  }
+}


Mime
View raw message