diff options
author | Hari Khalsa <hkhalsa@10gen.com> | 2014-01-17 13:18:01 -0500 |
---|---|---|
committer | Hari Khalsa <hkhalsa@10gen.com> | 2014-01-17 14:36:27 -0500 |
commit | 93b398f8808358846cab939e6c93d3b1d96a2230 (patch) | |
tree | 8ae921caae437532da73cd3021ba0d14633828a5 /src | |
parent | 88b256c5edcc13634338d51388dc42c355d1fc31 (diff) | |
download | mongo-93b398f8808358846cab939e6c93d3b1d96a2230.tar.gz |
SERVER-12213 all indices are btree based indices
Diffstat (limited to 'src')
28 files changed, 31 insertions, 119 deletions
diff --git a/src/mongo/db/catalog/index_catalog.cpp b/src/mongo/db/catalog/index_catalog.cpp index f5f0b2546e8..2e40107a044 100644 --- a/src/mongo/db/catalog/index_catalog.cpp +++ b/src/mongo/db/catalog/index_catalog.cpp @@ -1076,35 +1076,6 @@ namespace mongo { return entry->accessMethod(); } - IndexAccessMethod* IndexCatalog::getBtreeIndex( const IndexDescriptor* desc ) { - IndexCatalogEntry* entry = _entries.find( desc ); - massert( 17335, "cannot find index entry", entry ); - if ( !entry->forcedBtreeIndex() ) { - entry->setForcedBtreeIndex( new BtreeAccessMethod( entry ) ); - } - return entry->forcedBtreeIndex(); - } - - BtreeBasedAccessMethod* IndexCatalog::getBtreeBasedIndex( const IndexDescriptor* desc ) { - - string type = _getAccessMethodName(desc->keyPattern()); - - if (IndexNames::HASHED == type || - IndexNames::GEO_2DSPHERE == type || - IndexNames::TEXT == type || - IndexNames::GEO_HAYSTACK == type || - "" == type || - IndexNames::GEO_2D == type ) { - IndexAccessMethod* iam = getIndex( desc ); - return dynamic_cast<BtreeBasedAccessMethod*>( iam ); - } - - error() << "getBtreeBasedIndex with a non btree index (" << type << ")"; - invariant(0); - return NULL; - } - - IndexAccessMethod* IndexCatalog::_createAccessMethod( const IndexDescriptor* desc, IndexCatalogEntry* entry ) { string type = _getAccessMethodName(desc->keyPattern()); diff --git a/src/mongo/db/catalog/index_catalog.h b/src/mongo/db/catalog/index_catalog.h index 83945f99b86..9056b9af975 100644 --- a/src/mongo/db/catalog/index_catalog.h +++ b/src/mongo/db/catalog/index_catalog.h @@ -101,10 +101,6 @@ namespace mongo { // never returns NULL IndexAccessMethod* getIndex( const IndexDescriptor* desc ); - BtreeBasedAccessMethod* getBtreeBasedIndex( const IndexDescriptor* desc ); - - IndexAccessMethod* getBtreeIndex( const IndexDescriptor* desc ); - class IndexIterator { public: bool more(); diff --git a/src/mongo/db/dbhelpers.cpp b/src/mongo/db/dbhelpers.cpp index e298fa81ecd..63cb6b5a2e9 100644 --- a/src/mongo/db/dbhelpers.cpp +++ b/src/mongo/db/dbhelpers.cpp @@ -136,7 +136,10 @@ namespace mongo { if ( indexFound ) *indexFound = 1; - BtreeBasedAccessMethod* accessMethod = catalog->getBtreeBasedIndex( desc ); + // See SERVER-12397. This may not always be true. + BtreeBasedAccessMethod* accessMethod = + static_cast<BtreeBasedAccessMethod*>(catalog->getIndex( desc )); + DiskLoc loc = accessMethod->findSingle( query["_id"].wrap() ); if ( loc.isNull() ) return false; @@ -149,7 +152,9 @@ namespace mongo { IndexCatalog* catalog = collection->getIndexCatalog(); const IndexDescriptor* desc = catalog->findIdIndex(); uassert(13430, "no _id index", desc); - BtreeBasedAccessMethod* accessMethod = catalog->getBtreeBasedIndex( desc ); + // See SERVER-12397. This may not always be true. + BtreeBasedAccessMethod* accessMethod = + static_cast<BtreeBasedAccessMethod*>(catalog->getIndex( desc )); return accessMethod->findSingle( idquery["_id"].wrap() ); } diff --git a/src/mongo/db/exec/2dcommon.cpp b/src/mongo/db/exec/2dcommon.cpp index 0f6348527e5..3ef3117bb50 100644 --- a/src/mongo/db/exec/2dcommon.cpp +++ b/src/mongo/db/exec/2dcommon.cpp @@ -236,7 +236,6 @@ namespace twod_exec { // Two scans: one for min one for max. IndexScanParams minParams; minParams.direction = -1; - minParams.forceBtreeAccessMethod = true; minParams.descriptor = descriptor; minParams.bounds.fields.resize(descriptor->keyPattern().nFields()); minParams.doNotDedup = true; @@ -247,7 +246,6 @@ namespace twod_exec { minParams.bounds.fields[0].intervals.push_back(Interval(firstBob.obj(), false, true)); IndexScanParams maxParams; - maxParams.forceBtreeAccessMethod = true; maxParams.direction = 1; maxParams.descriptor = descriptor; maxParams.bounds.fields.resize(descriptor->keyPattern().nFields()); diff --git a/src/mongo/db/exec/index_scan.cpp b/src/mongo/db/exec/index_scan.cpp index 6b08689afeb..0e422e05aa0 100644 --- a/src/mongo/db/exec/index_scan.cpp +++ b/src/mongo/db/exec/index_scan.cpp @@ -58,24 +58,7 @@ namespace mongo { _params(params), _btreeCursor(NULL) { - string amName; - - // If the query is using complex bounds, we must use a Btree access method, since that's the - // only one that handles complex bounds. - if (params.forceBtreeAccessMethod || !_params.bounds.isSimpleRange) { - _iam = _descriptor->getIndexCatalog()->getBtreeIndex(_descriptor); - amName = ""; - } - else { - amName = _descriptor->getIndexCatalog()->getAccessMethodName(_descriptor->keyPattern()); - _iam = _descriptor->getIndexCatalog()->getIndex(_descriptor); - } - - if (IndexNames::GEO_2D == amName || IndexNames::GEO_2DSPHERE == amName) { - // _endKey is meaningless for 2d and 2dsphere. - verify(_params.bounds.isSimpleRange); - verify(_params.bounds.endKey.isEmpty()); - } + _iam = _descriptor->getIndexCatalog()->getIndex(_descriptor); if (_params.doNotDedup) { _shouldDedup = false; diff --git a/src/mongo/db/exec/index_scan.h b/src/mongo/db/exec/index_scan.h index 787d5d2bf2a..0f18ed8509e 100644 --- a/src/mongo/db/exec/index_scan.h +++ b/src/mongo/db/exec/index_scan.h @@ -47,8 +47,6 @@ namespace mongo { struct IndexScanParams { IndexScanParams() : descriptor(NULL), direction(1), - limit(0), - forceBtreeAccessMethod(false), doNotDedup(false), maxScan(0), addKeyMetadata(false) { } @@ -59,12 +57,6 @@ namespace mongo { int direction; - // This only matters for 2d indices and will be ignored by every other index. - int limit; - - // Special indices internally open an IndexCursor over themselves but as a straight Btree. - bool forceBtreeAccessMethod; - bool doNotDedup; // How many keys will we look at? @@ -78,6 +70,11 @@ namespace mongo { * Stage scans over an index from startKey to endKey, returning results that pass the provided * filter. Internally dedups on DiskLoc. * + * XXX: we probably should split this into 2 stages: one btree-only "fast" ixscan and one + * that strictly talks through the index API. Need to figure out what we really want + * to ship down through that API predicate-wise though, currently is a BSONObj but that's + * not going to be enough. See SERVER-12397 for tracking. + * * Sub-stage preconditions: None. Is a leaf and consumes no stage data. */ class IndexScan : public PlanStage { diff --git a/src/mongo/db/exec/stagedebug_cmd.cpp b/src/mongo/db/exec/stagedebug_cmd.cpp index ecc0c15caeb..dd3f53d9bb9 100644 --- a/src/mongo/db/exec/stagedebug_cmd.cpp +++ b/src/mongo/db/exec/stagedebug_cmd.cpp @@ -187,8 +187,6 @@ namespace mongo { params.bounds.endKey = nodeArgs["endKey"].Obj(); params.bounds.endKeyInclusive = nodeArgs["endKeyInclusive"].Bool(); params.direction = nodeArgs["direction"].numberInt(); - params.limit = nodeArgs["limit"].numberInt(); - params.forceBtreeAccessMethod = false; return new IndexScan(params, workingSet, matcher); } diff --git a/src/mongo/db/exec/text.cpp b/src/mongo/db/exec/text.cpp index a4b73a1e035..dc97425323c 100644 --- a/src/mongo/db/exec/text.cpp +++ b/src/mongo/db/exec/text.cpp @@ -137,7 +137,6 @@ namespace mongo { params.bounds.endKeyInclusive = true; params.bounds.isSimpleRange = true; params.descriptor = idxMatches[0]; - params.forceBtreeAccessMethod = true; params.direction = -1; IndexScan* ixscan = new IndexScan(params, _ws, NULL); scanners.push_back(ixscan); diff --git a/src/mongo/db/index/2d_access_method.cpp b/src/mongo/db/index/2d_access_method.cpp index 001508a21aa..4e21df67779 100644 --- a/src/mongo/db/index/2d_access_method.cpp +++ b/src/mongo/db/index/2d_access_method.cpp @@ -191,8 +191,4 @@ namespace mongo { } } - Status TwoDAccessMethod::newCursor(IndexCursor** out) const { - return Status(ErrorCodes::IllegalOperation, "Unimplemented seek called on S2"); - } - } // namespace mongo diff --git a/src/mongo/db/index/2d_access_method.h b/src/mongo/db/index/2d_access_method.h index 9b0a5f60f01..f387c121aad 100644 --- a/src/mongo/db/index/2d_access_method.h +++ b/src/mongo/db/index/2d_access_method.h @@ -72,8 +72,6 @@ namespace mongo { TwoDAccessMethod(IndexCatalogEntry* btreeState); virtual ~TwoDAccessMethod() { } - virtual Status newCursor(IndexCursor** out) const; - private: friend class TwoDIndexCursor; friend class twod_internal::GeoPoint; diff --git a/src/mongo/db/index/btree_access_method.cpp b/src/mongo/db/index/btree_access_method.cpp index 24c7ac12810..37558a40bdf 100644 --- a/src/mongo/db/index/btree_access_method.cpp +++ b/src/mongo/db/index/btree_access_method.cpp @@ -70,9 +70,4 @@ namespace mongo { _keyGenerator->getKeys(obj, keys); } - Status BtreeAccessMethod::newCursor(IndexCursor** out) const { - *out = new BtreeIndexCursor(_btreeState, _interface); - return Status::OK(); - } - } // namespace mongo diff --git a/src/mongo/db/index/btree_access_method.h b/src/mongo/db/index/btree_access_method.h index 0c3914d97b5..66cb0bf5fde 100644 --- a/src/mongo/db/index/btree_access_method.h +++ b/src/mongo/db/index/btree_access_method.h @@ -57,8 +57,6 @@ namespace mongo { BtreeAccessMethod(IndexCatalogEntry* btreeState ); virtual ~BtreeAccessMethod() { } - virtual Status newCursor(IndexCursor** out) const; - private: virtual void getKeys(const BSONObj& obj, BSONObjSet* keys); diff --git a/src/mongo/db/index/btree_based_access_method.cpp b/src/mongo/db/index/btree_based_access_method.cpp index 134084229f7..e4fd7992009 100644 --- a/src/mongo/db/index/btree_based_access_method.cpp +++ b/src/mongo/db/index/btree_based_access_method.cpp @@ -122,6 +122,11 @@ namespace mongo { return ret; } + Status BtreeBasedAccessMethod::newCursor(IndexCursor **out) const { + *out = new BtreeIndexCursor(_btreeState, _interface); + return Status::OK(); + } + // Remove the provided doc from the index. Status BtreeBasedAccessMethod::remove(const BSONObj &obj, const DiskLoc& loc, const InsertDeleteOptions &options, int64_t* numDeleted) { @@ -343,6 +348,7 @@ namespace mongo { virtual Status newCursor(IndexCursor **out) const { return _notAllowed(); } + virtual Status initializeAsEmpty() { return _notAllowed(); } diff --git a/src/mongo/db/index/btree_based_access_method.h b/src/mongo/db/index/btree_based_access_method.h index cf3b82c2828..76cd8bef706 100644 --- a/src/mongo/db/index/btree_based_access_method.h +++ b/src/mongo/db/index/btree_based_access_method.h @@ -47,9 +47,12 @@ namespace mongo { * Any access method that is Btree based subclasses from this. * * Subclassers must: - * 1. Call the constructor for this class from their constructors, - * 2. override newCursor, and - * 3. override getKeys. + * 1. Call the constructor for this class from their constructors, and + * 2. override getKeys. + * + * XXX: Should really think of the sub-class as providing an expression mapping of the input, + * don't need so many AMs, just really precomputing some data and mapping doc for getKeys(?). + * See SERVER-12397 for tracking. */ class BtreeBasedAccessMethod : public IndexAccessMethod { MONGO_DISALLOW_COPYING( BtreeBasedAccessMethod ); @@ -76,7 +79,7 @@ namespace mongo { virtual Status update(const UpdateTicket& ticket, int64_t* numUpdated); - virtual Status newCursor(IndexCursor **out) const = 0; + virtual Status newCursor(IndexCursor **out) const; virtual Status initializeAsEmpty(); diff --git a/src/mongo/db/index/btree_index_cursor.h b/src/mongo/db/index/btree_index_cursor.h index 0b1fadcfba0..469d6383490 100644 --- a/src/mongo/db/index/btree_index_cursor.h +++ b/src/mongo/db/index/btree_index_cursor.h @@ -78,7 +78,7 @@ namespace mongo { private: // We keep the constructor private and only allow the AM to create us. - friend class BtreeAccessMethod; + friend class BtreeBasedAccessMethod; // For handling bucket deletion. static unordered_set<BtreeIndexCursor*> _activeCursors; diff --git a/src/mongo/db/index/fts_access_method.cpp b/src/mongo/db/index/fts_access_method.cpp index 1aaadde4792..47cb519f3bc 100644 --- a/src/mongo/db/index/fts_access_method.cpp +++ b/src/mongo/db/index/fts_access_method.cpp @@ -38,8 +38,4 @@ namespace mongo { fts::FTSIndexFormat::getKeys(_ftsSpec, obj, keys); } - Status FTSAccessMethod::newCursor(IndexCursor** out) const { - return Status::OK(); - } - } // namespace mongo diff --git a/src/mongo/db/index/fts_access_method.h b/src/mongo/db/index/fts_access_method.h index 47dc8a98405..ba10b4e2b67 100644 --- a/src/mongo/db/index/fts_access_method.h +++ b/src/mongo/db/index/fts_access_method.h @@ -41,9 +41,6 @@ namespace mongo { FTSAccessMethod(IndexCatalogEntry* btreeState ); virtual ~FTSAccessMethod() { } - // Not implemented: - virtual Status newCursor(IndexCursor** out) const; - const fts::FTSSpec& getSpec() const { return _ftsSpec; } private: diff --git a/src/mongo/db/index/hash_access_method.cpp b/src/mongo/db/index/hash_access_method.cpp index 3aff284d11e..eb78f1934d8 100644 --- a/src/mongo/db/index/hash_access_method.cpp +++ b/src/mongo/db/index/hash_access_method.cpp @@ -78,10 +78,6 @@ namespace mongo { _hashedField = firstElt.fieldName(); } - Status HashAccessMethod::newCursor(IndexCursor** out) const { - return Status(ErrorCodes::IllegalOperation, "Unimplemented seek called on hash"); - } - void HashAccessMethod::getKeys(const BSONObj& obj, BSONObjSet* keys) { getKeysImpl(obj, _hashedField, _seed, _hashVersion, _descriptor->isSparse(), keys); } diff --git a/src/mongo/db/index/hash_access_method.h b/src/mongo/db/index/hash_access_method.h index cb49b9e0b8b..c2b9fa836b6 100644 --- a/src/mongo/db/index/hash_access_method.h +++ b/src/mongo/db/index/hash_access_method.h @@ -48,8 +48,6 @@ namespace mongo { HashAccessMethod(IndexCatalogEntry* btreeState); virtual ~HashAccessMethod() { } - virtual Status newCursor(IndexCursor** out) const; - // This is a NO-OP. virtual Status setOptions(const CursorOptions& options) { return Status::OK(); diff --git a/src/mongo/db/index/haystack_access_method.cpp b/src/mongo/db/index/haystack_access_method.cpp index aaddea81207..0fdf9dfa78f 100644 --- a/src/mongo/db/index/haystack_access_method.cpp +++ b/src/mongo/db/index/haystack_access_method.cpp @@ -137,10 +137,6 @@ namespace mongo { keys->insert(buf.obj()); } - Status HaystackAccessMethod::newCursor(IndexCursor** out) const { - return Status(ErrorCodes::IllegalOperation, "Unimplemented seek called on Haystack"); - } - void HaystackAccessMethod::searchCommand(const BSONObj& nearObj, double maxDistance, const BSONObj& search, BSONObjBuilder* result, unsigned limit) { diff --git a/src/mongo/db/index/haystack_access_method.h b/src/mongo/db/index/haystack_access_method.h index 1b07dce048e..0e1dd3426c7 100644 --- a/src/mongo/db/index/haystack_access_method.h +++ b/src/mongo/db/index/haystack_access_method.h @@ -58,9 +58,6 @@ namespace mongo { HaystackAccessMethod(IndexCatalogEntry* btreeState); virtual ~HaystackAccessMethod() { } - // Not implemented. - virtual Status newCursor(IndexCursor** out) const; - protected: friend class GeoHaystackSearchCommand; void searchCommand(const BSONObj& nearObj, double maxDistance, const BSONObj& search, diff --git a/src/mongo/db/index/s2_access_method.cpp b/src/mongo/db/index/s2_access_method.cpp index db1b429cac4..328c7031550 100644 --- a/src/mongo/db/index/s2_access_method.cpp +++ b/src/mongo/db/index/s2_access_method.cpp @@ -85,10 +85,6 @@ namespace mongo { geoFields >= 1); } - Status S2AccessMethod::newCursor(IndexCursor** out) const { - return Status(ErrorCodes::IllegalOperation, "Unimplemented seek called on S2"); - } - void S2AccessMethod::getKeys(const BSONObj& obj, BSONObjSet* keys) { BSONObjSet keysToAdd; // We output keys in the same order as the fields we index. diff --git a/src/mongo/db/index/s2_access_method.h b/src/mongo/db/index/s2_access_method.h index 33e7cf1647b..0dedc83016f 100644 --- a/src/mongo/db/index/s2_access_method.h +++ b/src/mongo/db/index/s2_access_method.h @@ -46,8 +46,6 @@ namespace mongo { S2AccessMethod(IndexCatalogEntry* btreeState); virtual ~S2AccessMethod() { } - virtual Status newCursor(IndexCursor** out) const; - private: virtual void getKeys(const BSONObj& obj, BSONObjSet* keys); diff --git a/src/mongo/db/query/idhack_runner.cpp b/src/mongo/db/query/idhack_runner.cpp index 1c2921d0da4..5a20d56c4df 100644 --- a/src/mongo/db/query/idhack_runner.cpp +++ b/src/mongo/db/query/idhack_runner.cpp @@ -66,7 +66,9 @@ namespace mongo { return Runner::RUNNER_EOF; } - BtreeBasedAccessMethod* accessMethod = catalog->getBtreeBasedIndex( idDesc ); + // XXX: This may not be valid always. See SERVER-12397. + BtreeBasedAccessMethod* accessMethod = + static_cast<BtreeBasedAccessMethod*>(catalog->getIndex(idDesc)); BSONObj key = _query->getQueryObj()["_id"].wrap(); diff --git a/src/mongo/db/query/internal_plans.h b/src/mongo/db/query/internal_plans.h index 19cdbf72213..be09789d8bb 100644 --- a/src/mongo/db/query/internal_plans.h +++ b/src/mongo/db/query/internal_plans.h @@ -103,9 +103,6 @@ namespace mongo { params.bounds.startKey = startKey; params.bounds.endKey = endKey; params.bounds.endKeyInclusive = endKeyInclusive; - // This always as 'true' as this is the new btreecursor. Even if the underlying index - // is 'special' (ie, expression) we treat it like a Btree. - params.forceBtreeAccessMethod = true; WorkingSet* ws = new WorkingSet(); IndexScan* ix = new IndexScan(params, ws, NULL); diff --git a/src/mongo/db/query/query_solution.cpp b/src/mongo/db/query/query_solution.cpp index 4cb0b0c0630..2c1a16d0a34 100644 --- a/src/mongo/db/query/query_solution.cpp +++ b/src/mongo/db/query/query_solution.cpp @@ -308,7 +308,7 @@ namespace mongo { // IndexScanNode::IndexScanNode() - : indexIsMultiKey(false), limit(0), direction(1), maxScan(0), addKeyMetadata(false) { } + : indexIsMultiKey(false), direction(1), maxScan(0), addKeyMetadata(false) { } void IndexScanNode::appendToString(mongoutils::str::stream* ss, int indent) const { addIndent(ss, indent); diff --git a/src/mongo/db/query/query_solution.h b/src/mongo/db/query/query_solution.h index 2f66dd706c1..b337536552b 100644 --- a/src/mongo/db/query/query_solution.h +++ b/src/mongo/db/query/query_solution.h @@ -354,9 +354,6 @@ namespace mongo { BSONObj indexKeyPattern; bool indexIsMultiKey; - // Only set for 2d. - int limit; - int direction; // maxScan option to .find() limits how many docs we look at. diff --git a/src/mongo/db/query/stage_builder.cpp b/src/mongo/db/query/stage_builder.cpp index 9c65cb76a48..886ebf56f5b 100644 --- a/src/mongo/db/query/stage_builder.cpp +++ b/src/mongo/db/query/stage_builder.cpp @@ -88,7 +88,6 @@ namespace mongo { params.bounds = ixn->bounds; params.direction = ixn->direction; - params.limit = ixn->limit; params.maxScan = ixn->maxScan; params.addKeyMetadata = ixn->addKeyMetadata; return new IndexScan(params, ws, ixn->filter.get()); |