/// <summary> /// Helper function to create a LinkedHashSet fulfilling the given specific parameters. The function will /// create an LinkedHashSet using the Comparer constructor and then add values /// to it until it is full. It will begin by adding the desired number of matching, /// followed by random (deterministic) elements until the desired count is reached. /// </summary> protected IEnumerable <T> CreateLinkedHashSet(IEnumerable <T> enumerableToMatchTo, int count, int numberOfMatchingElements) { JCG.LinkedHashSet <T> set = new JCG.LinkedHashSet <T>(GetIEqualityComparer()); int seed = 528; JCG.List <T> match = null; // Add Matching elements if (enumerableToMatchTo != null) { match = enumerableToMatchTo.ToList(); for (int i = 0; i < numberOfMatchingElements; i++) { set.Add(match[i]); } } // Add elements to reach the desired count while (set.Count < count) { T toAdd = CreateT(seed++); while (set.Contains(toAdd) || (match != null && match.Contains(toAdd, GetIEqualityComparer()))) // Don't want any unexpectedly duplicate values { toAdd = CreateT(seed++); } set.Add(toAdd); } // Validate that the Enumerable fits the guidelines as expected Debug.Assert(set.Count == count); if (match != null) { int actualMatchingCount = 0; foreach (T lookingFor in match) { actualMatchingCount += set.Contains(lookingFor) ? 1 : 0; } Assert.Equal(numberOfMatchingElements, actualMatchingCount); } return(set); }
private void doTest(SpatialOperation operation) { //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); } bool biasContains = (operation == SpatialOperation.Contains); //Main index loop: IDictionary <String, IShape> indexedShapes = new JCG.LinkedDictionary <String, IShape>(); IDictionary <String, IShape> indexedShapesGS = new JCG.LinkedDictionary <String, IShape>();//grid snapped int numIndexedShapes = randomIntBetween(1, 6); #pragma warning disable 219 bool indexedAtLeastOneShapePair = false; #pragma warning restore 219 for (int i = 0; i < numIndexedShapes; i++) { String id = "" + i; IShape indexedShape; int R = Random.nextInt(12); if (R == 0) {//1 in 12 indexedShape = null; } else if (R == 1) { //1 in 12 indexedShape = randomPoint(); //just one point } else if (R <= 4) {//3 in 12 //comprised of more than one shape indexedShape = randomShapePairRect(biasContains); indexedAtLeastOneShapePair = true; } else { indexedShape = randomRectangle();//just one rect } indexedShapes.Put(id, indexedShape); indexedShapesGS.Put(id, gridSnap(indexedShape)); adoc(id, indexedShape); if (Random.nextInt(10) == 0) { Commit();//intermediate commit, produces extra segments } } //delete some documents randomly IEnumerator <String> idIter = indexedShapes.Keys.ToList().GetEnumerator(); while (idIter.MoveNext()) { String id = idIter.Current; if (Random.nextInt(10) == 0) { DeleteDoc(id); //idIter.Remove(); indexedShapes.Remove(id); indexedShapesGS.Remove(id); } } Commit(); //Main query loop: int numQueryShapes = AtLeast(20); for (int i = 0; i < numQueryShapes; i++) { int scanLevel = randomInt(grid.MaxLevels); ((RecursivePrefixTreeStrategy)strategy).PrefixGridScanLevel = (scanLevel); IShape queryShape; switch (randomInt(10)) { case 0: queryShape = randomPoint(); break; // LUCENE-5549 //TODO debug: -Dtests.method=testWithin -Dtests.multiplier=3 -Dtests.seed=5F5294CE2E075A3E:AAD2F0F79288CA64 // case 1:case 2:case 3: // if (!indexedAtLeastOneShapePair) { // avoids ShapePair.relate(ShapePair), which isn't reliable // queryShape = randomShapePairRect(!biasContains);//invert biasContains for query side // break; // } default: queryShape = randomRectangle(); break; } IShape queryShapeGS = gridSnap(queryShape); bool opIsDisjoint = operation == SpatialOperation.IsDisjointTo; //Generate truth via brute force: // We ensure true-positive matches (if the predicate on the raw shapes match // then the search should find those same matches). // approximations, false-positive matches ISet <string> expectedIds = new JCG.LinkedHashSet <string>(); //true-positives ISet <string> secondaryIds = new JCG.LinkedHashSet <string>(); //false-positives (unless disjoint) foreach (var entry in indexedShapes) { string id = entry.Key; IShape indexedShapeCompare = entry.Value; if (indexedShapeCompare == null) { continue; } IShape queryShapeCompare = queryShape; if (operation.Evaluate(indexedShapeCompare, queryShapeCompare)) { expectedIds.Add(id); if (opIsDisjoint) { //if no longer intersect after buffering them, for disjoint, remember this indexedShapeCompare = indexedShapesGS[id]; queryShapeCompare = queryShapeGS; if (!operation.Evaluate(indexedShapeCompare, queryShapeCompare)) { secondaryIds.Add(id); } } } else if (!opIsDisjoint) { //buffer either the indexed or query shape (via gridSnap) and try again if (operation == SpatialOperation.Intersects) { indexedShapeCompare = indexedShapesGS[id]; queryShapeCompare = queryShapeGS; //TODO Unfortunately, grid-snapping both can result in intersections that otherwise // wouldn't happen when the grids are adjacent. Not a big deal but our test is just a // bit more lenient. } else if (operation == SpatialOperation.Contains) { indexedShapeCompare = indexedShapesGS[id]; } else if (operation == SpatialOperation.IsWithin) { queryShapeCompare = queryShapeGS; } if (operation.Evaluate(indexedShapeCompare, queryShapeCompare)) { secondaryIds.Add(id); } } } //Search and verify results SpatialArgs args = new SpatialArgs(operation, queryShape); if (queryShape is ShapePair) { args.DistErrPct = (0.0);//a hack; we want to be more detailed than gridSnap(queryShape) } Query query = strategy.MakeQuery(args); SearchResults got = executeQuery(query, 100); ISet <String> remainingExpectedIds = new JCG.LinkedHashSet <string>(expectedIds); foreach (SearchResult result in got.results) { String id = result.GetId(); bool removed = remainingExpectedIds.Remove(id); if (!removed && (!opIsDisjoint && !secondaryIds.Contains(id))) { fail("Shouldn't match", id, indexedShapes, indexedShapesGS, queryShape); } } if (opIsDisjoint) { remainingExpectedIds.ExceptWith(secondaryIds); } if (remainingExpectedIds.Count > 0) { var iter = remainingExpectedIds.GetEnumerator(); iter.MoveNext(); String id = iter.Current; fail("Should have matched", id, indexedShapes, indexedShapesGS, queryShape); } } }