示例#1
0
        // TODO: broadcastNodeExpire?  then we can purge the
        // known-stale cache entries...

        // MOCK: in a real env you have to hit the wire
        // (send this query to all remote nodes
        // concurrently):
        internal virtual TopDocs SearchNode(int nodeID, long[] nodeVersions, Query q, Sort sort, int numHits, ScoreDoc searchAfter)
        {
            NodeState.ShardIndexSearcher s = m_nodes[nodeID].Acquire(nodeVersions);
            try
            {
                if (sort is null)
                {
                    if (searchAfter != null)
                    {
                        return(s.LocalSearchAfter(searchAfter, q, numHits));
                    }
                    else
                    {
                        return(s.LocalSearch(q, numHits));
                    }
                }
                else
                {
                    if (Debugging.AssertsEnabled)
                    {
                        Debugging.Assert(searchAfter is null);                           // not supported yet
                    }
                    return(s.LocalSearch(q, numHits, sort));
                }
            }
            finally
            {
                NodeState.Release(s); // LUCENENET: made static per CA1822 and eliminated array lookup
            }
        }
示例#2
0
                public override TopDocs SearchAfter(ScoreDoc after, Query query, int numHits)
                {
                    TopDocs[] shardHits = new TopDocs[nodeVersions.Length];
                    // results are merged in that order: score, shardIndex, doc. therefore we set
                    // after to after.Score and depending on the nodeID we set doc to either:
                    // - not collect any more documents with that score (only with worse score)
                    // - collect more documents with that score (and worse) following the last collected document
                    // - collect all documents with that score (and worse)
                    ScoreDoc shardAfter = new ScoreDoc(after.Doc, after.Score);

                    for (int nodeID = 0; nodeID < nodeVersions.Length; nodeID++)
                    {
                        if (nodeID < after.ShardIndex)
                        {
                            // all documents with after.Score were already collected, so collect
                            // only documents with worse scores.
                            NodeState.ShardIndexSearcher s = outerInstance.outerInstance.m_nodes[nodeID].Acquire(nodeVersions);
                            try
                            {
                                // Setting after.Doc to reader.MaxDoc-1 is a way to tell
                                // TopScoreDocCollector that no more docs with that score should
                                // be collected. note that in practice the shard which sends the
                                // request to a remote shard won't have reader.MaxDoc at hand, so
                                // it will send some arbitrary value which will be fixed on the
                                // other end.
                                shardAfter.Doc = s.IndexReader.MaxDoc - 1;
                            }
                            finally
                            {
                                Release(s); // LUCENENET: Made static per CA1822 and eliminated array lookup
                            }
                        }
                        else if (nodeID == after.ShardIndex)
                        {
                            // collect all documents following the last collected doc with
                            // after.Score + documents with worse scores.
                            shardAfter.Doc = after.Doc;
                        }
                        else
                        {
                            // all documents with after.Score (and worse) should be collected
                            // because they didn't make it to top-N in the previous round.
                            shardAfter.Doc = -1;
                        }
                        if (nodeID == MyNodeID)
                        {
                            // My node; run using local shard searcher we
                            // already aquired:
                            shardHits[nodeID] = LocalSearchAfter(shardAfter, query, numHits);
                        }
                        else
                        {
                            shardHits[nodeID] = outerInstance.outerInstance.SearchNode(nodeID, nodeVersions, query, null, numHits, shardAfter);
                        }
                        //System.out.println("  node=" + nodeID + " totHits=" + shardHits[nodeID].TotalHits);
                    }

                    // Merge:
                    return(TopDocs.Merge(null, numHits, shardHits));
                }
        // TODO: broadcastNodeExpire?  then we can purge the
        // known-stale cache entries...

        // MOCK: in a real env you have to hit the wire
        // (send this query to all remote nodes
        // concurrently):
        internal virtual TopDocs SearchNode(int nodeID, long[] nodeVersions, Query q, Sort sort, int numHits, ScoreDoc searchAfter)
        {
            NodeState.ShardIndexSearcher s = m_nodes[nodeID].Acquire(nodeVersions);
            try
            {
                if (sort == null)
                {
                    if (searchAfter != null)
                    {
                        return(s.LocalSearchAfter(searchAfter, q, numHits));
                    }
                    else
                    {
                        return(s.LocalSearch(q, numHits));
                    }
                }
                else
                {
                    Debug.Assert(searchAfter == null); // not supported yet
                    return(s.LocalSearch(q, numHits, sort));
                }
            }
            finally
            {
                m_nodes[nodeID].Release(s);
            }
        }
