Beispiel #1
0
 void FindingStartCursor::next() {
     if ( !_findingStartCursor || !_findingStartCursor->ok() ) {
         _findingStart = false;
         _c = _qp.newCursor(); // on error, start from beginning
         destroyClientCursor();
         return;
     }
     switch( _findingStartMode ) {
         case Initial: {
             if ( !_matcher->matchesCurrent( _findingStartCursor->c() ) ) {
                 _findingStart = false; // found first record out of query range, so scan normally
                 _c = _qp.newCursor( _findingStartCursor->currLoc() );
                 destroyClientCursor();
                 return;
             }
             _findingStartCursor->advance();
             RARELY {
                 if ( _findingStartTimer.seconds() >= __findingStartInitialTimeout ) {
                     createClientCursor( startLoc( _findingStartCursor->currLoc() ) );
                     _findingStartMode = FindExtent;
                     return;
                 }
             }
             return;
         }
         case FindExtent: {
             if ( !_matcher->matchesCurrent( _findingStartCursor->c() ) ) {
                 _findingStartMode = InExtent;
                 return;
             }
             DiskLoc prev = prevLoc( _findingStartCursor->currLoc() );
             if ( prev.isNull() ) { // hit beginning, so start scanning from here
                 createClientCursor();
                 _findingStartMode = InExtent;
                 return;
             }
             // There might be a more efficient implementation than creating new cursor & client cursor each time,
             // not worrying about that for now
             createClientCursor( prev );
             return;
         }
         case InExtent: {
             if ( _matcher->matchesCurrent( _findingStartCursor->c() ) ) {
                 _findingStart = false; // found first record in query range, so scan normally
                 _c = _qp.newCursor( _findingStartCursor->currLoc() );
                 destroyClientCursor();
                 return;
             }
             _findingStartCursor->advance();
             return;
         }
         default: {
             massert( 14038, "invalid _findingStartMode", false );
         }
     }
 }
Beispiel #2
0
 void FindingStartCursor::next() {
     if ( !_findingStartCursor || !_findingStartCursor->ok() ) {
         _findingStart = false;
         _c = _qp.newCursor(); // on error, start from beginning
         destroyClientCursor();
         return;
     }
     switch( _findingStartMode ) {
         // Initial mode: scan backwards from end of collection
         case Initial: {
             if ( !_matcher->matchesCurrent( _findingStartCursor->c() ) ) {
                 _findingStart = false; // found first record out of query range, so scan normally
                 _c = _qp.newCursor( _findingStartCursor->currLoc() );
                 destroyClientCursor();
                 return;
             }
             _findingStartCursor->advance();
             RARELY {
                 if ( _findingStartTimer.seconds() >= __findingStartInitialTimeout ) {
                     // If we've scanned enough, switch to find extent mode.
                     createClientCursor( extentFirstLoc( _findingStartCursor->currLoc() ) );
                     _findingStartMode = FindExtent;
                     return;
                 }
             }
             return;
         }
         // FindExtent mode: moving backwards through extents, check first
         // document of each extent.
         case FindExtent: {
             if ( !_matcher->matchesCurrent( _findingStartCursor->c() ) ) {
                 _findingStartMode = InExtent;
                 return;
             }
             DiskLoc prev = prevExtentFirstLoc( _findingStartCursor->currLoc() );
             if ( prev.isNull() ) { // hit beginning, so start scanning from here
                 createClientCursor();
                 _findingStartMode = InExtent;
                 return;
             }
             // There might be a more efficient implementation than creating new cursor & client cursor each time,
             // not worrying about that for now
             createClientCursor( prev );
             return;
         }
         // InExtent mode: once an extent is chosen, find starting doc in the extent.
         case InExtent: {
             if ( _matcher->matchesCurrent( _findingStartCursor->c() ) ) {
                 _findingStart = false; // found first record in query range, so scan normally
                 _c = _qp.newCursor( _findingStartCursor->currLoc() );
                 destroyClientCursor();
                 return;
             }
             _findingStartCursor->advance();
             return;
         }
         default: {
             massert( 14038, "invalid _findingStartMode", false );
         }
     }
 }