Beispiel #1
0
        /// <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);
                }
            }
        }