diff options
author | Eliot Horowitz <eliot@10gen.com> | 2014-04-17 02:42:34 -0400 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2014-04-17 13:14:04 -0400 |
commit | 92748f2572fd6492bfccd56e339b7255017d15ee (patch) | |
tree | b1b40e383042ca10fc52b72e678765bb22e67fcf /src/mongo | |
parent | ce52f313ca52759d606886641f44541bd7baf5bd (diff) | |
download | mongo-92748f2572fd6492bfccd56e339b7255017d15ee.tar.gz |
SERVER-13084: remove many cc() calls from query/exec world
Diffstat (limited to 'src/mongo')
64 files changed, 317 insertions, 265 deletions
diff --git a/src/mongo/db/auth/authz_manager_external_state_d.cpp b/src/mongo/db/auth/authz_manager_external_state_d.cpp index 6263a0d67f0..388644f9bdc 100644 --- a/src/mongo/db/auth/authz_manager_external_state_d.cpp +++ b/src/mongo/db/auth/authz_manager_external_state_d.cpp @@ -108,7 +108,7 @@ namespace mongo { Client::ReadContext ctx(collectionName.ns()); BSONObj found; - if (Helpers::findOne(collectionName.ns(), + if (Helpers::findOne(ctx.ctx().db()->getCollection(collectionName), query, found)) { *result = found.getOwned(); diff --git a/src/mongo/db/catalog/collection.h b/src/mongo/db/catalog/collection.h index f633a5444cf..4c84a8370df 100644 --- a/src/mongo/db/catalog/collection.h +++ b/src/mongo/db/catalog/collection.h @@ -139,8 +139,9 @@ namespace mongo { * canonical to get all would be * getIterator( DiskLoc(), false, CollectionScanParams::FORWARD ) */ - RecordIterator* getIterator( const DiskLoc& start, bool tailable, - const CollectionScanParams::Direction& dir) const; + RecordIterator* getIterator( const DiskLoc& start = DiskLoc(), + bool tailable = false, + const CollectionScanParams::Direction& dir = CollectionScanParams::FORWARD ) const; /** diff --git a/src/mongo/db/catalog/database.cpp b/src/mongo/db/catalog/database.cpp index 5f8e530202d..ece0e04db27 100644 --- a/src/mongo/db/catalog/database.cpp +++ b/src/mongo/db/catalog/database.cpp @@ -308,33 +308,32 @@ namespace mongo { void Database::clearTmpCollections() { Lock::assertWriteLocked( _name ); - Client::Context ctx( _name ); - - string systemNamespaces = _name + ".system.namespaces"; // Note: we build up a toDelete vector rather than dropping the collection inside the loop // to avoid modifying the system.namespaces collection while iterating over it since that // would corrupt the cursor. vector<string> toDelete; - auto_ptr<Runner> runner(InternalPlanner::collectionScan(systemNamespaces)); - BSONObj nsObj; - Runner::RunnerState state; - while (Runner::RUNNER_ADVANCED == (state = runner->getNext(&nsObj, NULL))) { - BSONElement e = nsObj.getFieldDotted( "options.temp" ); - if ( !e.trueValue() ) - continue; + { + Collection* coll = getCollection( _namespacesName ); + if ( coll ) { + scoped_ptr<RecordIterator> it( coll->getIterator() ); + DiskLoc next; + while ( !( next = it->getNext() ).isNull() ) { + BSONObj nsObj = coll->docFor( next ); - string ns = nsObj["name"].String(); + BSONElement e = nsObj.getFieldDotted( "options.temp" ); + if ( !e.trueValue() ) + continue; - // Do not attempt to drop indexes - if ( !NamespaceString::normal(ns.c_str()) ) - continue; + string ns = nsObj["name"].String(); - toDelete.push_back(ns); - } + // Do not attempt to drop indexes + if ( !NamespaceString::normal(ns.c_str()) ) + continue; - if (Runner::RUNNER_EOF != state) { - warning() << "Internal error while reading collection " << systemNamespaces << endl; + toDelete.push_back(ns); + } + } } for (size_t i=0; i < toDelete.size(); i++) { @@ -509,7 +508,9 @@ namespace mongo { // move index namespaces BSONObj oldIndexSpec; - while( Helpers::findOne( _indexesName, BSON( "ns" << fromNS ), oldIndexSpec ) ) { + while( Helpers::findOne( getCollection( _indexesName ), + BSON( "ns" << fromNS ), + oldIndexSpec ) ) { oldIndexSpec = oldIndexSpec.getOwned(); BSONObj newIndexSpec; @@ -615,7 +616,9 @@ namespace mongo { { BSONObj oldSpec; - if ( !Helpers::findOne( _namespacesName, BSON( "name" << fromNS ), oldSpec ) ) + if ( !Helpers::findOne( getCollection( _namespacesName ), + BSON( "name" << fromNS ), + oldSpec ) ) return Status( ErrorCodes::InternalError, "can't find system.namespaces entry" ); BSONObjBuilder b; diff --git a/src/mongo/db/catalog/index_catalog.cpp b/src/mongo/db/catalog/index_catalog.cpp index 6f900fca99c..6376ea048d7 100644 --- a/src/mongo/db/catalog/index_catalog.cpp +++ b/src/mongo/db/catalog/index_catalog.cpp @@ -255,7 +255,8 @@ namespace mongo { fassert(16737, dfh->versionMinor == PDFILE_VERSION_MINOR_22_AND_OLDER); - auto_ptr<Runner> runner( InternalPlanner::collectionScan( db->_indexesName ) ); + auto_ptr<Runner> runner( InternalPlanner::collectionScan( db->_indexesName, + db->getCollection( db->_indexesName ) ) ); BSONObj index; Runner::RunnerState state; diff --git a/src/mongo/db/catalog/index_create.cpp b/src/mongo/db/catalog/index_create.cpp index 744ed46d96d..44e1fa157c8 100644 --- a/src/mongo/db/catalog/index_create.cpp +++ b/src/mongo/db/catalog/index_create.cpp @@ -104,7 +104,7 @@ namespace mongo { unsigned long long n = 0; unsigned long long numDropped = 0; - auto_ptr<Runner> runner(InternalPlanner::collectionScan(ns)); + auto_ptr<Runner> runner(InternalPlanner::collectionScan(ns,collection)); // We're not delegating yielding to the runner because we need to know when a yield // happens. diff --git a/src/mongo/db/commands/collection_to_capped.cpp b/src/mongo/db/commands/collection_to_capped.cpp index e1fe3c6c1c6..d7304afc31d 100644 --- a/src/mongo/db/commands/collection_to_capped.cpp +++ b/src/mongo/db/commands/collection_to_capped.cpp @@ -81,6 +81,7 @@ namespace mongo { ( toCollection->storageSize() * 2 ) ); scoped_ptr<Runner> runner( InternalPlanner::collectionScan(fromNs, + fromCollection, InternalPlanner::FORWARD ) ); diff --git a/src/mongo/db/commands/dbhash.cpp b/src/mongo/db/commands/dbhash.cpp index 227473dabd8..61e75e61e61 100644 --- a/src/mongo/db/commands/dbhash.cpp +++ b/src/mongo/db/commands/dbhash.cpp @@ -98,7 +98,8 @@ namespace mongo { InternalPlanner::IXSCAN_FETCH)); } else if ( collection->details()->isCapped() ) { - runner.reset(InternalPlanner::collectionScan(fullCollectionName)); + runner.reset(InternalPlanner::collectionScan(fullCollectionName, + collection)); } else { log() << "can't find _id index for: " << fullCollectionName << endl; diff --git a/src/mongo/db/commands/find_and_modify.cpp b/src/mongo/db/commands/find_and_modify.cpp index 6ec6f6f87c5..072bb2d8000 100644 --- a/src/mongo/db/commands/find_and_modify.cpp +++ b/src/mongo/db/commands/find_and_modify.cpp @@ -139,6 +139,7 @@ namespace mongo { Lock::DBWrite lk( ns ); Client::Context cx( ns ); + Collection* collection = cx.db()->getCollection( ns ); BSONObj doc; bool found = false; @@ -149,7 +150,7 @@ namespace mongo { Runner* rawRunner; massert(17384, "Could not get runner for query " + queryOriginal.toString(), - getRunner(cq, &rawRunner, QueryPlannerParams::DEFAULT).isOK()); + getRunner(collection, cq, &rawRunner, QueryPlannerParams::DEFAULT).isOK()); auto_ptr<Runner> runner(rawRunner); @@ -255,6 +256,10 @@ namespace mongo { UpdateLifecycleImpl updateLifecycle(false, requestNs); request.setLifecycle(&updateLifecycle); UpdateResult res = mongo::update(request, &cc().curop()->debug()); + if ( !collection ) { + // collection created by an upsert + collection = cx.db()->getCollection( ns ); + } LOG(3) << "update result: " << res ; if ( returnNew ) { @@ -270,7 +275,7 @@ namespace mongo { } LOG(3) << "using modified query to return the new doc: " << queryModified; - if ( ! Helpers::findOne( ns.c_str() , queryModified , doc ) ) { + if ( ! Helpers::findOne( collection, queryModified, doc ) ) { errmsg = str::stream() << "can't find object after modification " << " ns: " << ns << " queryModified: " << queryModified diff --git a/src/mongo/db/commands/geonear.cpp b/src/mongo/db/commands/geonear.cpp index 135b861005c..1df9385c43e 100644 --- a/src/mongo/db/commands/geonear.cpp +++ b/src/mongo/db/commands/geonear.cpp @@ -177,7 +177,7 @@ namespace mongo { } Runner* rawRunner; - if (!getRunner(cq, &rawRunner, 0).isOK()) { + if (!getRunner(collection, cq, &rawRunner, 0).isOK()) { errmsg = "can't get query runner"; return false; } diff --git a/src/mongo/db/commands/group.cpp b/src/mongo/db/commands/group.cpp index b431853eb05..e0e28264b13 100644 --- a/src/mongo/db/commands/group.cpp +++ b/src/mongo/db/commands/group.cpp @@ -144,7 +144,7 @@ namespace mongo { } Runner* rawRunner; - if (!getRunner(cq, &rawRunner).isOK()) { + if (!getRunner(collection, cq, &rawRunner).isOK()) { uasserted(17213, "Can't get runner for query " + query.toString()); return 0; } diff --git a/src/mongo/db/commands/mr.cpp b/src/mongo/db/commands/mr.cpp index 9306256f631..1f72e6648a2 100644 --- a/src/mongo/db/commands/mr.cpp +++ b/src/mongo/db/commands/mr.cpp @@ -591,7 +591,8 @@ namespace mongo { bool found; { Client::Context tx( _config.outputOptions.finalNamespace ); - found = Helpers::findOne(_config.outputOptions.finalNamespace.c_str(), + Collection* coll = tx.db()->getCollection( _config.outputOptions.finalNamespace ); + found = Helpers::findOne(coll, temp["_id"].wrap(), old, true); @@ -958,7 +959,8 @@ namespace mongo { verify(CanonicalQuery::canonicalize(_config.incLong, BSONObj(), sortKey, BSONObj(), &cq).isOK()); Runner* rawRunner; - verify(getRunner(cq, &rawRunner, QueryPlannerParams::NO_TABLE_SCAN).isOK()); + verify(getRunner(ctx.ctx().db()->getCollection(_config.incLong), + cq, &rawRunner, QueryPlannerParams::NO_TABLE_SCAN).isOK()); auto_ptr<Runner> runner(rawRunner); const ScopedRunnerRegistration safety(runner.get()); @@ -1297,7 +1299,7 @@ namespace mongo { } Runner* rawRunner; - if (!getRunner(cq, &rawRunner).isOK()) { + if (!getRunner(ctx.db()->getCollection( config.ns), cq, &rawRunner).isOK()) { uasserted(17239, "Can't get runner for query " + config.filter.toString()); return 0; } diff --git a/src/mongo/db/commands/pipeline_command.cpp b/src/mongo/db/commands/pipeline_command.cpp index a0902a3cab2..3cf66336dfc 100644 --- a/src/mongo/db/commands/pipeline_command.cpp +++ b/src/mongo/db/commands/pipeline_command.cpp @@ -319,7 +319,9 @@ namespace { // This does mongod-specific stuff like creating the input Runner and adding to the // front of the pipeline if needed. - boost::shared_ptr<Runner> input = PipelineD::prepareCursorSource(pPipeline, pCtx); + boost::shared_ptr<Runner> input = PipelineD::prepareCursorSource(collection, + pPipeline, + pCtx); pPipeline->stitch(); runnerHolder.reset(new PipelineRunner(pPipeline, input)); diff --git a/src/mongo/db/commands/test_commands.cpp b/src/mongo/db/commands/test_commands.cpp index ffbb052e1fb..0553f314a12 100644 --- a/src/mongo/db/commands/test_commands.cpp +++ b/src/mongo/db/commands/test_commands.cpp @@ -146,6 +146,7 @@ namespace mongo { massert( 13417, "captrunc collection not found or empty", collection); boost::scoped_ptr<Runner> runner(InternalPlanner::collectionScan(nss.ns(), + collection, InternalPlanner::BACKWARD)); DiskLoc end; // We remove 'n' elements so the start is one past that diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp index 795d36094b3..5fc8ed61c86 100644 --- a/src/mongo/db/db.cpp +++ b/src/mongo/db/db.cpp @@ -414,8 +414,9 @@ namespace mongo { } } else { - const string systemIndexes = cc().database()->name() + ".system.indexes"; - auto_ptr<Runner> runner(InternalPlanner::collectionScan(systemIndexes)); + const string systemIndexes = ctx.db()->name() + ".system.indexes"; + Collection* coll = ctx.db()->getCollection( systemIndexes ); + auto_ptr<Runner> runner(InternalPlanner::collectionScan(systemIndexes,coll)); BSONObj index; Runner::RunnerState state; while (Runner::RUNNER_ADVANCED == (state = runner->getNext(&index, NULL))) { diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp index e8dd0904832..fdedbb125a1 100644 --- a/src/mongo/db/dbcommands.cpp +++ b/src/mongo/db/dbcommands.cpp @@ -808,10 +808,6 @@ namespace mongo { bool run(const string& dbname, BSONObj& jsobj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl ) { const std::string ns = parseNs(dbname, jsobj); - // Check shard version at startup. - // This will throw before we've done any work if shard version is outdated - Client::ReadContext ctx(ns); - md5digest d; md5_state_t st; md5_init(&st); @@ -837,6 +833,11 @@ namespace mongo { BSONObj query = BSON( "files_id" << jsobj["filemd5"] << "n" << GTE << n ); BSONObj sort = BSON( "files_id" << 1 << "n" << 1 ); + // Check shard version at startup. + // This will throw before we've done any work if shard version is outdated + Client::ReadContext ctx(ns); + Collection* coll = ctx.ctx().db()->getCollection(ns); + CanonicalQuery* cq; if (!CanonicalQuery::canonicalize(ns, query, sort, BSONObj(), &cq).isOK()) { uasserted(17240, "Can't canonicalize query " + query.toString()); @@ -844,7 +845,7 @@ namespace mongo { } Runner* rawRunner; - if (!getRunner(cq, &rawRunner, QueryPlannerParams::NO_TABLE_SCAN).isOK()) { + if (!getRunner(coll, cq, &rawRunner, QueryPlannerParams::NO_TABLE_SCAN).isOK()) { uasserted(17241, "Can't get runner for query " + query.toString()); return 0; } @@ -989,7 +990,7 @@ namespace mongo { result.append( "millis" , timer.millis() ); return 1; } - runner.reset(InternalPlanner::collectionScan(ns)); + runner.reset(InternalPlanner::collectionScan(ns,collection)); } else if ( min.isEmpty() || max.isEmpty() ) { errmsg = "only one of min or max specified"; diff --git a/src/mongo/db/dbhelpers.cpp b/src/mongo/db/dbhelpers.cpp index 9808c7e7f7c..6ffaaf6c2fc 100644 --- a/src/mongo/db/dbhelpers.cpp +++ b/src/mongo/db/dbhelpers.cpp @@ -89,8 +89,8 @@ namespace mongo { /* fetch a single object from collection ns that matches query set your db SavedContext first */ - bool Helpers::findOne(const StringData& ns, const BSONObj &query, BSONObj& result, bool requireIndex) { - DiskLoc loc = findOne( ns, query, requireIndex ); + bool Helpers::findOne(Collection* collection, const BSONObj &query, BSONObj& result, bool requireIndex) { + DiskLoc loc = findOne( collection, query, requireIndex ); if ( loc.isNull() ) return false; result = loc.obj(); @@ -100,15 +100,18 @@ namespace mongo { /* fetch a single object from collection ns that matches query set your db SavedContext first */ - DiskLoc Helpers::findOne(const StringData& ns, const BSONObj &query, bool requireIndex) { + DiskLoc Helpers::findOne(Collection* collection, const BSONObj &query, bool requireIndex) { + if ( !collection ) + return DiskLoc(); + CanonicalQuery* cq; massert(17244, "Could not canonicalize " + query.toString(), - CanonicalQuery::canonicalize(ns.toString(), query, &cq).isOK()); + CanonicalQuery::canonicalize(collection->ns(), query, &cq).isOK()); Runner* rawRunner; size_t options = requireIndex ? QueryPlannerParams::NO_TABLE_SCAN : QueryPlannerParams::DEFAULT; massert(17245, "Could not get runner for query " + query.toString(), - getRunner(cq, &rawRunner, options).isOK()); + getRunner(collection, cq, &rawRunner, options).isOK()); auto_ptr<Runner> runner(rawRunner); Runner::RunnerState state; @@ -174,7 +177,7 @@ namespace mongo { Runner* rawRunner; uassert(17237, "Could not get runner for query " + query.toString(), - getRunner(cq, &rawRunner).isOK()); + getRunner(ctx.db()->getCollection( ns ), cq, &rawRunner).isOK()); vector<BSONObj> all; @@ -190,7 +193,8 @@ namespace mongo { bool Helpers::isEmpty(const char *ns) { Client::Context context(ns, storageGlobalParams.dbpath); - auto_ptr<Runner> runner(InternalPlanner::collectionScan(ns)); + auto_ptr<Runner> runner(InternalPlanner::collectionScan(ns, + context.db()->getCollection(ns))); return Runner::RUNNER_EOF == runner->getNext(NULL, NULL); } @@ -201,7 +205,8 @@ namespace mongo { */ bool Helpers::getSingleton(const char *ns, BSONObj& result) { Client::Context context(ns); - auto_ptr<Runner> runner(InternalPlanner::collectionScan(ns)); + auto_ptr<Runner> runner(InternalPlanner::collectionScan(ns, + context.db()->getCollection(ns))); Runner::RunnerState state = runner->getNext(&result, NULL); context.getClient()->curop()->done(); return Runner::RUNNER_ADVANCED == state; @@ -209,7 +214,10 @@ namespace mongo { bool Helpers::getLast(const char *ns, BSONObj& result) { Client::Context ctx(ns); - auto_ptr<Runner> runner(InternalPlanner::collectionScan(ns, InternalPlanner::BACKWARD)); + Collection* coll = ctx.db()->getCollection( ns ); + auto_ptr<Runner> runner(InternalPlanner::collectionScan(ns, + coll, + InternalPlanner::BACKWARD)); Runner::RunnerState state = runner->getNext(&result, NULL); return Runner::RUNNER_ADVANCED == state; } diff --git a/src/mongo/db/dbhelpers.h b/src/mongo/db/dbhelpers.h index a8aebc58c25..15aa8d96e77 100644 --- a/src/mongo/db/dbhelpers.h +++ b/src/mongo/db/dbhelpers.h @@ -80,8 +80,10 @@ namespace mongo { @return true if object found */ - static bool findOne(const StringData& ns, const BSONObj &query, BSONObj& result, bool requireIndex = false); - static DiskLoc findOne(const StringData& ns, const BSONObj &query, bool requireIndex); + static bool findOne(Collection* collection, const BSONObj &query, + BSONObj& result, bool requireIndex = false); + static DiskLoc findOne(Collection* collection, const BSONObj &query, + bool requireIndex); /** * have to be locked already diff --git a/src/mongo/db/exec/2d.cpp b/src/mongo/db/exec/2d.cpp index 7c5da3f4141..0d9a4b301c4 100644 --- a/src/mongo/db/exec/2d.cpp +++ b/src/mongo/db/exec/2d.cpp @@ -38,7 +38,8 @@ namespace mongo { TwoD::TwoD(const TwoDParams& params, WorkingSet* ws) : _params(params), _workingSet(ws), _initted(false), - _descriptor(NULL), _am(NULL) { } + _descriptor(NULL), _am(NULL) { + } TwoD::~TwoD() { } @@ -52,19 +53,16 @@ namespace mongo { if (!_initted) { _initted = true; - Database* database = cc().database(); - if ( !database ) + if ( !_params.collection ) return PlanStage::IS_EOF; - Collection* collection = database->getCollection( _params.ns ); - if ( !collection ) - return PlanStage::IS_EOF; + IndexCatalog* indexCatalog = _params.collection->getIndexCatalog(); - _descriptor = collection->getIndexCatalog()->findIndexByKeyPattern(_params.indexKeyPattern); + _descriptor = indexCatalog->findIndexByKeyPattern(_params.indexKeyPattern); if ( _descriptor == NULL ) return PlanStage::IS_EOF; - _am = static_cast<TwoDAccessMethod*>( collection->getIndexCatalog()->getIndex( _descriptor ) ); + _am = static_cast<TwoDAccessMethod*>( indexCatalog->getIndex( _descriptor ) ); verify( _am ); if (NULL != _params.gq.getGeometry()._cap.get()) { diff --git a/src/mongo/db/exec/2d.h b/src/mongo/db/exec/2d.h index ae8cdfd2595..0f0cdd111de 100644 --- a/src/mongo/db/exec/2d.h +++ b/src/mongo/db/exec/2d.h @@ -35,11 +35,11 @@ namespace mongo { struct TwoDParams { - TwoDParams() : filter(NULL) { } + TwoDParams() : filter(NULL), collection(NULL) { } GeoQuery gq; MatchExpression* filter; BSONObj indexKeyPattern; - string ns; + Collection* collection; // not owned }; class TwoD : public PlanStage { diff --git a/src/mongo/db/exec/2dnear.cpp b/src/mongo/db/exec/2dnear.cpp index d739c4ca8b7..3f62aeefac9 100644 --- a/src/mongo/db/exec/2dnear.cpp +++ b/src/mongo/db/exec/2dnear.cpp @@ -54,17 +54,15 @@ namespace mongo { if (!_initted) { _initted = true; - Database* db = cc().database(); - if ( !db ) - return PlanStage::IS_EOF; - Collection* collection = db->getCollection( _params.ns ); - if ( !collection ) + if ( !_params.collection ) return PlanStage::IS_EOF; - IndexDescriptor* desc = collection->getIndexCatalog()->findIndexByKeyPattern(_params.indexKeyPattern); + IndexCatalog* indexCatalog = _params.collection->getIndexCatalog(); + + IndexDescriptor* desc = indexCatalog->findIndexByKeyPattern(_params.indexKeyPattern); if ( desc == NULL ) return PlanStage::IS_EOF; - TwoDAccessMethod* am = static_cast<TwoDAccessMethod*>( collection->getIndexCatalog()->getIndex( desc ) ); + TwoDAccessMethod* am = static_cast<TwoDAccessMethod*>( indexCatalog->getIndex( desc ) ); auto_ptr<twod_exec::GeoSearch> search; search.reset(new twod_exec::GeoSearch(am, diff --git a/src/mongo/db/exec/2dnear.h b/src/mongo/db/exec/2dnear.h index 7b8a8b66fa4..9768ebb90c4 100644 --- a/src/mongo/db/exec/2dnear.h +++ b/src/mongo/db/exec/2dnear.h @@ -41,7 +41,7 @@ namespace mongo { struct TwoDNearParams { NearQuery nearQuery; - string ns; + Collection* collection; // not owned BSONObj indexKeyPattern; MatchExpression* filter; int numWanted; diff --git a/src/mongo/db/exec/collection_scan.cpp b/src/mongo/db/exec/collection_scan.cpp index e652099faa5..b74682c47c4 100644 --- a/src/mongo/db/exec/collection_scan.cpp +++ b/src/mongo/db/exec/collection_scan.cpp @@ -79,15 +79,14 @@ namespace mongo { // Do some init if we haven't already. if (NULL == _iter) { - Collection* collection = cc().database()->getCollection( _params.ns ); - if ( collection == NULL ) { + if ( _params.collection == NULL ) { _nsDropped = true; return PlanStage::DEAD; } - _iter.reset( collection->getIterator( _params.start, - _params.tailable, - _params.direction ) ); + _iter.reset( _params.collection->getIterator( _params.start, + _params.tailable, + _params.direction ) ); ++_commonStats.needTime; return PlanStage::NEED_TIME; diff --git a/src/mongo/db/exec/collection_scan.h b/src/mongo/db/exec/collection_scan.h index 0b1a63bf9ab..05b38df9d52 100644 --- a/src/mongo/db/exec/collection_scan.h +++ b/src/mongo/db/exec/collection_scan.h @@ -58,7 +58,6 @@ namespace mongo { virtual void recoverFromYield(); virtual PlanStageStats* getStats(); - private: /** * Returns true if the record 'loc' references is in memory, false otherwise. diff --git a/src/mongo/db/exec/collection_scan_common.h b/src/mongo/db/exec/collection_scan_common.h index 9c88e7653f6..92a3c19fbbc 100644 --- a/src/mongo/db/exec/collection_scan_common.h +++ b/src/mongo/db/exec/collection_scan_common.h @@ -32,19 +32,23 @@ namespace mongo { + class Collection; + struct CollectionScanParams { enum Direction { FORWARD = 1, BACKWARD = -1, }; - CollectionScanParams() : start(DiskLoc()), + CollectionScanParams() : collection(NULL), + start(DiskLoc()), direction(FORWARD), tailable(false), maxScan(0) { } // What collection? - string ns; + // not owned + Collection* collection; // isNull by default. If you specify any value for this, you're responsible for the DiskLoc // not being invalidated before the first call to work(...). diff --git a/src/mongo/db/exec/oplogstart.cpp b/src/mongo/db/exec/oplogstart.cpp index f6754d42670..15f0036c563 100644 --- a/src/mongo/db/exec/oplogstart.cpp +++ b/src/mongo/db/exec/oplogstart.cpp @@ -38,13 +38,14 @@ namespace mongo { // Does not take ownership. - OplogStart::OplogStart(const string& ns, MatchExpression* filter, WorkingSet* ws) + OplogStart::OplogStart(Collection* collection, MatchExpression* filter, WorkingSet* ws) : _needInit(true), _backwardsScanning(false), _extentHopping(false), _done(false), + _collection(collection), + _nsd(NULL), _workingSet(ws), - _ns(ns), _filter(filter) { } OplogStart::~OplogStart() { } @@ -53,11 +54,10 @@ namespace mongo { // We do our (heavy) init in a work(), where work is expected. if (_needInit) { CollectionScanParams params; - params.ns = _ns; + params.collection = _collection; params.direction = CollectionScanParams::BACKWARD; _cs.reset(new CollectionScan(params, _workingSet, NULL)); - Collection* collection = cc().database()->getCollection( _ns ); - _nsd = collection->details(); + _nsd = _collection->details(); _needInit = false; _backwardsScanning = true; _timer.reset(); diff --git a/src/mongo/db/exec/oplogstart.h b/src/mongo/db/exec/oplogstart.h index 1fce80218d4..f2a0b76c478 100644 --- a/src/mongo/db/exec/oplogstart.h +++ b/src/mongo/db/exec/oplogstart.h @@ -61,7 +61,7 @@ namespace mongo { class OplogStart : public PlanStage { public: // Does not take ownership. - OplogStart(const string& ns, MatchExpression* filter, WorkingSet* ws); + OplogStart(Collection* collection, MatchExpression* filter, WorkingSet* ws); virtual ~OplogStart(); virtual StageState work(WorkingSetID* out); @@ -107,6 +107,7 @@ namespace mongo { // Our final state: done. bool _done; + Collection* _collection; const NamespaceDetails* _nsd; // We only go backwards via a collscan for a few seconds. @@ -116,7 +117,7 @@ namespace mongo { WorkingSet* _workingSet; string _ns; - + MatchExpression* _filter; static int _backwardsScanTime; diff --git a/src/mongo/db/exec/plan_stage.h b/src/mongo/db/exec/plan_stage.h index 6797841971e..304baf50bf5 100644 --- a/src/mongo/db/exec/plan_stage.h +++ b/src/mongo/db/exec/plan_stage.h @@ -34,6 +34,7 @@ namespace mongo { + class Collection; class DiskLoc; /** @@ -220,6 +221,7 @@ namespace mongo { * Caller owns returned pointer. */ virtual PlanStageStats* getStats() = 0; + }; } // namespace mongo diff --git a/src/mongo/db/exec/s2near.cpp b/src/mongo/db/exec/s2near.cpp index 8ad0c2bd9eb..2af9b6259a7 100644 --- a/src/mongo/db/exec/s2near.cpp +++ b/src/mongo/db/exec/s2near.cpp @@ -80,19 +80,13 @@ namespace mongo { _outerRadiusInclusive = false; // Grab the IndexDescriptor. - Database* db = cc().database(); - if (!db) { + if ( !_params.collection ) { _failed = true; return; } - Collection* collection = db->getCollection(_params.ns); - if (!collection) { - _failed = true; - return; - } - - _descriptor = collection->getIndexCatalog()->findIndexByKeyPattern(_params.indexKeyPattern); + _descriptor = + _params.collection->getIndexCatalog()->findIndexByKeyPattern(_params.indexKeyPattern); if (NULL == _descriptor) { _failed = true; return; diff --git a/src/mongo/db/exec/s2near.h b/src/mongo/db/exec/s2near.h index 054b4cce16f..add9cf6ef29 100644 --- a/src/mongo/db/exec/s2near.h +++ b/src/mongo/db/exec/s2near.h @@ -44,7 +44,8 @@ namespace mongo { struct S2NearParams { - string ns; + S2NearParams() : collection(NULL) { } + Collection* collection; BSONObj indexKeyPattern; NearQuery nearQuery; IndexBounds baseBounds; diff --git a/src/mongo/db/exec/sort.cpp b/src/mongo/db/exec/sort.cpp index db7b6a5777d..f9119cd1a72 100644 --- a/src/mongo/db/exec/sort.cpp +++ b/src/mongo/db/exec/sort.cpp @@ -44,7 +44,10 @@ namespace mongo { const size_t kMaxBytes = 32 * 1024 * 1024; - SortStageKeyGenerator::SortStageKeyGenerator(const BSONObj& sortSpec, const BSONObj& queryObj) { + SortStageKeyGenerator::SortStageKeyGenerator(Collection* collection, + const BSONObj& sortSpec, + const BSONObj& queryObj) { + _collection = collection; _hasBounds = false; _sortHasMeta = false; _rawSortSpec = sortSpec; @@ -275,7 +278,8 @@ namespace mongo { } SortStage::SortStage(const SortStageParams& params, WorkingSet* ws, PlanStage* child) - : _ws(ws), + : _collection(params.collection), + _ws(ws), _child(child), _pattern(params.pattern), _query(params.query), @@ -298,7 +302,7 @@ namespace mongo { if (NULL == _sortKeyGen) { // This is heavy and should be done as part of work(). - _sortKeyGen.reset(new SortStageKeyGenerator(_pattern, _query)); + _sortKeyGen.reset(new SortStageKeyGenerator(_collection, _pattern, _query)); _sortKeyComparator.reset(new WorkingSetComparator(_sortKeyGen->getSortComparator())); // If limit > 1, we need to initialize _dataSet here to maintain ordered // set of data items while fetching from the child stage. diff --git a/src/mongo/db/exec/sort.h b/src/mongo/db/exec/sort.h index 91fbb0826f4..e67305504ba 100644 --- a/src/mongo/db/exec/sort.h +++ b/src/mongo/db/exec/sort.h @@ -47,7 +47,9 @@ namespace mongo { // Parameters that must be provided to a SortStage class SortStageParams { public: - SortStageParams() : limit(0) { } + SortStageParams() : collection( NULL), limit(0) { } + + Collection* collection; // How we're sorting. BSONObj pattern; @@ -71,12 +73,15 @@ namespace mongo { * ensure that the value we select to sort by is within bounds generated by * executing 'queryObj' using the virtual index with key pattern 'sortSpec'. */ - SortStageKeyGenerator(const BSONObj& sortSpec, const BSONObj& queryObj); + SortStageKeyGenerator(Collection* collection, + const BSONObj& sortSpec, + const BSONObj& queryObj); /** * Returns the key used to sort 'member'. */ - Status getSortKey(const WorkingSetMember& member, BSONObj* objOut) const; + Status getSortKey(const WorkingSetMember& member, + BSONObj* objOut) const; /** * Passed to std::sort and used to sort the keys that are returned from getSortKey. @@ -96,7 +101,10 @@ namespace mongo { * * Populates _hasBounds and _bounds. */ - void getBoundsForSort(const BSONObj& queryObj, const BSONObj& sortObj); + void getBoundsForSort(const BSONObj& queryObj, + const BSONObj& sortObj); + + Collection* _collection; // The object that we use to call woCompare on our resulting key. Is equal to _rawSortSpec // unless we have some $meta expressions. Each $meta expression has a default sort order. @@ -152,6 +160,8 @@ namespace mongo { // Query Stage // + Collection* _collection; + // Not owned by us. WorkingSet* _ws; diff --git a/src/mongo/db/exec/stagedebug_cmd.cpp b/src/mongo/db/exec/stagedebug_cmd.cpp index 5d4f36d31da..f2af118dc6d 100644 --- a/src/mongo/db/exec/stagedebug_cmd.cpp +++ b/src/mongo/db/exec/stagedebug_cmd.cpp @@ -295,9 +295,9 @@ namespace mongo { CollectionScanParams params; // What collection? - params.ns = dbname + "." + nodeArgs["name"].String(); - uassert(16962, "Can't find collection " + nodeArgs["name"].String(), - NULL != cc().database()->getCollection(params.ns)); + string ns = dbname + "." + nodeArgs["name"].String(); + params.collection = cc().database()->getCollection(ns); + uassert(16962, "Can't find collection " + ns, NULL != params.collection ); // What direction? uassert(16963, "Direction argument must be specified and be a number", @@ -364,7 +364,6 @@ namespace mongo { FTSAccessMethod* fam = dynamic_cast<FTSAccessMethod*>( collection->getIndexCatalog()->getIndex( index ) ); TextStageParams params(fam->getSpec()); - params.ns = ns; params.index = index; // TODO: Deal with non-empty filters. This is a hack to put in covering information diff --git a/src/mongo/db/exec/text.h b/src/mongo/db/exec/text.h index 932e0de2e7c..29c1210deab 100644 --- a/src/mongo/db/exec/text.h +++ b/src/mongo/db/exec/text.h @@ -55,9 +55,6 @@ namespace mongo { struct TextStageParams { TextStageParams(const FTSSpec& s) : spec(s) {} - // Namespace. - string ns; - // Text index descriptor. IndexCatalog owns this. IndexDescriptor* index; diff --git a/src/mongo/db/fts/fts_command_mongod.cpp b/src/mongo/db/fts/fts_command_mongod.cpp index 7240d587a7c..695a6e937e5 100644 --- a/src/mongo/db/fts/fts_command_mongod.cpp +++ b/src/mongo/db/fts/fts_command_mongod.cpp @@ -31,6 +31,7 @@ #include <string> #include "mongo/db/client.h" +#include "mongo/db/catalog/database.h" #include "mongo/db/fts/fts_command.h" #include "mongo/db/fts/fts_util.h" #include "mongo/db/pdfile.h" @@ -103,7 +104,7 @@ namespace mongo { } Runner* rawRunner; - Status getRunnerStatus = getRunner(cq, &rawRunner, 0); + Status getRunnerStatus = getRunner(ctx.ctx().db()->getCollection(ns), cq, &rawRunner); if (!getRunnerStatus.isOK()) { errmsg = getRunnerStatus.reason(); return false; diff --git a/src/mongo/db/pipeline/pipeline_d.cpp b/src/mongo/db/pipeline/pipeline_d.cpp index 15615a4cbe5..73e011e7065 100644 --- a/src/mongo/db/pipeline/pipeline_d.cpp +++ b/src/mongo/db/pipeline/pipeline_d.cpp @@ -65,6 +65,7 @@ namespace { } boost::shared_ptr<Runner> PipelineD::prepareCursorSource( + Collection* collection, const intrusive_ptr<Pipeline>& pPipeline, const intrusive_ptr<ExpressionContext>& pExpCtx) { // get the full "namespace" name @@ -162,7 +163,7 @@ namespace { projectionForQuery, &cq); Runner* rawRunner; - if (status.isOK() && getRunner(cq, &rawRunner, runnerOptions).isOK()) { + if (status.isOK() && getRunner(collection, cq, &rawRunner, runnerOptions).isOK()) { // success: The Runner will handle sorting for us using an index. runner.reset(rawRunner); sortInRunner = true; @@ -186,7 +187,7 @@ namespace { &cq)); Runner* rawRunner; - uassertStatusOK(getRunner(cq, &rawRunner, runnerOptions)); + uassertStatusOK(getRunner(collection, cq, &rawRunner, runnerOptions)); runner.reset(rawRunner); } diff --git a/src/mongo/db/pipeline/pipeline_d.h b/src/mongo/db/pipeline/pipeline_d.h index 98ea7537be3..b6b34e6f378 100644 --- a/src/mongo/db/pipeline/pipeline_d.h +++ b/src/mongo/db/pipeline/pipeline_d.h @@ -71,6 +71,7 @@ namespace mongo { * @param pExpCtx the expression context for this pipeline */ static boost::shared_ptr<Runner> prepareCursorSource( + Collection* collection, const intrusive_ptr<Pipeline> &pPipeline, const intrusive_ptr<ExpressionContext> &pExpCtx); diff --git a/src/mongo/db/query/cached_plan_runner.cpp b/src/mongo/db/query/cached_plan_runner.cpp index 18cc3d3af71..08c944b9b8d 100644 --- a/src/mongo/db/query/cached_plan_runner.cpp +++ b/src/mongo/db/query/cached_plan_runner.cpp @@ -181,14 +181,15 @@ namespace mongo { return; } - Database* db = cc().database(); - // We need to check db and collection for NULL because updateCache() is called upon destruction of // the CachedPlanRunner. In some cases, the db or collection could be dropped without kill() // being called on the runner (for example, timeout of a ClientCursor holding the runner). + // XXX - this whole thing is odd + Database* db = cc().database(); if (NULL == db) { return; } Collection* collection = db->getCollection(_canonicalQuery->ns()); if (NULL == collection) { return; } + invariant( collection == _collection ); PlanCache* cache = collection->infoCache()->getPlanCache(); std::auto_ptr<PlanCacheEntryFeedback> feedback(new PlanCacheEntryFeedback()); diff --git a/src/mongo/db/query/get_runner.cpp b/src/mongo/db/query/get_runner.cpp index f062fbe578e..d817b218259 100644 --- a/src/mongo/db/query/get_runner.cpp +++ b/src/mongo/db/query/get_runner.cpp @@ -85,21 +85,6 @@ namespace mongo { temp.swap(*indexEntries); } - /** - * For a given query, get a runner. The runner could be a SingleSolutionRunner, a - * CachedQueryRunner, or a MultiPlanRunner, depending on the cache/query solver/etc. - */ - Status getRunner(CanonicalQuery* rawCanonicalQuery, - Runner** out, size_t plannerOptions) { - verify(rawCanonicalQuery); - Database* db = cc().database(); - verify(db); - return getRunner(db->getCollection(rawCanonicalQuery->ns()), - rawCanonicalQuery, - out, - plannerOptions); - } - Status getRunner(Collection* collection, const std::string& ns, const BSONObj& unparsedQuery, @@ -240,7 +225,7 @@ namespace mongo { WorkingSet* ws; PlanStage* root; - verify(StageBuilder::build(*qs, &root, &ws)); + verify(StageBuilder::build(collection, *qs, &root, &ws)); *out = new SingleSolutionRunner(collection, canonicalQuery, qs, root, ws); if (NULL != backupQs) { @@ -256,7 +241,7 @@ namespace mongo { WorkingSet* ws; PlanStage* root; - verify(StageBuilder::build(*qs, &root, &ws)); + verify(StageBuilder::build(collection, *qs, &root, &ws)); CachedPlanRunner* cpr = new CachedPlanRunner(collection, canonicalQuery, qs, @@ -267,7 +252,7 @@ namespace mongo { if (NULL != backupQs) { WorkingSet* backupWs; PlanStage* backupRoot; - verify(StageBuilder::build(*backupQs, &backupRoot, &backupWs)); + verify(StageBuilder::build(collection, *backupQs, &backupRoot, &backupWs)); cpr->setBackupPlan(backupQs, backupRoot, backupWs); } @@ -397,7 +382,7 @@ namespace mongo { // We're not going to cache anything that's fast count. WorkingSet* ws; PlanStage* root; - verify(StageBuilder::build(*solutions[i], &root, &ws)); + verify(StageBuilder::build(collection, *solutions[i], &root, &ws)); *out = new SingleSolutionRunner(collection, canonicalQuery.release(), solutions[i], @@ -416,7 +401,7 @@ namespace mongo { // Only one possible plan. Run it. Build the stages from the solution. WorkingSet* ws; PlanStage* root; - verify(StageBuilder::build(*solutions[0], &root, &ws)); + verify(StageBuilder::build(collection, *solutions[0], &root, &ws)); // And, run the plan. *out = new SingleSolutionRunner(collection, @@ -436,7 +421,7 @@ namespace mongo { if (solutions[i]->cacheData.get()) { solutions[i]->cacheData->indexFilterApplied = plannerParams.indexFiltersApplied; } - verify(StageBuilder::build(*solutions[i], &root, &ws)); + verify(StageBuilder::build(collection, *solutions[i], &root, &ws)); // Takes ownership of all arguments. mpr->addPlan(solutions[i], root, ws); } @@ -750,7 +735,7 @@ namespace mongo { } // Takes ownership of cq. - return getRunner(cq, out); + return getRunner(collection, cq, out); } // @@ -796,7 +781,7 @@ namespace mongo { WorkingSet* ws; PlanStage* root; - verify(StageBuilder::build(*soln, &root, &ws)); + verify(StageBuilder::build(collection, *soln, &root, &ws)); *out = new SingleSolutionRunner(collection, cq, soln, root, ws); return Status::OK(); } @@ -805,7 +790,7 @@ namespace mongo { vector<QuerySolution*> solutions; status = QueryPlanner::plan(*cq, plannerParams, &solutions); if (!status.isOK()) { - return getRunner(cq, out); + return getRunner(collection, cq, out); } // We look for a solution that has an ixscan we can turn into a distinctixscan @@ -824,7 +809,7 @@ namespace mongo { // Build and return the SSR over solutions[i]. WorkingSet* ws; PlanStage* root; - verify(StageBuilder::build(*solutions[i], &root, &ws)); + verify(StageBuilder::build(collection, *solutions[i], &root, &ws)); *out = new SingleSolutionRunner(collection, cq, solutions[i], root, ws); return Status::OK(); } @@ -849,7 +834,7 @@ namespace mongo { } // Takes ownership of cq. - return getRunner(cq, out); + return getRunner(collection, cq, out); } ScopedRunnerRegistration::ScopedRunnerRegistration(Runner* runner) diff --git a/src/mongo/db/query/get_runner.h b/src/mongo/db/query/get_runner.h index 18f7c7235f1..9360478e278 100644 --- a/src/mongo/db/query/get_runner.h +++ b/src/mongo/db/query/get_runner.h @@ -61,17 +61,6 @@ namespace mongo { * If the query cannot be executed, returns a Status indicating why. Deletes * rawCanonicalQuery. */ - Status getRunner(CanonicalQuery* rawCanonicalQuery, - Runner** out, - size_t plannerOptions = 0); - - /** - * Get a runner for a query. Takes ownership of rawCanonicalQuery. - * - * As 'getRunner' above, but takes a Collection* as the first argument, for cases where the - * work to obtain the Collection has already been done by the caller. The 'collection' - * argument may be NULL. - */ Status getRunner(Collection* collection, CanonicalQuery* rawCanonicalQuery, Runner** out, diff --git a/src/mongo/db/query/internal_plans.h b/src/mongo/db/query/internal_plans.h index fa5597dfbc1..a36b7478714 100644 --- a/src/mongo/db/query/internal_plans.h +++ b/src/mongo/db/query/internal_plans.h @@ -62,14 +62,18 @@ namespace mongo { /** * Return a collection scan. Caller owns pointer. */ - static Runner* collectionScan(const StringData& ns, // TODO: make this a Collection* + static Runner* collectionScan(const StringData& ns, + Collection* collection, const Direction direction = FORWARD, const DiskLoc startLoc = DiskLoc()) { - Collection* collection = cc().database()->getCollection(ns); - if (NULL == collection) { return new EOFRunner(NULL, ns.toString()); } + if (NULL == collection) { + return new EOFRunner(NULL, ns.toString()); + } + + dassert( ns == collection->ns().ns() ); CollectionScanParams params; - params.ns = ns.toString(); + params.collection = collection; params.start = startLoc; if (FORWARD == direction) { diff --git a/src/mongo/db/query/new_find.cpp b/src/mongo/db/query/new_find.cpp index 3205eb3f45c..25ffb9b042d 100644 --- a/src/mongo/db/query/new_find.cpp +++ b/src/mongo/db/query/new_find.cpp @@ -363,7 +363,7 @@ namespace mongo { // Make an oplog start finding stage. WorkingSet* oplogws = new WorkingSet(); - OplogStart* stage = new OplogStart(cq->ns(), tsExpr, oplogws); + OplogStart* stage = new OplogStart(collection, tsExpr, oplogws); // Takes ownership of ws and stage. auto_ptr<InternalRunner> runner(new InternalRunner(collection, stage, oplogws)); @@ -374,7 +374,7 @@ namespace mongo { Runner::RunnerState state = runner->getNext(NULL, &startLoc); // This is normal. The start of the oplog is the beginning of the collection. - if (Runner::RUNNER_EOF == state) { return getRunner(cq, runnerOut); } + if (Runner::RUNNER_EOF == state) { return getRunner(collection, cq, runnerOut); } // This is not normal. An error was encountered. if (Runner::RUNNER_ADVANCED != state) { @@ -386,7 +386,7 @@ namespace mongo { // Build our collection scan... CollectionScanParams params; - params.ns = cq->ns(); + params.collection = collection; params.start = startLoc; params.direction = CollectionScanParams::FORWARD; params.tailable = cq->getParsed().hasOption(QueryOption_CursorTailable); @@ -495,7 +495,7 @@ namespace mongo { if (shardingState.needCollectionMetadata(pq.ns())) { options |= QueryPlannerParams::INCLUDE_SHARD_FILTER; } - status = getRunner(cq, &rawRunner, options); + status = getRunner(collection, cq, &rawRunner, options); } if (!status.isOK()) { diff --git a/src/mongo/db/query/planner_analysis.cpp b/src/mongo/db/query/planner_analysis.cpp index 24441a7a811..a6339e4121e 100644 --- a/src/mongo/db/query/planner_analysis.cpp +++ b/src/mongo/db/query/planner_analysis.cpp @@ -465,12 +465,11 @@ namespace mongo { // static QuerySolution* QueryPlannerAnalysis::analyzeDataAccess(const CanonicalQuery& query, - const QueryPlannerParams& params, - QuerySolutionNode* solnRoot) { + const QueryPlannerParams& params, + QuerySolutionNode* solnRoot) { auto_ptr<QuerySolution> soln(new QuerySolution()); soln->filterData = query.getQueryObj(); verify(soln->filterData.isOwned()); - soln->ns = query.ns(); soln->indexFilterApplied = params.indexFiltersApplied; solnRoot->computeProperties(); diff --git a/src/mongo/db/query/planner_analysis.h b/src/mongo/db/query/planner_analysis.h index 22237c1afcc..4dcf9dd2aea 100644 --- a/src/mongo/db/query/planner_analysis.h +++ b/src/mongo/db/query/planner_analysis.h @@ -34,6 +34,8 @@ namespace mongo { + class Collection; + class QueryPlannerAnalysis { public: diff --git a/src/mongo/db/query/query_planner.cpp b/src/mongo/db/query/query_planner.cpp index 92d8a04674e..94bb3eece90 100644 --- a/src/mongo/db/query/query_planner.cpp +++ b/src/mongo/db/query/query_planner.cpp @@ -271,7 +271,9 @@ namespace mongo { if (SolutionCacheData::WHOLE_IXSCAN_SOLN == cacheData.solnType) { // The solution can be constructed by a scan over the entire index. QuerySolution* soln = buildWholeIXSoln(*cacheData.tree->entry, - query, params, cacheData.wholeIXSolnDir); + query, + params, + cacheData.wholeIXSolnDir); if (soln == NULL) { return Status(ErrorCodes::BadValue, "plan cache error: soln that uses index to provide sort"); @@ -331,7 +333,9 @@ namespace mongo { if (NULL != solnRoot) { // Takes ownership of 'solnRoot'. - QuerySolution* soln = QueryPlannerAnalysis::analyzeDataAccess(query, params, solnRoot); + QuerySolution* soln = QueryPlannerAnalysis::analyzeDataAccess(query, + params, + solnRoot); if (NULL != soln) { QLOG() << "Planner: solution constructed from the cache:\n" << soln->toString() << endl; *out = soln; @@ -369,7 +373,8 @@ namespace mongo { if (cachedSoln.backupSoln) { SolutionCacheData* backupCacheData = cachedSoln.plannerData[*cachedSoln.backupSoln]; - Status backupStatus = planFromCache(query, params, *backupCacheData, backupOut); + Status backupStatus = planFromCache(query, params, + *backupCacheData, backupOut); if (!backupStatus.isOK()) { return backupStatus; } @@ -653,7 +658,9 @@ namespace mongo { // only be first for gnNode. tag->first.erase(tag->first.begin() + i); - QuerySolution* soln = QueryPlannerAnalysis::analyzeDataAccess(query, params, solnRoot); + QuerySolution* soln = QueryPlannerAnalysis::analyzeDataAccess(query, + params, + solnRoot); if (NULL != soln) { out->push_back(soln); @@ -743,7 +750,9 @@ namespace mongo { if (NULL == solnRoot) { continue; } - QuerySolution* soln = QueryPlannerAnalysis::analyzeDataAccess(query, params, solnRoot); + QuerySolution* soln = QueryPlannerAnalysis::analyzeDataAccess(query, + params, + solnRoot); if (NULL != soln) { QLOG() << "Planner: adding solution:" << endl << soln->toString(); if (indexTreeStatus.isOK()) { @@ -780,7 +789,8 @@ namespace mongo { // desired behavior when an index is hinted that is not relevant to the query. if (!hintIndex.isEmpty()) { if (0 == out->size()) { - QuerySolution* soln = buildWholeIXSoln(params.indices[hintIndexNumber], query, params); + QuerySolution* soln = buildWholeIXSoln(params.indices[hintIndexNumber], + query, params); verify(NULL != soln); QLOG() << "Planner: outputting soln that uses hinted index as scan." << endl; out->push_back(soln); @@ -816,7 +826,8 @@ namespace mongo { if (providesSort(query, kp)) { QLOG() << "Planner: outputting soln that uses index to provide sort." << endl; - QuerySolution* soln = buildWholeIXSoln(params.indices[i], query, params); + QuerySolution* soln = buildWholeIXSoln(params.indices[i], + query, params); if (NULL != soln) { PlanCacheIndexTree* indexTree = new PlanCacheIndexTree(); indexTree->setIndexEntry(params.indices[i]); @@ -833,7 +844,8 @@ namespace mongo { if (providesSort(query, QueryPlannerCommon::reverseSortObj(kp))) { QLOG() << "Planner: outputting soln that uses (reverse) index " << "to provide sort." << endl; - QuerySolution* soln = buildWholeIXSoln(params.indices[i], query, params, -1); + QuerySolution* soln = buildWholeIXSoln(params.indices[i], query, + params, -1); if (NULL != soln) { PlanCacheIndexTree* indexTree = new PlanCacheIndexTree(); indexTree->setIndexEntry(params.indices[i]); diff --git a/src/mongo/db/query/query_planner.h b/src/mongo/db/query/query_planner.h index a8534c69f62..e314e1f132c 100644 --- a/src/mongo/db/query/query_planner.h +++ b/src/mongo/db/query/query_planner.h @@ -35,6 +35,7 @@ namespace mongo { class CachedSolution; + class Collection; /** * QueryPlanner's job is to provide an entry point to the query planning and optimization diff --git a/src/mongo/db/query/query_solution.h b/src/mongo/db/query/query_solution.h index 7721e718f83..45908539398 100644 --- a/src/mongo/db/query/query_solution.h +++ b/src/mongo/db/query/query_solution.h @@ -180,8 +180,6 @@ namespace mongo { // Any filters in root or below point into this object. Must be owned. BSONObj filterData; - string ns; - // There are two known scenarios in which a query solution might potentially block: // // Sort stage: diff --git a/src/mongo/db/query/stage_builder.cpp b/src/mongo/db/query/stage_builder.cpp index 6e71b1db934..da4005cd4d1 100644 --- a/src/mongo/db/query/stage_builder.cpp +++ b/src/mongo/db/query/stage_builder.cpp @@ -55,11 +55,14 @@ namespace mongo { - PlanStage* buildStages(const QuerySolution& qsol, const QuerySolutionNode* root, WorkingSet* ws) { + PlanStage* buildStages(Collection* collection, + const QuerySolution& qsol, + const QuerySolutionNode* root, + WorkingSet* ws) { if (STAGE_COLLSCAN == root->getType()) { const CollectionScanNode* csn = static_cast<const CollectionScanNode*>(root); CollectionScanParams params; - params.ns = csn->name; + params.collection = collection; params.tailable = csn->tailable; params.direction = (csn->direction == 1) ? CollectionScanParams::FORWARD : CollectionScanParams::BACKWARD; @@ -69,19 +72,18 @@ namespace mongo { else if (STAGE_IXSCAN == root->getType()) { const IndexScanNode* ixn = static_cast<const IndexScanNode*>(root); - Database* db = cc().database(); - Collection* collection = db ? db->getCollection(qsol.ns) : NULL; if (NULL == collection) { - warning() << "Can't ixscan null namespace " << qsol.ns << endl; + warning() << "Can't ixscan null namespace"; return NULL; } IndexScanParams params; - params.descriptor = collection->getIndexCatalog()->findIndexByKeyPattern( ixn->indexKeyPattern ); + params.descriptor = + collection->getIndexCatalog()->findIndexByKeyPattern( ixn->indexKeyPattern ); if ( params.descriptor == NULL ) { warning() << "Can't find index " << ixn->indexKeyPattern.toString() - << "in namespace " << qsol.ns << endl; + << "in namespace " << collection->ns() << endl; return NULL; } @@ -93,13 +95,13 @@ namespace mongo { } else if (STAGE_FETCH == root->getType()) { const FetchNode* fn = static_cast<const FetchNode*>(root); - PlanStage* childStage = buildStages(qsol, fn->children[0], ws); + PlanStage* childStage = buildStages(collection, qsol, fn->children[0], ws); if (NULL == childStage) { return NULL; } return new FetchStage(ws, childStage, fn->filter.get()); } else if (STAGE_SORT == root->getType()) { const SortNode* sn = static_cast<const SortNode*>(root); - PlanStage* childStage = buildStages(qsol, sn->children[0], ws); + PlanStage* childStage = buildStages(collection, qsol, sn->children[0], ws); if (NULL == childStage) { return NULL; } SortStageParams params; params.pattern = sn->pattern; @@ -109,7 +111,7 @@ namespace mongo { } else if (STAGE_PROJECTION == root->getType()) { const ProjectionNode* pn = static_cast<const ProjectionNode*>(root); - PlanStage* childStage = buildStages(qsol, pn->children[0], ws); + PlanStage* childStage = buildStages(collection, qsol, pn->children[0], ws); if (NULL == childStage) { return NULL; } ProjectionStageParams params; params.projObj = pn->projection; @@ -133,13 +135,13 @@ namespace mongo { } else if (STAGE_LIMIT == root->getType()) { const LimitNode* ln = static_cast<const LimitNode*>(root); - PlanStage* childStage = buildStages(qsol, ln->children[0], ws); + PlanStage* childStage = buildStages(collection, qsol, ln->children[0], ws); if (NULL == childStage) { return NULL; } return new LimitStage(ln->limit, ws, childStage); } else if (STAGE_SKIP == root->getType()) { const SkipNode* sn = static_cast<const SkipNode*>(root); - PlanStage* childStage = buildStages(qsol, sn->children[0], ws); + PlanStage* childStage = buildStages(collection, qsol, sn->children[0], ws); if (NULL == childStage) { return NULL; } return new SkipStage(sn->skip, ws, childStage); } @@ -147,7 +149,7 @@ namespace mongo { const AndHashNode* ahn = static_cast<const AndHashNode*>(root); auto_ptr<AndHashStage> ret(new AndHashStage(ws, ahn->filter.get())); for (size_t i = 0; i < ahn->children.size(); ++i) { - PlanStage* childStage = buildStages(qsol, ahn->children[i], ws); + PlanStage* childStage = buildStages(collection, qsol, ahn->children[i], ws); if (NULL == childStage) { return NULL; } ret->addChild(childStage); } @@ -157,7 +159,7 @@ namespace mongo { const OrNode * orn = static_cast<const OrNode*>(root); auto_ptr<OrStage> ret(new OrStage(ws, orn->dedup, orn->filter.get())); for (size_t i = 0; i < orn->children.size(); ++i) { - PlanStage* childStage = buildStages(qsol, orn->children[i], ws); + PlanStage* childStage = buildStages(collection, qsol, orn->children[i], ws); if (NULL == childStage) { return NULL; } ret->addChild(childStage); } @@ -167,7 +169,7 @@ namespace mongo { const AndSortedNode* asn = static_cast<const AndSortedNode*>(root); auto_ptr<AndSortedStage> ret(new AndSortedStage(ws, asn->filter.get())); for (size_t i = 0; i < asn->children.size(); ++i) { - PlanStage* childStage = buildStages(qsol, asn->children[i], ws); + PlanStage* childStage = buildStages(collection, qsol, asn->children[i], ws); if (NULL == childStage) { return NULL; } ret->addChild(childStage); } @@ -180,7 +182,7 @@ namespace mongo { params.pattern = msn->sort; auto_ptr<MergeSortStage> ret(new MergeSortStage(params, ws)); for (size_t i = 0; i < msn->children.size(); ++i) { - PlanStage* childStage = buildStages(qsol, msn->children[i], ws); + PlanStage* childStage = buildStages(collection, qsol, msn->children[i], ws); if (NULL == childStage) { return NULL; } ret->addChild(childStage); } @@ -192,14 +194,14 @@ namespace mongo { params.gq = node->gq; params.filter = node->filter.get(); params.indexKeyPattern = node->indexKeyPattern; - params.ns = qsol.ns; + params.collection = collection; return new TwoD(params, ws); } else if (STAGE_GEO_NEAR_2D == root->getType()) { const GeoNear2DNode* node = static_cast<const GeoNear2DNode*>(root); TwoDNearParams params; params.nearQuery = node->nq; - params.ns = qsol.ns; + params.collection = collection; params.indexKeyPattern = node->indexKeyPattern; params.filter = node->filter.get(); params.numWanted = node->numWanted; @@ -210,7 +212,7 @@ namespace mongo { else if (STAGE_GEO_NEAR_2DSPHERE == root->getType()) { const GeoNear2DSphereNode* node = static_cast<const GeoNear2DSphereNode*>(root); S2NearParams params; - params.ns = qsol.ns; + params.collection = collection; params.indexKeyPattern = node->indexKeyPattern; params.nearQuery = node->nq; params.baseBounds = node->baseBounds; @@ -222,8 +224,6 @@ namespace mongo { else if (STAGE_TEXT == root->getType()) { const TextNode* node = static_cast<const TextNode*>(root); - Database* db = cc().database(); - Collection* collection = db ? db->getCollection(qsol.ns) : NULL; if (NULL == collection) { warning() << "Null collection for text"; return NULL; @@ -239,7 +239,7 @@ namespace mongo { static_cast<FTSAccessMethod*>( collection->getIndexCatalog()->getIndex( index ) ); TextStageParams params(fam->getSpec()); - params.ns = qsol.ns; + //params.collection = collection; params.index = index; params.spec = fam->getSpec(); params.indexPrefix = node->indexPrefix; @@ -258,23 +258,22 @@ namespace mongo { } else if (STAGE_SHARDING_FILTER == root->getType()) { const ShardingFilterNode* fn = static_cast<const ShardingFilterNode*>(root); - PlanStage* childStage = buildStages(qsol, fn->children[0], ws); + PlanStage* childStage = buildStages(collection, qsol, fn->children[0], ws); if (NULL == childStage) { return NULL; } - return new ShardFilterStage(shardingState.getCollectionMetadata(qsol.ns), ws, childStage); + return new ShardFilterStage(shardingState.getCollectionMetadata(collection->ns()), + ws, childStage); } else if (STAGE_KEEP_MUTATIONS == root->getType()) { const KeepMutationsNode* km = static_cast<const KeepMutationsNode*>(root); - PlanStage* childStage = buildStages(qsol, km->children[0], ws); + PlanStage* childStage = buildStages(collection, qsol, km->children[0], ws); if (NULL == childStage) { return NULL; } return new KeepMutationsStage(km->filter.get(), ws, childStage); } else if (STAGE_DISTINCT == root->getType()) { const DistinctNode* dn = static_cast<const DistinctNode*>(root); - Database* db = cc().database(); - Collection* collection = db ? db->getCollection(qsol.ns) : NULL; if (NULL == collection) { - warning() << "Can't distinct-scan null namespace " << qsol.ns << endl; + warning() << "Can't distinct-scan null namespace"; return NULL; } @@ -290,15 +289,8 @@ namespace mongo { else if (STAGE_COUNT == root->getType()) { const CountNode* cn = static_cast<const CountNode*>(root); - Database* db = cc().database(); - if (NULL == db) { - warning() << "Can't fast-count null namespace (database null)" << qsol.ns << endl; - return NULL; - } - - Collection* collection = db ? db->getCollection(qsol.ns) : NULL; if (NULL == collection) { - warning() << "Can't fast-count null namespace (collection null)" << qsol.ns << endl; + warning() << "Can't fast-count null namespace (collection null)"; return NULL; } @@ -323,13 +315,15 @@ namespace mongo { } // static - bool StageBuilder::build(const QuerySolution& solution, PlanStage** rootOut, + bool StageBuilder::build(Collection* collection, + const QuerySolution& solution, + PlanStage** rootOut, WorkingSet** wsOut) { QuerySolutionNode* root = solution.root.get(); if (NULL == root) { return false; } auto_ptr<WorkingSet> ws(new WorkingSet()); - PlanStage* stageRoot = buildStages(solution, root, ws.get()); + PlanStage* stageRoot = buildStages(collection, solution, root, ws.get()); if (NULL != stageRoot) { *rootOut = stageRoot; diff --git a/src/mongo/db/query/stage_builder.h b/src/mongo/db/query/stage_builder.h index c352fd1b9b6..4f3c5be8831 100644 --- a/src/mongo/db/query/stage_builder.h +++ b/src/mongo/db/query/stage_builder.h @@ -48,7 +48,10 @@ namespace mongo { * * Returns false otherwise. *rootOut and *wsOut are invalid. */ - static bool build(const QuerySolution& solution, PlanStage** rootOut, WorkingSet** wsOut); + static bool build(Collection* collection, + const QuerySolution& solution, + PlanStage** rootOut, + WorkingSet** wsOut); }; } // namespace mongo diff --git a/src/mongo/db/query/subplan_runner.cpp b/src/mongo/db/query/subplan_runner.cpp index 8c9566b7f15..82d100bc0d1 100644 --- a/src/mongo/db/query/subplan_runner.cpp +++ b/src/mongo/db/query/subplan_runner.cpp @@ -249,7 +249,7 @@ namespace mongo { for (size_t i = 0; i < solutions.size(); ++i) { WorkingSet* ws; PlanStage* root; - verify(StageBuilder::build(*solutions[i], &root, &ws)); + verify(StageBuilder::build(_collection, *solutions[i], &root, &ws)); // Takes ownership of all arguments. mpr->addPlan(solutions[i], root, ws); } @@ -336,7 +336,7 @@ namespace mongo { MultiPlanRunner* mpr = new MultiPlanRunner(_collection, _query.release()); WorkingSet* ws; PlanStage* root; - verify(StageBuilder::build(*soln, &root, &ws)); + verify(StageBuilder::build(_collection, *soln, &root, &ws)); // Takes ownership of all arguments. mpr->addPlan(soln, root, ws); diff --git a/src/mongo/db/repl/master_slave.cpp b/src/mongo/db/repl/master_slave.cpp index 78b5cc8195c..83e1527ebcc 100644 --- a/src/mongo/db/repl/master_slave.cpp +++ b/src/mongo/db/repl/master_slave.cpp @@ -227,7 +227,8 @@ namespace mongo { and cursor in effect. */ void ReplSource::loadAll(SourceVector &v) { - Client::Context ctx("local.sources"); + const char* localSources = "local.sources"; + Client::Context ctx(localSources); SourceVector old = v; v.clear(); @@ -236,7 +237,8 @@ namespace mongo { // check that no items are in sources other than that // add if missing int n = 0; - auto_ptr<Runner> runner(InternalPlanner::collectionScan("local.sources")); + auto_ptr<Runner> runner(InternalPlanner::collectionScan(localSources, + ctx.db()->getCollection(localSources))); BSONObj obj; Runner::RunnerState state; while (Runner::RUNNER_ADVANCED == (state = runner->getNext(&obj, NULL))) { @@ -278,7 +280,8 @@ namespace mongo { } } - auto_ptr<Runner> runner(InternalPlanner::collectionScan("local.sources")); + auto_ptr<Runner> runner(InternalPlanner::collectionScan(localSources, + ctx.db()->getCollection(localSources))); BSONObj obj; Runner::RunnerState state; while (Runner::RUNNER_ADVANCED == (state = runner->getNext(&obj, NULL))) { diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp index 716bd8c7c83..c1308a85e43 100644 --- a/src/mongo/db/repl/oplog.cpp +++ b/src/mongo/db/repl/oplog.cpp @@ -625,7 +625,7 @@ namespace mongo { if (collection == NULL || (indexCatalog->haveIdIndex() && Helpers::findById(collection, updateCriteria).isNull()) || // capped collections won't have an _id index - (!indexCatalog->haveIdIndex() && Helpers::findOne(ns, updateCriteria, false).isNull())) { + (!indexCatalog->haveIdIndex() && Helpers::findOne(collection, updateCriteria, false).isNull())) { failedUpdate = true; log() << "replication couldn't find doc: " << op.toString() << endl; } diff --git a/src/mongo/db/repl/replication_server_status.cpp b/src/mongo/db/repl/replication_server_status.cpp index ff220122500..14164a2a63b 100644 --- a/src/mongo/db/repl/replication_server_status.cpp +++ b/src/mongo/db/repl/replication_server_status.cpp @@ -86,8 +86,10 @@ namespace mongo { int n = 0; list<BSONObj> src; { - Client::ReadContext ctx("local.sources", storageGlobalParams.dbpath); - auto_ptr<Runner> runner(InternalPlanner::collectionScan("local.sources")); + const char* localSources = "local.sources"; + Client::ReadContext ctx(localSources, storageGlobalParams.dbpath); + auto_ptr<Runner> runner(InternalPlanner::collectionScan(localSources, + ctx.ctx().db()->getCollection(localSources))); BSONObj obj; Runner::RunnerState state; while (Runner::RUNNER_ADVANCED == (state = runner->getNext(&obj, NULL))) { diff --git a/src/mongo/db/repl/rs_rollback.cpp b/src/mongo/db/repl/rs_rollback.cpp index 4c3c69e912c..250c55b0a71 100644 --- a/src/mongo/db/repl/rs_rollback.cpp +++ b/src/mongo/db/repl/rs_rollback.cpp @@ -229,8 +229,9 @@ namespace mongo { verify( Lock::isLocked() ); Client::Context c(rsoplog); - boost::scoped_ptr<Runner> runner( - InternalPlanner::collectionScan(rsoplog, InternalPlanner::BACKWARD)); + boost::scoped_ptr<Runner> runner(InternalPlanner::collectionScan(rsoplog, + c.db()->getCollection(rsoplog), + InternalPlanner::BACKWARD)); BSONObj ourObj; DiskLoc ourLoc; @@ -496,7 +497,7 @@ namespace mongo { // Add the doc to our rollback file BSONObj obj; - bool found = Helpers::findOne(d.ns, pattern, obj, false); + bool found = Helpers::findOne(c.db()->getCollection(d.ns), pattern, obj, false); if ( found ) { rs->goingToDelete( obj ); } else { @@ -517,7 +518,7 @@ namespace mongo { /** todo: IIRC cappedTruncateAfter does not handle completely empty. todo. */ // this will crazy slow if no _id index. long long start = Listener::getElapsedTimeMillis(); - DiskLoc loc = Helpers::findOne(d.ns, pattern, false); + DiskLoc loc = Helpers::findOne(collection, pattern, false); if( Listener::getElapsedTimeMillis() - start > 200 ) log() << "replSet warning roll back slow no _id index for " << d.ns << " perhaps?" << rsLog; //would be faster but requires index: DiskLoc loc = Helpers::findById(nsd, pattern); diff --git a/src/mongo/db/structure/catalog/namespace_details.cpp b/src/mongo/db/structure/catalog/namespace_details.cpp index e369a477405..5acd5d98585 100644 --- a/src/mongo/db/structure/catalog/namespace_details.cpp +++ b/src/mongo/db/structure/catalog/namespace_details.cpp @@ -413,11 +413,11 @@ namespace mongo { Lock::assertWriteLocked( ns ); string system_namespaces = nsToDatabaseSubstring(ns).toString() + ".system.namespaces"; + Collection* coll = cc().database()->getCollection( system_namespaces ); - DiskLoc oldLocation = Helpers::findOne( system_namespaces, BSON( "name" << ns ), false ); + DiskLoc oldLocation = Helpers::findOne( coll, BSON( "name" << ns ), false ); fassert( 17247, !oldLocation.isNull() ); - Collection* coll = cc().database()->getCollection( system_namespaces ); BSONObj oldEntry = coll->docFor( oldLocation ); BSONObj newEntry = applyUpdateOperators( oldEntry , BSON( "$set" << BSON( "options.flags" << userFlags() ) ) ); diff --git a/src/mongo/dbtests/documentsourcetests.cpp b/src/mongo/dbtests/documentsourcetests.cpp index 06ce6475e34..607ee1001c0 100644 --- a/src/mongo/dbtests/documentsourcetests.cpp +++ b/src/mongo/dbtests/documentsourcetests.cpp @@ -169,7 +169,7 @@ namespace DocumentSourceTests { CanonicalQuery* cq; uassertStatusOK(CanonicalQuery::canonicalize(ns, /*query=*/BSONObj(), &cq)); Runner* runnerBare; - uassertStatusOK(getRunner(cq, &runnerBare)); + uassertStatusOK(getRunner(ctx.ctx().db()->getCollection(ns), cq, &runnerBare)); _runner.reset(runnerBare); _runner->setYieldPolicy(Runner::YIELD_AUTO); diff --git a/src/mongo/dbtests/namespacetests.cpp b/src/mongo/dbtests/namespacetests.cpp index 2b2f69e3f4f..687d26776b6 100644 --- a/src/mongo/dbtests/namespacetests.cpp +++ b/src/mongo/dbtests/namespacetests.cpp @@ -1658,14 +1658,16 @@ namespace NamespaceTests { DiskLoc last, first; { - auto_ptr<Runner> runner( - InternalPlanner::collectionScan(ns(), InternalPlanner::BACKWARD)); + auto_ptr<Runner> runner(InternalPlanner::collectionScan(ns(), + collection(), + InternalPlanner::BACKWARD)); runner->getNext(NULL, &last); ASSERT( !last.isNull() ); } { - auto_ptr<Runner> runner( - InternalPlanner::collectionScan(ns(), InternalPlanner::FORWARD)); + auto_ptr<Runner> runner(InternalPlanner::collectionScan(ns(), + collection(), + InternalPlanner::FORWARD)); runner->getNext(NULL, &first); ASSERT( !first.isNull() ); ASSERT( first != last ) ; @@ -1676,14 +1678,16 @@ namespace NamespaceTests { { DiskLoc loc; - auto_ptr<Runner> runner( - InternalPlanner::collectionScan(ns(), InternalPlanner::FORWARD)); + auto_ptr<Runner> runner(InternalPlanner::collectionScan(ns(), + collection(), + InternalPlanner::FORWARD)); runner->getNext(NULL, &loc); ASSERT( first == loc); } { - auto_ptr<Runner> runner( - InternalPlanner::collectionScan(ns(), InternalPlanner::BACKWARD)); + auto_ptr<Runner> runner(InternalPlanner::collectionScan(ns(), + collection(), + InternalPlanner::BACKWARD)); DiskLoc loc; runner->getNext(NULL, &loc); ASSERT( last != loc ); diff --git a/src/mongo/dbtests/oplogstarttests.cpp b/src/mongo/dbtests/oplogstarttests.cpp index 3f4c725521d..0b8a168ae36 100644 --- a/src/mongo/dbtests/oplogstarttests.cpp +++ b/src/mongo/dbtests/oplogstarttests.cpp @@ -73,6 +73,10 @@ namespace OplogStartTests { return "oplogstarttests"; } + Collection* collection() { + return _context.db()->getCollection( ns() ); + } + DBDirectClient *client() const { return &_client; } void setupFromQuery(const BSONObj& query) { @@ -81,7 +85,7 @@ namespace OplogStartTests { ASSERT(s.isOK()); _cq.reset(cq); _oplogws.reset(new WorkingSet()); - _stage.reset(new OplogStart(_cq->ns(), _cq->root(), _oplogws.get())); + _stage.reset(new OplogStart(collection(), _cq->root(), _oplogws.get())); } void assertWorkingSetMemberHasId(WorkingSetID id, int expectedId) { diff --git a/src/mongo/dbtests/plan_ranking.cpp b/src/mongo/dbtests/plan_ranking.cpp index 991ffc6d316..df47ba579f1 100644 --- a/src/mongo/dbtests/plan_ranking.cpp +++ b/src/mongo/dbtests/plan_ranking.cpp @@ -111,7 +111,7 @@ namespace PlanRankingTests { for (size_t i = 0; i < solutions.size(); ++i) { WorkingSet* ws; PlanStage* root; - ASSERT(StageBuilder::build(*solutions[i], &root, &ws)); + ASSERT(StageBuilder::build(collection, *solutions[i], &root, &ws)); // Takes ownership of all arguments. _mpr->addPlan(solutions[i], root, ws); } diff --git a/src/mongo/dbtests/query_multi_plan_runner.cpp b/src/mongo/dbtests/query_multi_plan_runner.cpp index fadc0347a50..717035c5ce1 100644 --- a/src/mongo/dbtests/query_multi_plan_runner.cpp +++ b/src/mongo/dbtests/query_multi_plan_runner.cpp @@ -114,7 +114,7 @@ namespace QueryMultiPlanRunner { // Plan 1: CollScan with matcher. CollectionScanParams csparams; - csparams.ns = ns(); + csparams.collection = ctx.ctx().db()->getCollection( ns() ); csparams.direction = CollectionScanParams::FORWARD; auto_ptr<WorkingSet> secondWs(new WorkingSet()); // Make the filter. diff --git a/src/mongo/dbtests/query_single_solution_runner.cpp b/src/mongo/dbtests/query_single_solution_runner.cpp index b11bc35aaed..2d6064b90d7 100644 --- a/src/mongo/dbtests/query_single_solution_runner.cpp +++ b/src/mongo/dbtests/query_single_solution_runner.cpp @@ -80,7 +80,7 @@ namespace QuerySingleSolutionRunner { SingleSolutionRunner* makeCollScanRunner(Client::Context& ctx, BSONObj& filterObj) { CollectionScanParams csparams; - csparams.ns = ns(); + csparams.collection = ctx.db()->getCollection( ns() ); csparams.direction = CollectionScanParams::FORWARD; auto_ptr<WorkingSet> ws(new WorkingSet()); // Parse the filter. diff --git a/src/mongo/dbtests/query_stage_collscan.cpp b/src/mongo/dbtests/query_stage_collscan.cpp index 04e5b64015c..47360cdf9a7 100644 --- a/src/mongo/dbtests/query_stage_collscan.cpp +++ b/src/mongo/dbtests/query_stage_collscan.cpp @@ -68,7 +68,7 @@ namespace QueryStageCollectionScan { insertTestData(); CollectionScanParams params; - params.ns = ns(); + params.collection = collection(); params.direction = CollectionScanParams::FORWARD; params.tailable = false; params.start = DiskLoc(); @@ -321,7 +321,7 @@ namespace QueryStageCollectionScan { // Configure the scan. CollectionScanParams params; - params.ns = ns(); + params.collection = ctx.ctx().db()->getCollection( ns() ); params.direction = direction; params.tailable = false; @@ -341,11 +341,13 @@ namespace QueryStageCollectionScan { return count; } - void getLocs(CollectionScanParams::Direction direction, vector<DiskLoc>* out) { + void getLocs(Collection* collection, + CollectionScanParams::Direction direction, + vector<DiskLoc>* out) { WorkingSet ws; CollectionScanParams params; - params.ns = ns(); + params.collection = collection; params.direction = direction; params.tailable = false; @@ -427,7 +429,7 @@ namespace QueryStageCollectionScan { // Configure the scan. CollectionScanParams params; - params.ns = ns(); + params.collection = ctx.ctx().db()->getCollection( ns() ); params.direction = CollectionScanParams::FORWARD; params.tailable = false; @@ -457,7 +459,7 @@ namespace QueryStageCollectionScan { Client::ReadContext ctx(ns()); CollectionScanParams params; - params.ns = ns(); + params.collection = ctx.ctx().db()->getCollection( ns() ); params.direction = CollectionScanParams::BACKWARD; params.tailable = false; @@ -485,13 +487,15 @@ namespace QueryStageCollectionScan { void run() { Client::WriteContext ctx(ns()); + Collection* coll = ctx.ctx().db()->getCollection( ns() ); + // Get the DiskLocs that would be returned by an in-order scan. vector<DiskLoc> locs; - getLocs(CollectionScanParams::FORWARD, &locs); + getLocs(coll, CollectionScanParams::FORWARD, &locs); // Configure the scan. CollectionScanParams params; - params.ns = ns(); + params.collection = coll; params.direction = CollectionScanParams::FORWARD; params.tailable = false; @@ -544,14 +548,15 @@ namespace QueryStageCollectionScan { public: void run() { Client::WriteContext ctx(ns()); + Collection* coll = ctx.ctx().db()->getCollection(ns()); // Get the DiskLocs that would be returned by an in-order scan. vector<DiskLoc> locs; - getLocs(CollectionScanParams::BACKWARD, &locs); + getLocs(coll, CollectionScanParams::BACKWARD, &locs); // Configure the scan. CollectionScanParams params; - params.ns = ns(); + params.collection = coll; params.direction = CollectionScanParams::BACKWARD; params.tailable = false; @@ -599,6 +604,7 @@ namespace QueryStageCollectionScan { public: void run() { Client::WriteContext ctx(ns()); + Collection* coll = ctx.ctx().db()->getCollection(ns()); // We want every result from our collscan to NOT be in memory, at least // the first time around. @@ -609,11 +615,11 @@ namespace QueryStageCollectionScan { // Get the DiskLocs that would be returned by an in-order scan. vector<DiskLoc> locs; - getLocs(CollectionScanParams::FORWARD, &locs); + getLocs(coll, CollectionScanParams::FORWARD, &locs); // Configure the scan. CollectionScanParams params; - params.ns = ns(); + params.collection = coll; params.direction = CollectionScanParams::FORWARD; params.tailable = false; diff --git a/src/mongo/dbtests/query_stage_keep.cpp b/src/mongo/dbtests/query_stage_keep.cpp index 8e4699950e8..46a990146f1 100644 --- a/src/mongo/dbtests/query_stage_keep.cpp +++ b/src/mongo/dbtests/query_stage_keep.cpp @@ -127,7 +127,7 @@ namespace QueryStageKeep { // Create a collscan to provide the 10 objects in the collection. CollectionScanParams params; - params.ns = ns(); + params.collection = coll; params.direction = CollectionScanParams::FORWARD; params.tailable = false; params.start = DiskLoc(); diff --git a/src/mongo/dbtests/querytests.cpp b/src/mongo/dbtests/querytests.cpp index 8c53cc324b7..82454857fab 100644 --- a/src/mongo/dbtests/querytests.cpp +++ b/src/mongo/dbtests/querytests.cpp @@ -115,10 +115,10 @@ namespace QueryTests { BSONObj query = fromjson( "{$or:[{b:2},{c:3}]}" ); BSONObj ret; // Check findOne() returning object. - ASSERT( Helpers::findOne( ns(), query, ret, true ) ); + ASSERT( Helpers::findOne( _collection, query, ret, true ) ); ASSERT_EQUALS( string( "b" ), ret.firstElement().fieldName() ); // Cross check with findOne() returning location. - ASSERT_EQUALS( ret, Helpers::findOne( ns(), query, true ).obj() ); + ASSERT_EQUALS( ret, Helpers::findOne( _collection, query, true ).obj() ); } }; @@ -130,20 +130,20 @@ namespace QueryTests { BSONObj ret; // Check findOne() returning object, allowing unindexed scan. - ASSERT( Helpers::findOne( ns(), query, ret, false ) ); + ASSERT( Helpers::findOne( _collection, query, ret, false ) ); // Check findOne() returning location, allowing unindexed scan. - ASSERT_EQUALS( ret, Helpers::findOne( ns(), query, false ).obj() ); + ASSERT_EQUALS( ret, Helpers::findOne( _collection, query, false ).obj() ); // Check findOne() returning object, requiring indexed scan without index. - ASSERT_THROWS( Helpers::findOne( ns(), query, ret, true ), MsgAssertionException ); + ASSERT_THROWS( Helpers::findOne( _collection, query, ret, true ), MsgAssertionException ); // Check findOne() returning location, requiring indexed scan without index. - ASSERT_THROWS( Helpers::findOne( ns(), query, true ), MsgAssertionException ); + ASSERT_THROWS( Helpers::findOne( _collection, query, true ), MsgAssertionException ); addIndex( BSON( "b" << 1 ) ); // Check findOne() returning object, requiring indexed scan with index. - ASSERT( Helpers::findOne( ns(), query, ret, true ) ); + ASSERT( Helpers::findOne( _collection, query, ret, true ) ); // Check findOne() returning location, requiring indexed scan with index. - ASSERT_EQUALS( ret, Helpers::findOne( ns(), query, true ).obj() ); + ASSERT_EQUALS( ret, Helpers::findOne( _collection, query, true ).obj() ); } }; @@ -171,9 +171,9 @@ namespace QueryTests { insert( BSONObj() ); BSONObj query; BSONObj ret; - ASSERT( Helpers::findOne( ns(), query, ret, false ) ); + ASSERT( Helpers::findOne( _collection, query, ret, false ) ); ASSERT( ret.isEmpty() ); - ASSERT_EQUALS( ret, Helpers::findOne( ns(), query, false ).obj() ); + ASSERT_EQUALS( ret, Helpers::findOne( _collection, query, false ).obj() ); } }; @@ -1226,7 +1226,8 @@ namespace QueryTests { ASSERT_EQUALS( 50 , count() ); BSONObj res; - ASSERT( Helpers::findOne( ns() , BSON( "_id" << 20 ) , res , true ) ); + ASSERT( Helpers::findOne( ctx.ctx().db()->getCollection( ns() ), + BSON( "_id" << 20 ) , res , true ) ); ASSERT_EQUALS( 40 , res["x"].numberInt() ); ASSERT( Helpers::findById( cc(), ns() , BSON( "_id" << 20 ) , res ) ); @@ -1241,7 +1242,8 @@ namespace QueryTests { { Timer t; for ( int i=0; i<n; i++ ) { - ASSERT( Helpers::findOne( ns() , BSON( "_id" << 20 ) , res , true ) ); + ASSERT( Helpers::findOne( ctx.ctx().db()->getCollection(ns()), + BSON( "_id" << 20 ), res, true ) ); } slow = t.micros(); } diff --git a/src/mongo/dbtests/runner_registry.cpp b/src/mongo/dbtests/runner_registry.cpp index 5e4bc4645dd..4a079fb1b93 100644 --- a/src/mongo/dbtests/runner_registry.cpp +++ b/src/mongo/dbtests/runner_registry.cpp @@ -63,7 +63,7 @@ namespace RunnerRegistry { Runner* getCollscan() { auto_ptr<WorkingSet> ws(new WorkingSet()); CollectionScanParams params; - params.ns = ns(); + params.collection = collection(); params.direction = CollectionScanParams::FORWARD; params.tailable = false; auto_ptr<CollectionScan> scan(new CollectionScan(params, ws.get(), NULL)); @@ -87,6 +87,10 @@ namespace RunnerRegistry { int N() { return 50; } + Collection* collection() { + return _ctx->ctx().db()->getCollection( ns() ); + } + static const char* ns() { return "unittests.RunnerRegistryDiskLocInvalidation"; } static DBDirectClient _client; auto_ptr<Client::WriteContext> _ctx; |