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;
}
}
}