示例#4
0
        private PreviousSearchState AssertSame(IndexSearcher mockSearcher, NodeState.ShardIndexSearcher shardSearcher, Query q, Sort sort, PreviousSearchState state)
        {
            int numHits = TestUtil.NextInt(Random(), 1, 100);

            if (state != null && state.SearchAfterLocal == null)
            {
                // In addition to what we last searched:
                numHits += state.NumHitsPaged;
            }

            if (VERBOSE)
            {
                Console.WriteLine("TEST: query=" + q + " sort=" + sort + " numHits=" + numHits);
                if (state != null)
                {
                    Console.WriteLine("  prev: searchAfterLocal=" + state.SearchAfterLocal + " searchAfterShard=" + state.SearchAfterShard + " numHitsPaged=" + state.NumHitsPaged);
                }
            }

            // Single (mock local) searcher:
            TopDocs hits;

            if (sort == null)
            {
                if (state != null && state.SearchAfterLocal != null)
                {
                    hits = mockSearcher.SearchAfter(state.SearchAfterLocal, q, numHits);
                }
                else
                {
                    hits = mockSearcher.Search(q, numHits);
                }
            }
            else
            {
                hits = mockSearcher.Search(q, numHits, sort);
            }

            // Shard searcher
            TopDocs shardHits;

            if (sort == null)
            {
                if (state != null && state.SearchAfterShard != null)
                {
                    shardHits = shardSearcher.SearchAfter(state.SearchAfterShard, q, numHits);
                }
                else
                {
                    shardHits = shardSearcher.Search(q, numHits);
                }
            }
            else
            {
                shardHits = shardSearcher.Search(q, numHits, sort);
            }

            int numNodes = shardSearcher.NodeVersions.Length;

            int[] @base = new int[numNodes];
            IList <IndexReaderContext> subs = mockSearcher.TopReaderContext.Children;

            Assert.AreEqual(numNodes, subs.Count);

            for (int nodeID = 0; nodeID < numNodes; nodeID++)
            {
                @base[nodeID] = subs[nodeID].DocBaseInParent;
            }

            if (VERBOSE)
            {
                /*
                 * for(int shardID=0;shardID<shardSearchers.Length;shardID++) {
                 * System.out.println("  shard=" + shardID + " maxDoc=" + shardSearchers[shardID].searcher.getIndexReader().MaxDoc);
                 * }
                 */
                Console.WriteLine("  single searcher: " + hits.TotalHits + " totalHits maxScore=" + hits.MaxScore);
                for (int i = 0; i < hits.ScoreDocs.Length; i++)
                {
                    ScoreDoc sd = hits.ScoreDocs[i];
                    Console.WriteLine("    doc=" + sd.Doc + " score=" + sd.Score);
                }
                Console.WriteLine("  shard searcher: " + shardHits.TotalHits + " totalHits maxScore=" + shardHits.MaxScore);
                for (int i = 0; i < shardHits.ScoreDocs.Length; i++)
                {
                    ScoreDoc sd = shardHits.ScoreDocs[i];
                    Console.WriteLine("    doc=" + sd.Doc + " (rebased: " + (sd.Doc + @base[sd.ShardIndex]) + ") score=" + sd.Score + " shard=" + sd.ShardIndex);
                }
            }

            int numHitsPaged;

            if (state != null && state.SearchAfterLocal != null)
            {
                numHitsPaged = hits.ScoreDocs.Length;
                if (state != null)
                {
                    numHitsPaged += state.NumHitsPaged;
                }
            }
            else
            {
                numHitsPaged = hits.ScoreDocs.Length;
            }

            bool moreHits;

            ScoreDoc bottomHit;
            ScoreDoc bottomHitShards;

            if (numHitsPaged < hits.TotalHits)
            {
                // More hits to page through
                moreHits = true;
                if (sort == null)
                {
                    bottomHit = hits.ScoreDocs[hits.ScoreDocs.Length - 1];
                    ScoreDoc sd = shardHits.ScoreDocs[shardHits.ScoreDocs.Length - 1];
                    // Must copy because below we rebase:
                    bottomHitShards = new ScoreDoc(sd.Doc, sd.Score, sd.ShardIndex);
                    if (VERBOSE)
                    {
                        Console.WriteLine("  save bottomHit=" + bottomHit);
                    }
                }
                else
                {
                    bottomHit       = null;
                    bottomHitShards = null;
                }
            }
            else
            {
                Assert.AreEqual(hits.TotalHits, numHitsPaged);
                bottomHit       = null;
                bottomHitShards = null;
                moreHits        = false;
            }

            // Must rebase so Assert.AreEqual passes:
            for (int hitID = 0; hitID < shardHits.ScoreDocs.Length; hitID++)
            {
                ScoreDoc sd = shardHits.ScoreDocs[hitID];
                sd.Doc += @base[sd.ShardIndex];
            }

            TestUtil.AssertEquals(hits, shardHits);

            if (moreHits)
            {
                // Return a continuation:
                return(new PreviousSearchState(q, sort, bottomHit, bottomHitShards, shardSearcher.NodeVersions, numHitsPaged));
            }
            else
            {
                return(null);
            }
        }