From 2df2fe89910ae0c0c78f85e1533c49dfb765a2d0 Mon Sep 17 00:00:00 2001 From: Aaron Date: Mon, 25 Apr 2011 11:13:52 -0700 Subject: reduce queryutil dependencies a bit --- db/oplog.h | 116 +++++-------------------------------------------------------- 1 file changed, 8 insertions(+), 108 deletions(-) (limited to 'db/oplog.h') diff --git a/db/oplog.h b/db/oplog.h index 4b859ecc1e4..601b0a1a0e0 100644 --- a/db/oplog.h +++ b/db/oplog.h @@ -27,7 +27,6 @@ #include "db.h" #include "dbhelpers.h" #include "query.h" -#include "queryoptimizer.h" #include "../client/dbclient.h" #include "../util/optime.h" #include "../util/timer.h" @@ -64,72 +63,14 @@ namespace mongo { extern int __findingStartInitialTimeout; // configurable for testing + class QueryPlan; + class FindingStartCursor { public: - FindingStartCursor( const QueryPlan & qp ) : - _qp( qp ), - _findingStart( true ), - _findingStartMode(), - _findingStartTimer( 0 ) - { init(); } + FindingStartCursor( const QueryPlan & qp ); bool done() const { return !_findingStart; } shared_ptr cRelease() { return _c; } - void next() { - if ( !_findingStartCursor || !_findingStartCursor->ok() ) { - _findingStart = false; - _c = _qp.newCursor(); // on error, start from beginning - destroyClientCursor(); - return; - } - switch( _findingStartMode ) { - case Initial: { - if ( !_matcher->matches( _findingStartCursor->currKey(), _findingStartCursor->currLoc() ) ) { - _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->matches( _findingStartCursor->currKey(), _findingStartCursor->currLoc() ) ) { - _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->matches( _findingStartCursor->currKey(), _findingStartCursor->currLoc() ) ) { - _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 ); - } - } - } + void next(); bool prepareToYield() { if ( _findingStartCursor ) { return _findingStartCursor->prepareToYield( _yieldData ); @@ -153,56 +94,15 @@ namespace mongo { ClientCursor::CleanupPointer _findingStartCursor; shared_ptr _c; ClientCursor::YieldData _yieldData; - DiskLoc startLoc( const DiskLoc &rec ) { - Extent *e = rec.rec()->myExtent( rec ); - if ( !_qp.nsd()->capLooped() || ( e->myLoc != _qp.nsd()->capExtent ) ) - return e->firstRecord; - // Likely we are on the fresh side of capExtent, so return first fresh record. - // If we are on the stale side of capExtent, then the collection is small and it - // doesn't matter if we start the extent scan with capFirstNewRecord. - return _qp.nsd()->capFirstNewRecord; - } + DiskLoc startLoc( const DiskLoc &rec ); // should never have an empty extent in the oplog, so don't worry about that case - DiskLoc prevLoc( const DiskLoc &rec ) { - Extent *e = rec.rec()->myExtent( rec ); - if ( _qp.nsd()->capLooped() ) { - if ( e->xprev.isNull() ) - e = _qp.nsd()->lastExtent.ext(); - else - e = e->xprev.ext(); - if ( e->myLoc != _qp.nsd()->capExtent ) - return e->firstRecord; - } - else { - if ( !e->xprev.isNull() ) { - e = e->xprev.ext(); - return e->firstRecord; - } - } - return DiskLoc(); // reached beginning of collection - } - void createClientCursor( const DiskLoc &startLoc = DiskLoc() ) { - shared_ptr c = _qp.newCursor( startLoc ); - _findingStartCursor.reset( new ClientCursor(QueryOption_NoCursorTimeout, c, _qp.ns()) ); - } + DiskLoc prevLoc( const DiskLoc &rec ); + void createClientCursor( const DiskLoc &startLoc = DiskLoc() ); void destroyClientCursor() { _findingStartCursor.reset( 0 ); } - void init() { - // Use a ClientCursor here so we can release db mutex while scanning - // oplog (can take quite a while with large oplogs). - shared_ptr c = _qp.newReverseCursor(); - _findingStartCursor.reset( new ClientCursor(QueryOption_NoCursorTimeout, c, _qp.ns(), BSONObj()) ); - _findingStartTimer.reset(); - _findingStartMode = Initial; - BSONElement tsElt = _qp.originalQuery()[ "ts" ]; - massert( 13044, "no ts field in query", !tsElt.eoo() ); - BSONObjBuilder b; - b.append( tsElt ); - BSONObj tsQuery = b.obj(); - _matcher.reset(new CoveredIndexMatcher(tsQuery, _qp.indexKey())); - } + void init(); }; void pretouchOperation(const BSONObj& op); -- cgit v1.2.1