}
private void doTest(final SpatialOperation operation) throws IOException {
//first show that when there's no data, a query will result in no results
{
Query query = strategy.makeQuery(new SpatialArgs(operation, randomRectangle()));
SearchResults searchResults = executeQuery(query, 1);
assertEquals(0, searchResults.numFound);
}
final boolean biasContains = (operation == SpatialOperation.Contains);
Map<String, Shape> indexedShapes = new LinkedHashMap<String, Shape>();
Map<String, Shape> indexedShapesGS = new LinkedHashMap<String, Shape>();
final int numIndexedShapes = randomIntBetween(1, 6);
for (int i = 0; i < numIndexedShapes; i++) {
String id = "" + i;
Shape indexedShape;
Shape indexedShapeGS; //(grid-snapped)
int R = random().nextInt(12);
if (R == 0) {//1 in 12
indexedShape = null; //no shape for this doc
indexedShapeGS = null;
} else if (R % 3 == 0) {//4-1 in 12
//comprised of more than one shape
Rectangle shape1 = randomRectangle();
Rectangle shape2 = randomRectangle();
indexedShape = new ShapePair(shape1, shape2, biasContains);
indexedShapeGS = new ShapePair(gridSnap(shape1), gridSnap(shape2), biasContains);
} else {
//just one shape
indexedShape = randomRectangle();
indexedShapeGS = gridSnap(indexedShape);
}
indexedShapes.put(id, indexedShape);
indexedShapesGS.put(id, indexedShapeGS);
adoc(id, indexedShape);
if (random().nextInt(10) == 0)
commit();//intermediate commit, produces extra segments
}
Iterator<String> idIter = indexedShapes.keySet().iterator();
while (idIter.hasNext()) {
String id = idIter.next();
if (random().nextInt(10) == 0) {
deleteDoc(id);
idIter.remove();
indexedShapesGS.remove(id);
}
}
commit();
final int numQueryShapes = atLeast(20);
for (int i = 0; i < numQueryShapes; i++) {
int scanLevel = randomInt(grid.getMaxLevels());
((RecursivePrefixTreeStrategy) strategy).setPrefixGridScanLevel(scanLevel);
final Shape queryShape = randomRectangle();
final boolean DISJOINT = operation.equals(SpatialOperation.IsDisjointTo);
//Generate truth via brute force:
// We really try to ensure true-positive matches (if the predicate on the raw shapes match
// then the search should find those same matches).
// approximations, false-positive matches
Set <String> expectedIds = new LinkedHashSet<String>();//true-positives
Set<String> secondaryIds = new LinkedHashSet<String>();//false-positives (unless disjoint)
for (Map.Entry<String, Shape> entry : indexedShapes.entrySet()) {
Shape indexedShapeCompare = entry.getValue();
if (indexedShapeCompare == null)
continue;
Shape queryShapeCompare = queryShape;
String id = entry.getKey();
if (operation.evaluate(indexedShapeCompare, queryShapeCompare)) {
expectedIds.add(id);
if (DISJOINT) {
//if no longer intersect after buffering them, for disjoint, remember this
indexedShapeCompare = indexedShapesGS.get(entry.getKey());
queryShapeCompare = gridSnap(queryShape);
if (!operation.evaluate(indexedShapeCompare, queryShapeCompare))
secondaryIds.add(id);
}
} else if (!DISJOINT) {
//buffer either the indexed or query shape (via gridSnap) and try again
if (operation.equals(SpatialOperation.Intersects)) {
indexedShapeCompare = indexedShapesGS.get(entry.getKey());
queryShapeCompare = gridSnap(queryShape);
} else if (operation.equals(SpatialOperation.Contains)) {
indexedShapeCompare = indexedShapesGS.get(entry.getKey());
} else if (operation.equals(SpatialOperation.IsWithin)) {
queryShapeCompare = gridSnap(queryShape);
}
if (operation.evaluate(indexedShapeCompare, queryShapeCompare))
secondaryIds.add(id);
}
}
//Search and verify results
SpatialArgs args = new SpatialArgs(operation, queryShape);
Query query = strategy.makeQuery(args);
SearchResults got = executeQuery(query, 100);
Set<String> remainingExpectedIds = new LinkedHashSet<String>(expectedIds);
for (SearchResult result : got.results) {
String id = result.getId();