@@ -234,13 +234,14 @@ namespace mongo {
234234 MatchCountingExplainStrategy::MatchCountingExplainStrategy
235235 ( const ExplainQueryInfo::AncillaryInfo &ancillaryInfo ) :
236236 ExplainRecordingStrategy ( ancillaryInfo ),
237- _matches () {
237+ _orderedMatches () {
238238 }
239239
240- void MatchCountingExplainStrategy::noteIterate ( bool match, bool loadedObject, bool chunkSkip ) {
241- _noteIterate ( match, loadedObject, chunkSkip );
242- if ( match ) {
243- ++_matches;
240+ void MatchCountingExplainStrategy::noteIterate ( bool match, bool orderedMatch,
241+ bool loadedObject, bool chunkSkip ) {
242+ _noteIterate ( match, orderedMatch, loadedObject, chunkSkip );
243+ if ( orderedMatch ) {
244+ ++_orderedMatches;
244245 }
245246 }
246247
@@ -256,7 +257,8 @@ namespace mongo {
256257 _explainInfo->notePlan ( *_cursor, scanAndOrder, indexOnly );
257258 }
258259
259- void SimpleCursorExplainStrategy::_noteIterate ( bool match, bool loadedObject, bool chunkSkip ) {
260+ void SimpleCursorExplainStrategy::_noteIterate ( bool match, bool orderedMatch,
261+ bool loadedObject, bool chunkSkip ) {
260262 _explainInfo->noteIterate ( match, loadedObject, chunkSkip, *_cursor );
261263 }
262264
@@ -276,9 +278,11 @@ namespace mongo {
276278 _cursor ( cursor ) {
277279 }
278280
279- void QueryOptimizerCursorExplainStrategy::_noteIterate ( bool match, bool loadedObject,
280- bool chunkSkip ) {
281- _cursor->noteIterate ( match, loadedObject, chunkSkip );
281+ void QueryOptimizerCursorExplainStrategy::_noteIterate ( bool match, bool orderedMatch,
282+ bool loadedObject, bool chunkSkip ) {
283+ // Note ordered matches only; if an unordered plan is selected, the explain result will
284+ // be updated with reviseN().
285+ _cursor->noteIterate ( orderedMatch, loadedObject, chunkSkip );
282286 }
283287
284288 shared_ptr<ExplainQueryInfo> QueryOptimizerCursorExplainStrategy::_doneQueryInfo () {
@@ -336,22 +340,22 @@ namespace mongo {
336340 _bufferedMatches () {
337341 }
338342
339- bool OrderedBuildStrategy::handleMatch () {
343+ bool OrderedBuildStrategy::handleMatch ( bool &orderedMatch ) {
340344 DiskLoc loc = _cursor->currLoc ();
341345 if ( _cursor->getsetdup ( loc ) ) {
342- return false ;
346+ return orderedMatch = false ;
343347 }
344348 if ( _skip > 0 ) {
345349 --_skip;
346- return false ;
350+ return orderedMatch = false ;
347351 }
348352 // Explain does not obey soft limits, so matches should not be buffered.
349353 if ( !_parsedQuery.isExplain () ) {
350354 fillQueryResultFromObj ( _buf, _parsedQuery.getFields (), current ( true ),
351355 ( _parsedQuery.showDiskLoc () ? &loc : 0 ) );
352356 ++_bufferedMatches;
353357 }
354- return true ;
358+ return orderedMatch = true ;
355359 }
356360
357361 ReorderBuildStrategy::ReorderBuildStrategy ( const ParsedQuery &parsedQuery,
@@ -363,17 +367,18 @@ namespace mongo {
363367 _bufferedMatches () {
364368 }
365369
366- bool ReorderBuildStrategy::handleMatch () {
370+ bool ReorderBuildStrategy::handleMatch ( bool &orderedMatch ) {
371+ orderedMatch = false ;
367372 if ( _cursor->getsetdup ( _cursor->currLoc () ) ) {
368373 return false ;
369374 }
370- return _handleMatchNoDedup ();
375+ _handleMatchNoDedup ();
376+ return true ;
371377 }
372378
373- bool ReorderBuildStrategy::_handleMatchNoDedup () {
379+ void ReorderBuildStrategy::_handleMatchNoDedup () {
374380 DiskLoc loc = _cursor->currLoc ();
375381 _scanAndOrder->add ( current ( false ), _parsedQuery.showDiskLoc () ? &loc : 0 );
376- return false ;
377382 }
378383
379384 int ReorderBuildStrategy::rewriteMatches () {
@@ -412,18 +417,18 @@ namespace mongo {
412417 _reorderedMatches () {
413418 }
414419
415- bool HybridBuildStrategy::handleMatch () {
420+ bool HybridBuildStrategy::handleMatch ( bool &orderedMatch ) {
416421 if ( !_queryOptimizerCursor->currentPlanScanAndOrderRequired () ) {
417- return _orderedBuild.handleMatch ();
422+ return _orderedBuild.handleMatch ( orderedMatch );
418423 }
419- handleReorderMatch () ;
420- return false ;
424+ orderedMatch = false ;
425+ return handleReorderMatch () ;
421426 }
422427
423- void HybridBuildStrategy::handleReorderMatch () {
428+ bool HybridBuildStrategy::handleReorderMatch () {
424429 DiskLoc loc = _cursor->currLoc ();
425430 if ( _scanAndOrderDups.getsetdup ( loc ) ) {
426- return ;
431+ return false ;
427432 }
428433 try {
429434 _reorderBuild._handleMatchNoDedup ();
@@ -435,11 +440,12 @@ namespace mongo {
435440 }
436441 else if ( _queryOptimizerCursor->runningInitialInOrderPlan () ) {
437442 _queryOptimizerCursor->abortOutOfOrderPlans ();
438- return ;
443+ return true ;
439444 }
440445 }
441446 throw ;
442- }
447+ }
448+ return true ;
443449 }
444450
445451 int HybridBuildStrategy::rewriteMatches () {
@@ -482,9 +488,10 @@ namespace mongo {
482488 if ( !chunkMatches () ) {
483489 return false ;
484490 }
485- bool orderedMatch = _builder->handleMatch ();
486- _explain->noteIterate ( orderedMatch, true , false );
487- return true ;
491+ bool orderedMatch = false ;
492+ bool match = _builder->handleMatch ( orderedMatch );
493+ _explain->noteIterate ( match, orderedMatch, true , false );
494+ return match;
488495 }
489496
490497 void QueryResponseBuilder::noteYield () {
@@ -497,7 +504,7 @@ namespace mongo {
497504
498505 bool QueryResponseBuilder::enoughTotalResults () const {
499506 if ( _parsedQuery.isExplain () ) {
500- return _parsedQuery.enoughForExplain ( _explain->matches () );
507+ return _parsedQuery.enoughForExplain ( _explain->orderedMatches () );
501508 }
502509 return ( _parsedQuery.enough ( _builder->bufferedMatches () ) ||
503510 _buf.len () >= MaxBytesToReturnToClientAtOnce );
@@ -584,7 +591,7 @@ namespace mongo {
584591 if ( _cursor->currentMatches ( &details ) ) {
585592 return true ;
586593 }
587- _explain->noteIterate ( false , details._loadedObject , false );
594+ _explain->noteIterate ( false , false , details._loadedObject , false );
588595 return false ;
589596 }
590597
@@ -596,7 +603,7 @@ namespace mongo {
596603 if ( _chunkManager->belongsToMe ( _cursor->current () ) ) {
597604 return true ;
598605 }
599- _explain->noteIterate ( false , true , true );
606+ _explain->noteIterate ( false , false , true , true );
600607 return false ;
601608 }
602609
0 commit comments