diff options
author | Eliot Horowitz <eliot@10gen.com> | 2014-01-06 14:25:45 -0500 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2014-01-09 14:21:49 -0500 |
commit | aa0d807497e09fcee93a21b437b354ad0dcffd11 (patch) | |
tree | 51ee50e890847df986eebf0a645c067212114075 /src/mongo/db | |
parent | ea5d43f74e4ddf990a156ce37b05369cd9ee3479 (diff) | |
download | mongo-aa0d807497e09fcee93a21b437b354ad0dcffd11.tar.gz |
SERVER-12213: merge BtreInMemoryState and IndexCatalogEntry
Diffstat (limited to 'src/mongo/db')
33 files changed, 329 insertions, 496 deletions
diff --git a/src/mongo/db/catalog/index_catalog.cpp b/src/mongo/db/catalog/index_catalog.cpp index b0382e7dc29..943cee3cc9b 100644 --- a/src/mongo/db/catalog/index_catalog.cpp +++ b/src/mongo/db/catalog/index_catalog.cpp @@ -105,17 +105,15 @@ namespace mongo { auto_ptr<RecordStore> recordStore( new RecordStore( descriptor->indexNamespace() ) ); recordStore->init( indexMetadata, _collection->getExtentManager(), false ); - auto_ptr<BtreeInMemoryState> state( new BtreeInMemoryState( _collection, - descriptor.get(), - recordStore.release() ) ); - state->setIsReady( true ); + auto_ptr<IndexCatalogEntry> entry( new IndexCatalogEntry( _collection, + descriptor.release(), + recordStore.release() ) ); - auto_ptr<IndexAccessMethod> accessMethod( _createAccessMethod( descriptor.get(), - state.get() ) ); + entry->init( _createAccessMethod( entry->descriptor(), + entry.get() ) ); + + fassert( 17340, entry->isReady() ); - auto_ptr<IndexCatalogEntry> entry( new IndexCatalogEntry( descriptor.release(), - state.release(), - accessMethod.release() ) ); _entries.add( entry.release() ); } @@ -332,16 +330,12 @@ namespace mongo { // finish creating in memory state // --------- { - auto_ptr<BtreeInMemoryState> state( new BtreeInMemoryState( _collection, - descriptor, - recordStore.release() ) ); - - auto_ptr<IndexAccessMethod> accessMethod( _createAccessMethod( descriptor, - state.get() ) ); + auto_ptr<IndexCatalogEntry> entry( new IndexCatalogEntry( _collection, + descriptorCleaner.release(), + recordStore.release() ) ); - auto_ptr<IndexCatalogEntry> entry( new IndexCatalogEntry( descriptorCleaner.release(), - state.release(), - accessMethod.release() ) ); + entry->init( _createAccessMethod( entry->descriptor(), + entry.get() ) ); _entries.add( entry.release() ); } @@ -361,7 +355,7 @@ namespace mongo { cc().curop()->setQuery( spec ); } - buildAnIndex( _collection, entry->state(), mayInterrupt ); + buildAnIndex( _collection, entry, mayInterrupt ); indexBuildBlock.success(); int idxNo = _details->_catalogFindIndexByName( idxName, true ); @@ -478,7 +472,7 @@ namespace mongo { IndexCatalogEntry* entry = _catalog->_entries.find( desc ); fassert( 17331, entry ); - entry->state()->setIsReady( true ); + entry->setIsReady( true ); IndexLegacy::postBuildHook( _catalog->_collection, _catalog->findIndexByName( _indexName )->keyPattern() ); @@ -764,7 +758,7 @@ namespace mongo { IndexCatalogEntry* entry = _entries.find( desc ); if ( !entry ) return Status( ErrorCodes::InternalError, "cannot find index to delete" ); - if ( !entry->state()->isReady() ) + if ( !entry->isReady() ) return Status( ErrorCodes::InternalError, "cannot delete not ready index" ); return _dropIndex( entry ); } @@ -914,7 +908,7 @@ namespace mongo { bool IndexCatalog::isMultikey( const IndexDescriptor* idx ) { IndexCatalogEntry* entry = _entries.find( idx ); verify( entry ); - return entry->state()->isMultikey(); + return entry->isMultikey(); } @@ -972,7 +966,7 @@ namespace mongo { ++_iterator; if ( _includeUnfinishedIndexes || - entry->state()->isReady() ) { + entry->isReady() ) { _next = entry; return; } @@ -1054,7 +1048,7 @@ namespace mongo { IndexCatalogEntry* entry = _entries.find( desc ); massert( 17335, "cannot find index entry", entry ); if ( !entry->forcedBtreeIndex() ) { - entry->setForcedBtreeIndex( new BtreeAccessMethod( entry->state() ) ); + entry->setForcedBtreeIndex( new BtreeAccessMethod( entry ) ); } return entry->forcedBtreeIndex(); } @@ -1080,26 +1074,26 @@ namespace mongo { IndexAccessMethod* IndexCatalog::_createAccessMethod( const IndexDescriptor* desc, - BtreeInMemoryState* state ) { + IndexCatalogEntry* entry ) { string type = _getAccessMethodName(desc->keyPattern()); if (IndexNames::HASHED == type) - return new HashAccessMethod( state ); + return new HashAccessMethod( entry ); if (IndexNames::GEO_2DSPHERE == type) - return new S2AccessMethod( state ); + return new S2AccessMethod( entry ); if (IndexNames::TEXT == type) - return new FTSAccessMethod( state ); + return new FTSAccessMethod( entry ); if (IndexNames::GEO_HAYSTACK == type) - return new HaystackAccessMethod( state ); + return new HaystackAccessMethod( entry ); if ("" == type) - return new BtreeAccessMethod( state ); + return new BtreeAccessMethod( entry ); if (IndexNames::GEO_2D == type) - return new TwoDAccessMethod( state ); + return new TwoDAccessMethod( entry ); log() << "Can't find index for keypattern " << desc->keyPattern(); verify(0); @@ -1196,7 +1190,7 @@ namespace mongo { IndexCatalogEntry* entry = *i; // If it's a background index, we DO NOT want to log anything. - bool logIfError = entry->state()->isReady() ? !noWarn : false; + bool logIfError = entry->isReady() ? !noWarn : false; _unindexRecord( entry, obj, loc, logIfError ); } diff --git a/src/mongo/db/catalog/index_catalog.h b/src/mongo/db/catalog/index_catalog.h index 30b396b23a3..faea5cb3ca0 100644 --- a/src/mongo/db/catalog/index_catalog.h +++ b/src/mongo/db/catalog/index_catalog.h @@ -34,7 +34,7 @@ #include "mongo/db/diskloc.h" #include "mongo/db/jsobj.h" -#include "mongo/db/catalog/index_catalog_internal.h" +#include "mongo/db/catalog/index_catalog_entry.h" namespace mongo { @@ -215,7 +215,7 @@ namespace mongo { // creates a new thing, no caching IndexAccessMethod* _createAccessMethod( const IndexDescriptor* desc, - BtreeInMemoryState* state ); + IndexCatalogEntry* entry ); Status _upgradeDatabaseMinorVersionIfNeeded( const string& newPluginName ); diff --git a/src/mongo/db/catalog/index_catalog_internal.cpp b/src/mongo/db/catalog/index_catalog_entry.cpp index ce2eb5cd2f7..ef1d0941864 100644 --- a/src/mongo/db/catalog/index_catalog_internal.cpp +++ b/src/mongo/db/catalog/index_catalog_entry.cpp @@ -1,4 +1,4 @@ -// index_catalog_internal.h +// index_catalog_entry.h /** * Copyright (C) 2013 10gen Inc. @@ -28,29 +28,109 @@ * it in the license file. */ -#include "mongo/db/catalog/index_catalog_internal.h" +#include "mongo/db/catalog/index_catalog_entry.h" #include "mongo/db/index/index_access_method.h" #include "mongo/db/index/index_descriptor.h" -#include "mongo/db/structure/btree/state.h" namespace mongo { - IndexCatalogEntry::IndexCatalogEntry( IndexDescriptor* descriptor, - BtreeInMemoryState* state, - IndexAccessMethod* accessMethod ) - : _descriptor( descriptor ), - _state( state ), - _accessMethod( accessMethod ), - _forcedBtreeIndex( 0 ) { - } + IndexCatalogEntry::IndexCatalogEntry( Collection* collection, + IndexDescriptor* descriptor, + RecordStore* recordstore ) + : _collection( collection ), + _descriptor( descriptor ), + _recordStore( recordstore ), + _accessMethod( NULL ), + _forcedBtreeIndex( NULL ), + _ordering( Ordering::make( descriptor->keyPattern() ) ), + _isReady( false ) { + } IndexCatalogEntry::~IndexCatalogEntry() { + delete _forcedBtreeIndex; delete _accessMethod; - delete _state; + + delete _recordStore; + delete _descriptor; } + void IndexCatalogEntry::init( IndexAccessMethod* accessMethod ) { + verify( _accessMethod == NULL ); + _accessMethod = accessMethod; + + _isReady = _catalogIsReady(); + _head = _catalogHead(); + _isMultikey = _catalogIsMultikey(); + } + + const DiskLoc& IndexCatalogEntry::head() const { + DEV verify( _head == _catalogHead() ); + return _head; + } + + bool IndexCatalogEntry::isReady() const { + DEV verify( _isReady == _catalogIsReady() ); + return _isReady; + } + + bool IndexCatalogEntry::isMultikey() const { + DEV verify( _isMultikey == _catalogIsMultikey() ); + return _isMultikey; + } + + // --- + + void IndexCatalogEntry::setIsReady( bool newIsReady ) { + _isReady = newIsReady; + verify( isReady() == newIsReady ); + } + + void IndexCatalogEntry::setHead( DiskLoc newHead ) { + NamespaceDetails* nsd = _collection->details(); + int idxNo = _indexNo(); + IndexDetails& id = nsd->idx( idxNo ); + id.head.writing() = newHead; + _head = newHead; + } + + void IndexCatalogEntry::setMultikey() { + NamespaceDetails* nsd = _collection->details(); + int idxNo = _indexNo(); + if ( nsd->setIndexIsMultikey( idxNo, true ) ) + _collection->infoCache()->clearQueryCache(); + _isMultikey = true; + } + + // ---- + + bool IndexCatalogEntry::_catalogIsReady() const { + return _indexNo() < _collection->getIndexCatalog()->numIndexesReady(); + } + + DiskLoc IndexCatalogEntry::_catalogHead() const { + NamespaceDetails* nsd = _collection->details(); + int idxNo = _indexNo(); + return nsd->idx( idxNo ).head; + } + + bool IndexCatalogEntry::_catalogIsMultikey() const { + NamespaceDetails* nsd = _collection->details(); + int idxNo = _indexNo(); + return nsd->isMultikey( idxNo ); + } + + int IndexCatalogEntry::_indexNo() const { + int idxNo = _collection->details()->_catalogFindIndexByName( _descriptor->indexName(), + true ); + fassert( 17341, idxNo >= 0 ); + return idxNo; + } + + + // ------------------ + const IndexCatalogEntry* IndexCatalogEntryContainer::find( const IndexDescriptor* desc ) const { for ( const_iterator i = begin(); i != end(); ++i ) { const IndexCatalogEntry* e = *i; diff --git a/src/mongo/db/catalog/index_catalog_internal.h b/src/mongo/db/catalog/index_catalog_entry.h index 895dc390801..17e5389a834 100644 --- a/src/mongo/db/catalog/index_catalog_internal.h +++ b/src/mongo/db/catalog/index_catalog_entry.h @@ -1,4 +1,4 @@ -// index_catalog_internal.h +// index_catalog_entry.h /** * Copyright (C) 2013 10gen Inc. @@ -33,37 +33,86 @@ #include <string> #include "mongo/base/owned_pointer_vector.h" +#include "mongo/bson/ordering.h" +#include "mongo/db/diskloc.h" namespace mongo { + class Collection; class IndexDescriptor; - class BtreeInMemoryState; + class RecordStore; class IndexAccessMethod; class IndexCatalogEntry { + MONGO_DISALLOW_COPYING( IndexCatalogEntry ); public: - IndexCatalogEntry( IndexDescriptor* descriptor, - BtreeInMemoryState* state, - IndexAccessMethod* accessMethod ); + IndexCatalogEntry( Collection* collection, + IndexDescriptor* descriptor, // ownership passes to me + RecordStore* recordStore ); // ownership passes to me ~IndexCatalogEntry(); - IndexDescriptor* descriptor() { return _descriptor; } - BtreeInMemoryState* state() { return _state; } - IndexAccessMethod* accessMethod() { return _accessMethod; } + void init( IndexAccessMethod* accessMethod ); + const Collection* collection() const { return _collection; } + + IndexDescriptor* descriptor() { return _descriptor; } const IndexDescriptor* descriptor() const { return _descriptor; } - const BtreeInMemoryState* state() const { return _state; } + + IndexAccessMethod* accessMethod() { return _accessMethod; } const IndexAccessMethod* accessMethod() const { return _accessMethod; } IndexAccessMethod* forcedBtreeIndex() { return _forcedBtreeIndex; } + // ownership passes void setForcedBtreeIndex( IndexAccessMethod* iam ) { _forcedBtreeIndex = iam; } + RecordStore* recordStore() { return _recordStore; } + const RecordStore* recordStore() const { return _recordStore; } + + const Ordering& ordering() const { return _ordering; } + + /// --------------------- + + const DiskLoc& head() const; + + void setHead( DiskLoc newHead ); + + void setIsReady( bool newIsReady ); + + // -- + + bool isMultikey() const; + + void setMultikey(); + + // if this ready is ready for queries + bool isReady() const; + private: + + int _indexNo() const; + + bool _catalogIsReady() const; + DiskLoc _catalogHead() const; + bool _catalogIsMultikey() const; + + // ----- + + Collection* _collection; // not owned here + IndexDescriptor* _descriptor; // owned here - BtreeInMemoryState* _state; // owned here + + RecordStore* _recordStore; // owned here + IndexAccessMethod* _accessMethod; // owned here IndexAccessMethod* _forcedBtreeIndex; // owned here + + // cached stuff + + Ordering _ordering; // TODO: this might be b-tree specific + bool _isReady; // cache of NamespaceDetails info + DiskLoc _head; // cache of IndexDetails + bool _isMultikey; // cache of NamespaceDetails info }; class IndexCatalogEntryContainer { diff --git a/src/mongo/db/catalog/index_create.cpp b/src/mongo/db/catalog/index_create.cpp index d43bb68b449..1d29237d69f 100644 --- a/src/mongo/db/catalog/index_create.cpp +++ b/src/mongo/db/catalog/index_create.cpp @@ -81,7 +81,7 @@ namespace mongo { : BackgroundOperation(ns) { } - unsigned long long go( Collection* collection, BtreeInMemoryState* idx ); + unsigned long long go( Collection* collection, IndexCatalogEntry* idx ); private: unsigned long long addExistingToIndex( Collection* collection, @@ -103,7 +103,7 @@ namespace mongo { }; unsigned long long BackgroundIndexBuildJob::go( Collection* collection, - BtreeInMemoryState* btreeState) { + IndexCatalogEntry* btreeState) { string ns = collection->ns().ns(); @@ -226,7 +226,7 @@ namespace mongo { // throws DBException void buildAnIndex( Collection* collection, - BtreeInMemoryState* btreeState, + IndexCatalogEntry* btreeState, bool mayInterrupt ) { string ns = collection->ns().ns(); // our copy diff --git a/src/mongo/db/catalog/index_create.h b/src/mongo/db/catalog/index_create.h index 6abe7e07484..88aad085afd 100644 --- a/src/mongo/db/catalog/index_create.h +++ b/src/mongo/db/catalog/index_create.h @@ -34,14 +34,14 @@ namespace mongo { - class BtreeInMemoryState; + class IndexCatalogEntry; class Collection; // Build an index in the foreground // If background is false, uses fast index builder // If background is true, uses background index builder; blocks until done. void buildAnIndex( Collection* collection, - BtreeInMemoryState* btreeState, + IndexCatalogEntry* btreeState, bool mayInterrupt ); } // namespace mongo diff --git a/src/mongo/db/index/2d_access_method.cpp b/src/mongo/db/index/2d_access_method.cpp index 0c33e54dd88..001508a21aa 100644 --- a/src/mongo/db/index/2d_access_method.cpp +++ b/src/mongo/db/index/2d_access_method.cpp @@ -45,7 +45,7 @@ namespace mongo { return def; } - TwoDAccessMethod::TwoDAccessMethod(BtreeInMemoryState* btreeState) + TwoDAccessMethod::TwoDAccessMethod(IndexCatalogEntry* btreeState) : BtreeBasedAccessMethod(btreeState) { const IndexDescriptor* descriptor = btreeState->descriptor(); diff --git a/src/mongo/db/index/2d_access_method.h b/src/mongo/db/index/2d_access_method.h index e3986382569..782162da8b0 100644 --- a/src/mongo/db/index/2d_access_method.h +++ b/src/mongo/db/index/2d_access_method.h @@ -35,7 +35,7 @@ namespace mongo { - class BtreeInMemoryState; + class IndexCatalogEntry; class IndexCursor; class IndexDescriptor; struct TwoDIndexingParams; @@ -69,7 +69,7 @@ namespace mongo { using BtreeBasedAccessMethod::_descriptor; using BtreeBasedAccessMethod::_interface; - TwoDAccessMethod(BtreeInMemoryState* btreeState); + TwoDAccessMethod(IndexCatalogEntry* btreeState); virtual ~TwoDAccessMethod() { } virtual Status newCursor(IndexCursor** out) const; diff --git a/src/mongo/db/index/btree_access_method.cpp b/src/mongo/db/index/btree_access_method.cpp index f3317725bdd..d73ae59e321 100644 --- a/src/mongo/db/index/btree_access_method.cpp +++ b/src/mongo/db/index/btree_access_method.cpp @@ -37,11 +37,10 @@ #include "mongo/db/keypattern.h" #include "mongo/db/pdfile.h" #include "mongo/db/pdfile_private.h" -#include "mongo/db/structure/btree/state-inl.h" namespace mongo { - BtreeBasedAccessMethod::BtreeBasedAccessMethod(BtreeInMemoryState* btreeState) + BtreeBasedAccessMethod::BtreeBasedAccessMethod(IndexCatalogEntry* btreeState) : _btreeState(btreeState), _descriptor(btreeState->descriptor()) { verify(0 == _descriptor->version() || 1 == _descriptor->version()); @@ -181,15 +180,18 @@ namespace mongo { } DiskLoc BtreeBasedAccessMethod::findSingle( const BSONObj& key ) { + DiskLoc head = _btreeState->head(); + Record* record = _btreeState->recordStore()->recordFor( head ); + if ( 0 == _descriptor->version() ) { - return _btreeState->getHeadBucket<V0>()->findSingle( _btreeState, - _btreeState->head(), - key ); + return BtreeBucket<V0>::asVersion( record )->findSingle( _btreeState, + _btreeState->head(), + key ); } if ( 1 == _descriptor->version() ) { - return _btreeState->getHeadBucket<V1>()->findSingle( _btreeState, - _btreeState->head(), - key ); + return BtreeBucket<V1>::asVersion( record )->findSingle( _btreeState, + _btreeState->head(), + key ); } verify( 0 ); } @@ -274,7 +276,7 @@ namespace mongo { } // Standard Btree implementation below. - BtreeAccessMethod::BtreeAccessMethod(BtreeInMemoryState* btreeState) + BtreeAccessMethod::BtreeAccessMethod(IndexCatalogEntry* btreeState) : BtreeBasedAccessMethod(btreeState) { // The key generation wants these values. diff --git a/src/mongo/db/index/btree_access_method.h b/src/mongo/db/index/btree_access_method.h index 09028615350..d6c80a7f215 100644 --- a/src/mongo/db/index/btree_access_method.h +++ b/src/mongo/db/index/btree_access_method.h @@ -54,7 +54,7 @@ namespace mongo { using BtreeBasedAccessMethod::_descriptor; using BtreeBasedAccessMethod::_interface; - BtreeAccessMethod(BtreeInMemoryState* btreeState ); + BtreeAccessMethod(IndexCatalogEntry* btreeState ); virtual ~BtreeAccessMethod() { } virtual Status newCursor(IndexCursor** out) const; diff --git a/src/mongo/db/index/btree_access_method_internal.h b/src/mongo/db/index/btree_access_method_internal.h index dc9b41e41db..320c1de8944 100644 --- a/src/mongo/db/index/btree_access_method_internal.h +++ b/src/mongo/db/index/btree_access_method_internal.h @@ -37,7 +37,6 @@ #include "mongo/db/index/index_access_method.h" #include "mongo/db/index/index_cursor.h" #include "mongo/db/index/index_descriptor.h" -#include "mongo/db/structure/btree/state.h" namespace mongo { @@ -52,7 +51,7 @@ namespace mongo { class BtreeBasedAccessMethod : public IndexAccessMethod { MONGO_DISALLOW_COPYING( BtreeBasedAccessMethod ); public: - BtreeBasedAccessMethod( BtreeInMemoryState* btreeState ); + BtreeBasedAccessMethod( IndexCatalogEntry* btreeState ); virtual ~BtreeBasedAccessMethod() { } @@ -92,7 +91,7 @@ namespace mongo { virtual void getKeys(const BSONObj &obj, BSONObjSet *keys) = 0; - BtreeInMemoryState* _btreeState; // owned by IndexCatalogEntry + IndexCatalogEntry* _btreeState; // owned by IndexCatalogEntry const IndexDescriptor* _descriptor; // There are 2 types of Btree disk formats. We put them both behind one interface. diff --git a/src/mongo/db/index/btree_based_builder.cpp b/src/mongo/db/index/btree_based_builder.cpp index acd24d76d76..1a321f43b4e 100644 --- a/src/mongo/db/index/btree_based_builder.cpp +++ b/src/mongo/db/index/btree_based_builder.cpp @@ -75,7 +75,7 @@ namespace mongo { template< class V > void buildBottomUpPhases2And3( bool dupsAllowed, - BtreeInMemoryState* btreeState, + IndexCatalogEntry* btreeState, BSONObjExternalSorter& sorter, bool dropDups, set<DiskLoc>& dupsToDrop, @@ -136,7 +136,7 @@ namespace mongo { } } - DiskLoc BtreeBasedBuilder::makeEmptyIndex(BtreeInMemoryState* idx) { + DiskLoc BtreeBasedBuilder::makeEmptyIndex(IndexCatalogEntry* idx) { if (0 == idx->descriptor()->version()) { return BtreeBucket<V0>::addBucket(idx); } else { @@ -189,7 +189,7 @@ namespace mongo { } uint64_t BtreeBasedBuilder::fastBuildIndex( Collection* collection, - BtreeInMemoryState* btreeState, + IndexCatalogEntry* btreeState, bool mayInterrupt ) { CurOp * op = cc().curop(); Timer t; diff --git a/src/mongo/db/index/btree_based_builder.h b/src/mongo/db/index/btree_based_builder.h index e003d2b9518..d9515c3f6de 100644 --- a/src/mongo/db/index/btree_based_builder.h +++ b/src/mongo/db/index/btree_based_builder.h @@ -44,7 +44,7 @@ namespace mongo { class Collection; class BSONObjExternalSorter; - class BtreeInMemoryState; + class IndexCatalogEntry; class ExternalSortComparison; class IndexDescriptor; class IndexDetails; @@ -59,10 +59,10 @@ namespace mongo { * Want to build an index? Call this. Throws DBException. */ static uint64_t fastBuildIndex(Collection* collection, - BtreeInMemoryState* descriptor, + IndexCatalogEntry* descriptor, bool mayInterrupt); - static DiskLoc makeEmptyIndex(BtreeInMemoryState* idx); + static DiskLoc makeEmptyIndex(IndexCatalogEntry* idx); static ExternalSortComparison* getComparison(int version, const BSONObj& keyPattern); @@ -89,7 +89,7 @@ namespace mongo { // Exposed for testing purposes. template< class V > void buildBottomUpPhases2And3( bool dupsAllowed, - BtreeInMemoryState* btreeState, + IndexCatalogEntry* btreeState, BSONObjExternalSorter& sorter, bool dropDups, set<DiskLoc>& dupsToDrop, diff --git a/src/mongo/db/index/btree_index_cursor.cpp b/src/mongo/db/index/btree_index_cursor.cpp index 19cf283e081..2072446d20a 100644 --- a/src/mongo/db/index/btree_index_cursor.cpp +++ b/src/mongo/db/index/btree_index_cursor.cpp @@ -43,7 +43,7 @@ namespace mongo { SimpleMutex BtreeIndexCursor::_activeCursorsMutex("active_btree_index_cursors"); // Go forward by default. - BtreeIndexCursor::BtreeIndexCursor(const BtreeInMemoryState* btreeState, + BtreeIndexCursor::BtreeIndexCursor(const IndexCatalogEntry* btreeState, BtreeInterface *interface) : _direction(1), _btreeState(btreeState), _interface(interface), _bucket(btreeState->head()), _keyOffset(0) { diff --git a/src/mongo/db/index/btree_index_cursor.h b/src/mongo/db/index/btree_index_cursor.h index c1fc45181d3..0b1fadcfba0 100644 --- a/src/mongo/db/index/btree_index_cursor.h +++ b/src/mongo/db/index/btree_index_cursor.h @@ -36,7 +36,6 @@ #include "mongo/db/index/btree_interface.h" #include "mongo/db/index/index_cursor.h" #include "mongo/db/index/index_descriptor.h" -#include "mongo/db/structure/btree/state.h" namespace mongo { @@ -86,7 +85,7 @@ namespace mongo { static SimpleMutex _activeCursorsMutex; // Go forward by default. - BtreeIndexCursor(const BtreeInMemoryState* btreeState, BtreeInterface *interface); + BtreeIndexCursor(const IndexCatalogEntry* btreeState, BtreeInterface *interface); void skipUnusedKeys(); @@ -102,7 +101,7 @@ namespace mongo { BSONObj _emptyObj; int _direction; - const BtreeInMemoryState* _btreeState; // not-owned + const IndexCatalogEntry* _btreeState; // not-owned BtreeInterface* _interface; // What are we looking at RIGHT NOW? We look at a bucket. diff --git a/src/mongo/db/index/btree_interface.cpp b/src/mongo/db/index/btree_interface.cpp index 448a6abf9f2..f5a741665d9 100644 --- a/src/mongo/db/index/btree_interface.cpp +++ b/src/mongo/db/index/btree_interface.cpp @@ -26,11 +26,11 @@ * it in the license file. */ -#include "mongo/db/structure/btree/btree.h" -#include "mongo/db/structure/btree/state.h" -#include "mongo/db/structure/btree/state-inl.h" +#include "mongo/db/catalog/index_catalog_entry.h" #include "mongo/db/index/btree_interface.h" #include "mongo/db/pdfile.h" +#include "mongo/db/structure/btree/btree.h" +#include "mongo/db/structure/record_store.h" namespace mongo { @@ -41,14 +41,24 @@ namespace mongo { virtual ~BtreeInterfaceImpl() { } - virtual int bt_insert(BtreeInMemoryState* btreeState, + const BtreeBucket<Version>* getHeadBucket( const IndexCatalogEntry* entry ) const { + return getBucket( entry->head() ); + } + + const BtreeBucket<Version>* getBucket( const IndexCatalogEntry* entry, + const DiskLoc& loc ) const { + Record* record = entry->recordStore()->recordFor( loc ); + return BtreeBucket<Version>::asVersion( record ); + } + + virtual int bt_insert(IndexCatalogEntry* btreeState, const DiskLoc thisLoc, const DiskLoc recordLoc, const BSONObj& key, bool dupsallowed, bool toplevel) { // FYI: toplevel has a default value of true in btree.h - return btreeState->getBucket<Version>(thisLoc)->bt_insert(btreeState, + return getBucket( btreeState, thisLoc )->bt_insert(btreeState, thisLoc, recordLoc, key, @@ -56,17 +66,17 @@ namespace mongo { toplevel); } - virtual bool unindex(BtreeInMemoryState* btreeState, + virtual bool unindex(IndexCatalogEntry* btreeState, const DiskLoc thisLoc, const BSONObj& key, const DiskLoc recordLoc) { - return btreeState->getBucket<Version>(thisLoc)->unindex(btreeState, + return getBucket( btreeState, thisLoc )->unindex(btreeState, thisLoc, key, recordLoc); } - virtual DiskLoc locate(const BtreeInMemoryState* btreeState, + virtual DiskLoc locate(const IndexCatalogEntry* btreeState, const DiskLoc& thisLoc, const BSONObj& key, int& pos, @@ -74,7 +84,7 @@ namespace mongo { const DiskLoc& recordLoc, int direction) const { // FYI: direction has a default of 1 - return btreeState->getBucket<Version>(thisLoc)->locate(btreeState, + return getBucket( btreeState, thisLoc )->locate(btreeState, thisLoc, key, pos, @@ -83,18 +93,18 @@ namespace mongo { direction); } - virtual bool wouldCreateDup(const BtreeInMemoryState* btreeState, + virtual bool wouldCreateDup(const IndexCatalogEntry* btreeState, const DiskLoc& thisLoc, const BSONObj& key, const DiskLoc& self) const { typename Version::KeyOwned ownedVersion(key); - return btreeState->getBucket<Version>(thisLoc)->wouldCreateDup(btreeState, + return getBucket( btreeState, thisLoc )->wouldCreateDup(btreeState, thisLoc, ownedVersion, self); } - virtual void customLocate(const BtreeInMemoryState* btreeState, + virtual void customLocate(const IndexCatalogEntry* btreeState, DiskLoc& locInOut, int& keyOfs, const BSONObj& keyBegin, @@ -114,7 +124,7 @@ namespace mongo { bestParent); } - virtual void advanceTo(const BtreeInMemoryState* btreeState, + virtual void advanceTo(const IndexCatalogEntry* btreeState, DiskLoc &thisLoc, int &keyOfs, const BSONObj &keyBegin, @@ -123,7 +133,7 @@ namespace mongo { const vector<const BSONElement*>& keyEnd, const vector<bool>& keyEndInclusive, int direction) const { - return btreeState->getBucket<Version>(thisLoc)->advanceTo(btreeState, + return getBucket( btreeState, thisLoc )->advanceTo(btreeState, thisLoc, keyOfs, keyBegin, @@ -176,26 +186,26 @@ namespace mongo { } } - virtual string dupKeyError(const BtreeInMemoryState* btreeState, + virtual string dupKeyError(const IndexCatalogEntry* btreeState, DiskLoc bucket, const BSONObj& keyObj) const { typename Version::KeyOwned key(keyObj); - return btreeState->getBucket<Version>( bucket )->dupKeyError(btreeState->descriptor(), - key); + return getBucket( btreeState, bucket )->dupKeyError(btreeState->descriptor(), + key); } - virtual DiskLoc advance(const BtreeInMemoryState* btreeState, + virtual DiskLoc advance(const IndexCatalogEntry* btreeState, const DiskLoc& thisLoc, int& keyOfs, int direction, const char* caller) const { - return btreeState->getBucket<Version>(thisLoc)->advance(thisLoc, keyOfs, direction, caller); + return getBucket( btreeState, thisLoc )->advance(thisLoc, keyOfs, direction, caller); } - virtual long long fullValidate(const BtreeInMemoryState* btreeState, + virtual long long fullValidate(const IndexCatalogEntry* btreeState, const DiskLoc& thisLoc, const BSONObj& keyPattern) { - return btreeState->getBucket<Version>(thisLoc)->fullValidate(thisLoc, keyPattern); + return getBucket( btreeState, thisLoc )->fullValidate(thisLoc, keyPattern); } }; diff --git a/src/mongo/db/index/btree_interface.h b/src/mongo/db/index/btree_interface.h index 9c468929920..37b5009a6ef 100644 --- a/src/mongo/db/index/btree_interface.h +++ b/src/mongo/db/index/btree_interface.h @@ -33,7 +33,7 @@ namespace mongo { - class BtreeInMemoryState; + class IndexCatalogEntry; /** * We have two Btree on-disk formats which support identical operations. We hide this as much @@ -51,19 +51,19 @@ namespace mongo { // was deleted. Calling code needs to be able to recognize this and possibly ignore it. static const int deletedBucketCode = 16738; - virtual int bt_insert(BtreeInMemoryState* btreeState, + virtual int bt_insert(IndexCatalogEntry* btreeState, const DiskLoc thisLoc, const DiskLoc recordLoc, const BSONObj& key, bool dupsallowed, bool toplevel = true) = 0; - virtual bool unindex(BtreeInMemoryState* btreeState, + virtual bool unindex(IndexCatalogEntry* btreeState, const DiskLoc thisLoc, const BSONObj& key, const DiskLoc recordLoc) = 0; - virtual DiskLoc locate(const BtreeInMemoryState* btreeState, + virtual DiskLoc locate(const IndexCatalogEntry* btreeState, const DiskLoc& thisLoc, const BSONObj& key, int& pos, // out @@ -71,12 +71,12 @@ namespace mongo { const DiskLoc& recordLoc, // out int direction = 1) const = 0; - virtual bool wouldCreateDup(const BtreeInMemoryState* btreeState, + virtual bool wouldCreateDup(const IndexCatalogEntry* btreeState, const DiskLoc& thisLoc, const BSONObj& key, const DiskLoc& self) const = 0; - virtual void customLocate(const BtreeInMemoryState* btreeState, + virtual void customLocate(const IndexCatalogEntry* btreeState, DiskLoc& locInOut, int& keyOfs, const BSONObj& keyBegin, @@ -86,7 +86,7 @@ namespace mongo { int direction, pair<DiskLoc, int>& bestParent) const = 0 ; - virtual void advanceTo(const BtreeInMemoryState* btreeState, + virtual void advanceTo(const IndexCatalogEntry* btreeState, DiskLoc &thisLoc, int &keyOfs, const BSONObj &keyBegin, @@ -96,17 +96,17 @@ namespace mongo { const vector<bool>& keyEndInclusive, int direction) const = 0; - virtual string dupKeyError(const BtreeInMemoryState* btreeState, + virtual string dupKeyError(const IndexCatalogEntry* btreeState, DiskLoc bucket, const BSONObj& keyObj) const =0; - virtual DiskLoc advance(const BtreeInMemoryState* btreeState, + virtual DiskLoc advance(const IndexCatalogEntry* btreeState, const DiskLoc& thisLoc, int& keyOfs, int direction, const char* caller) const = 0; - virtual long long fullValidate(const BtreeInMemoryState* btreeState, + virtual long long fullValidate(const IndexCatalogEntry* btreeState, const DiskLoc& thisLoc, const BSONObj& keyPattern) = 0; diff --git a/src/mongo/db/index/fts_access_method.cpp b/src/mongo/db/index/fts_access_method.cpp index 766c1a6789a..1aaadde4792 100644 --- a/src/mongo/db/index/fts_access_method.cpp +++ b/src/mongo/db/index/fts_access_method.cpp @@ -31,7 +31,7 @@ namespace mongo { - FTSAccessMethod::FTSAccessMethod(BtreeInMemoryState* btreeState) + FTSAccessMethod::FTSAccessMethod(IndexCatalogEntry* btreeState) : BtreeBasedAccessMethod(btreeState), _ftsSpec(btreeState->descriptor()->infoObj()) { } void FTSAccessMethod::getKeys(const BSONObj& obj, BSONObjSet* keys) { diff --git a/src/mongo/db/index/fts_access_method.h b/src/mongo/db/index/fts_access_method.h index 721b5f33b83..eceff2ae3b9 100644 --- a/src/mongo/db/index/fts_access_method.h +++ b/src/mongo/db/index/fts_access_method.h @@ -38,7 +38,7 @@ namespace mongo { class FTSAccessMethod : public BtreeBasedAccessMethod { public: - FTSAccessMethod(BtreeInMemoryState* btreeState ); + FTSAccessMethod(IndexCatalogEntry* btreeState ); virtual ~FTSAccessMethod() { } // Not implemented: diff --git a/src/mongo/db/index/hash_access_method.cpp b/src/mongo/db/index/hash_access_method.cpp index 2752b061f74..3aff284d11e 100644 --- a/src/mongo/db/index/hash_access_method.cpp +++ b/src/mongo/db/index/hash_access_method.cpp @@ -37,7 +37,7 @@ namespace mongo { return BSONElementHasher::hash64(e, seed); } - HashAccessMethod::HashAccessMethod(BtreeInMemoryState* btreeState) + HashAccessMethod::HashAccessMethod(IndexCatalogEntry* btreeState) : BtreeBasedAccessMethod(btreeState) { const IndexDescriptor* descriptor = btreeState->descriptor(); diff --git a/src/mongo/db/index/hash_access_method.h b/src/mongo/db/index/hash_access_method.h index a93fa6a3964..3fdff0e2b7d 100644 --- a/src/mongo/db/index/hash_access_method.h +++ b/src/mongo/db/index/hash_access_method.h @@ -45,7 +45,7 @@ namespace mongo { public: using BtreeBasedAccessMethod::_descriptor; - HashAccessMethod(BtreeInMemoryState* btreeState); + HashAccessMethod(IndexCatalogEntry* btreeState); virtual ~HashAccessMethod() { } virtual Status newCursor(IndexCursor** out) const; diff --git a/src/mongo/db/index/haystack_access_method.cpp b/src/mongo/db/index/haystack_access_method.cpp index d67be2e506b..aaddea81207 100644 --- a/src/mongo/db/index/haystack_access_method.cpp +++ b/src/mongo/db/index/haystack_access_method.cpp @@ -39,7 +39,7 @@ namespace mongo { static const string GEOSEARCHNAME = "geoHaystack"; - HaystackAccessMethod::HaystackAccessMethod(BtreeInMemoryState* btreeState) + HaystackAccessMethod::HaystackAccessMethod(IndexCatalogEntry* btreeState) : BtreeBasedAccessMethod(btreeState) { const IndexDescriptor* descriptor = btreeState->descriptor(); diff --git a/src/mongo/db/index/haystack_access_method.h b/src/mongo/db/index/haystack_access_method.h index 37c5d1a1270..e24e10f7df9 100644 --- a/src/mongo/db/index/haystack_access_method.h +++ b/src/mongo/db/index/haystack_access_method.h @@ -55,7 +55,7 @@ namespace mongo { public: using BtreeBasedAccessMethod::_descriptor; - HaystackAccessMethod(BtreeInMemoryState* btreeState); + HaystackAccessMethod(IndexCatalogEntry* btreeState); virtual ~HaystackAccessMethod() { } // Not implemented. diff --git a/src/mongo/db/index/s2_access_method.cpp b/src/mongo/db/index/s2_access_method.cpp index 11ceb4566ab..db1b429cac4 100644 --- a/src/mongo/db/index/s2_access_method.cpp +++ b/src/mongo/db/index/s2_access_method.cpp @@ -44,7 +44,7 @@ namespace mongo { return def; } - S2AccessMethod::S2AccessMethod(BtreeInMemoryState* btreeState) + S2AccessMethod::S2AccessMethod(IndexCatalogEntry* btreeState) : BtreeBasedAccessMethod(btreeState) { const IndexDescriptor* descriptor = btreeState->descriptor(); diff --git a/src/mongo/db/index/s2_access_method.h b/src/mongo/db/index/s2_access_method.h index b3a34b4e679..66c091f3e90 100644 --- a/src/mongo/db/index/s2_access_method.h +++ b/src/mongo/db/index/s2_access_method.h @@ -43,7 +43,7 @@ namespace mongo { public: using BtreeBasedAccessMethod::_descriptor; - S2AccessMethod(BtreeInMemoryState* btreeState); + S2AccessMethod(IndexCatalogEntry* btreeState); virtual ~S2AccessMethod() { } virtual Status newCursor(IndexCursor** out) const; diff --git a/src/mongo/db/namespace_details.h b/src/mongo/db/namespace_details.h index 29854891bff..48c8e54db60 100644 --- a/src/mongo/db/namespace_details.h +++ b/src/mongo/db/namespace_details.h @@ -42,7 +42,7 @@ #include "mongo/platform/unordered_map.h" namespace mongo { - class BtreeInMemoryState; + class IndexCatalogEntry; class Database; class IndexCatalog; @@ -424,7 +424,7 @@ namespace mongo { friend class Database; friend class NamespaceIndex; friend class IndexCatalog; - friend class BtreeInMemoryState; + friend class IndexCatalogEntry; struct ExtraOld { // note we could use this field for more chaining later, so don't waste it: diff --git a/src/mongo/db/structure/btree/btree.cpp b/src/mongo/db/structure/btree/btree.cpp index 9acdc88de79..a1ebd9da6d1 100644 --- a/src/mongo/db/structure/btree/btree.cpp +++ b/src/mongo/db/structure/btree/btree.cpp @@ -34,7 +34,6 @@ #include "mongo/db/structure/btree/btree_stats.h" #include "mongo/db/structure/btree/btreebuilder.h" -#include "mongo/db/structure/btree/state-inl.h" #include "mongo/db/client.h" #include "mongo/db/clientcursor.h" #include "mongo/db/curop-inl.h" @@ -689,7 +688,7 @@ namespace mongo { } template< class V > - bool BtreeBucket<V>::exists(const BtreeInMemoryState* btreeState, + bool BtreeBucket<V>::exists(const IndexCatalogEntry* btreeState, const DiskLoc &thisLoc, const Key& key ) const { int pos; @@ -710,7 +709,7 @@ namespace mongo { } template< class V > - bool BtreeBucket<V>::wouldCreateDup(const BtreeInMemoryState* btreeState, + bool BtreeBucket<V>::wouldCreateDup(const IndexCatalogEntry* btreeState, const DiskLoc& thisLoc, const Key& key, const DiskLoc& self) const { @@ -720,7 +719,8 @@ namespace mongo { while ( !b.isNull() ) { // we skip unused keys - const BtreeBucket *bucket = btreeState->getBucket<V>( b ); + Record* record = btreeState->recordStore()->recordFor( b ); + const BtreeBucket *bucket = asVersion( record ); const _KeyNode& kn = bucket->k(pos); if ( kn.isUsed() ) { if( bucket->keyAt(pos).woEqual(key) ) @@ -759,7 +759,7 @@ namespace mongo { bool guessIncreasing = false; template< class V > - bool BtreeBucket<V>::find(const BtreeInMemoryState* btreeState, + bool BtreeBucket<V>::find(const IndexCatalogEntry* btreeState, const Key& key, const DiskLoc &rl, int& pos, @@ -839,7 +839,7 @@ namespace mongo { } template< class V > - void BtreeBucket<V>::delBucket(BtreeInMemoryState* btreeState, const DiskLoc thisLoc ) { + void BtreeBucket<V>::delBucket(IndexCatalogEntry* btreeState, const DiskLoc thisLoc ) { BtreeIndexCursor::aboutToDeleteBucket(thisLoc); verify( !isHead() ); @@ -851,7 +851,7 @@ namespace mongo { } template< class V > - void BtreeBucket<V>::deallocBucket(BtreeInMemoryState* btreeState, const DiskLoc thisLoc ) { + void BtreeBucket<V>::deallocBucket(IndexCatalogEntry* btreeState, const DiskLoc thisLoc ) { // Mark the bucket as deallocated, see SERVER-4575. this->n = this->INVALID_N_SENTINEL; // defensive: @@ -861,7 +861,7 @@ namespace mongo { /** note: may delete the entire bucket! this invalid upon return sometimes. */ template< class V > - void BtreeBucket<V>::delKeyAtPos(BtreeInMemoryState* btreeState, + void BtreeBucket<V>::delKeyAtPos(IndexCatalogEntry* btreeState, const DiskLoc thisLoc, int p ) { verify(this->n>0); DiskLoc left = this->childForPos(p); @@ -923,7 +923,7 @@ namespace mongo { * expected to mark a key as unused when handling a legacy btree. */ template< class V > - void BtreeBucket<V>::deleteInternalKey(BtreeInMemoryState* btreeState, + void BtreeBucket<V>::deleteInternalKey(IndexCatalogEntry* btreeState, const DiskLoc thisLoc, int keypos ) { DiskLoc lchild = this->childForPos( keypos ); @@ -958,7 +958,12 @@ namespace mongo { #define BTREEMOD(loc) (loc.template btreemod<V>()) template< class V > - void BtreeBucket<V>::replaceWithNextChild( BtreeInMemoryState* btreeState, + const BtreeBucket<V>* BtreeBucket<V>::asVersion( Record* rec ) { + return reinterpret_cast< BtreeBucket<V>* >( rec->data() ); + } + + template< class V > + void BtreeBucket<V>::replaceWithNextChild( IndexCatalogEntry* btreeState, const DiskLoc thisLoc ) { verify( this->n == 0 && !this->nextChild.isNull() ); if ( this->parent.isNull() ) { @@ -1044,7 +1049,7 @@ namespace mongo { } template< class V > - void BtreeBucket<V>::doMergeChildren( BtreeInMemoryState* btreeState, + void BtreeBucket<V>::doMergeChildren( IndexCatalogEntry* btreeState, const DiskLoc thisLoc, int leftIndex ) { DiskLoc leftNodeLoc = this->childForPos( leftIndex ); @@ -1109,7 +1114,7 @@ namespace mongo { } template< class V > - bool BtreeBucket<V>::tryBalanceChildren( BtreeInMemoryState* btreeState, + bool BtreeBucket<V>::tryBalanceChildren( IndexCatalogEntry* btreeState, const DiskLoc thisLoc, int leftIndex ) const { // If we can merge, then we must merge rather than balance to preserve @@ -1122,7 +1127,7 @@ namespace mongo { } template< class V > - void BtreeBucket<V>::doBalanceLeftToRight( BtreeInMemoryState* btreeState, + void BtreeBucket<V>::doBalanceLeftToRight( IndexCatalogEntry* btreeState, const DiskLoc thisLoc, int leftIndex, int split, BtreeBucket *l, const DiskLoc lchild, BtreeBucket *r, const DiskLoc rchild ) { @@ -1157,7 +1162,7 @@ namespace mongo { } template< class V > - void BtreeBucket<V>::doBalanceRightToLeft( BtreeInMemoryState* btreeState, + void BtreeBucket<V>::doBalanceRightToLeft( IndexCatalogEntry* btreeState, const DiskLoc thisLoc, int leftIndex, int split, BtreeBucket *l, const DiskLoc lchild, BtreeBucket *r, const DiskLoc rchild ) { @@ -1192,7 +1197,7 @@ namespace mongo { } template< class V > - void BtreeBucket<V>::doBalanceChildren( BtreeInMemoryState* btreeState, + void BtreeBucket<V>::doBalanceChildren( IndexCatalogEntry* btreeState, const DiskLoc thisLoc, int leftIndex ) { DiskLoc lchild = this->childForPos( leftIndex ); @@ -1216,7 +1221,7 @@ namespace mongo { } template< class V > - bool BtreeBucket<V>::mayBalanceWithNeighbors(BtreeInMemoryState* btreeState, + bool BtreeBucket<V>::mayBalanceWithNeighbors(IndexCatalogEntry* btreeState, const DiskLoc thisLoc ) { if ( this->parent.isNull() ) { // we are root, there are no neighbors return false; @@ -1260,7 +1265,7 @@ namespace mongo { /** remove a key from the index */ template< class V > - bool BtreeBucket<V>::unindex(BtreeInMemoryState* btreeState, + bool BtreeBucket<V>::unindex(IndexCatalogEntry* btreeState, const DiskLoc thisLoc, const BSONObj& key, const DiskLoc recordLoc) const { @@ -1299,7 +1304,7 @@ namespace mongo { } template< class V > - void BtreeBucket<V>::setInternalKey( BtreeInMemoryState* btreeState, + void BtreeBucket<V>::setInternalKey( IndexCatalogEntry* btreeState, const DiskLoc thisLoc, int keypos, const DiskLoc recordLoc, @@ -1333,7 +1338,7 @@ namespace mongo { * the optimized write intent code in basicInsert(). */ template< class V > - void BtreeBucket<V>::insertHere( BtreeInMemoryState* btreeState, + void BtreeBucket<V>::insertHere( IndexCatalogEntry* btreeState, const DiskLoc thisLoc, int keypos, const DiskLoc recordLoc, const Key& key, const DiskLoc lchild, const DiskLoc rchild ) const { @@ -1389,7 +1394,7 @@ namespace mongo { } template< class V > - void BtreeBucket<V>::split(BtreeInMemoryState* btreeState, + void BtreeBucket<V>::split(IndexCatalogEntry* btreeState, const DiskLoc thisLoc, int keypos, const DiskLoc recordLoc, const Key& key, const DiskLoc lchild, const DiskLoc rchild) { @@ -1482,7 +1487,7 @@ namespace mongo { /** start a new index off, empty */ template< class V > - DiskLoc BtreeBucket<V>::addBucket(BtreeInMemoryState* btreeState) { + DiskLoc BtreeBucket<V>::addBucket(IndexCatalogEntry* btreeState) { DummyDocWriter docWriter( V::BucketSize ); StatusWith<DiskLoc> loc = btreeState->recordStore()->insertRecord( &docWriter, 0 ); uassertStatusOK( loc.getStatus() ); @@ -1550,7 +1555,7 @@ namespace mongo { } template< class V > - DiskLoc BtreeBucket<V>::locate(const BtreeInMemoryState* btreeState, + DiskLoc BtreeBucket<V>::locate(const IndexCatalogEntry* btreeState, const DiskLoc& thisLoc, const BSONObj& key, int& pos, @@ -1562,7 +1567,7 @@ namespace mongo { } template< class V > - DiskLoc BtreeBucket<V>::locate(const BtreeInMemoryState* btreeState, + DiskLoc BtreeBucket<V>::locate(const IndexCatalogEntry* btreeState, const DiskLoc& thisLoc, const Key& key, int& pos, @@ -1632,7 +1637,7 @@ namespace mongo { * All the direction checks below allowed me to refactor the code, but possibly separate forward and reverse implementations would be more efficient */ template< class V > - void BtreeBucket<V>::advanceTo(const BtreeInMemoryState* btreeState, + void BtreeBucket<V>::advanceTo(const IndexCatalogEntry* btreeState, DiskLoc &thisLoc, int &keyOfs, const BSONObj &keyBegin, @@ -1694,7 +1699,7 @@ namespace mongo { as advanceTo. */ template< class V > - void BtreeBucket<V>::customLocate(const BtreeInMemoryState* btreeState, + void BtreeBucket<V>::customLocate(const IndexCatalogEntry* btreeState, DiskLoc& locInOut, int& keyOfs, const BSONObj& keyBegin, @@ -1777,7 +1782,7 @@ namespace mongo { /** @thisLoc disk location of *this */ template< class V > - int BtreeBucket<V>::_insert(BtreeInMemoryState* btreeState, + int BtreeBucket<V>::_insert(IndexCatalogEntry* btreeState, const DiskLoc thisLoc, const DiskLoc recordLoc, const Key& key, bool dupsAllowed, const DiskLoc lChild, const DiskLoc rChild ) const { @@ -1859,7 +1864,7 @@ namespace mongo { /** todo: meaning of return code unclear clean up */ template< class V > - int BtreeBucket<V>::bt_insert(BtreeInMemoryState* btreeState, + int BtreeBucket<V>::bt_insert(IndexCatalogEntry* btreeState, const DiskLoc thisLoc, const DiskLoc recordLoc, const BSONObj& keyBson, @@ -1905,7 +1910,7 @@ namespace mongo { } template< class V > - DiskLoc BtreeBucket<V>::findSingle( const BtreeInMemoryState* btreeState, + DiskLoc BtreeBucket<V>::findSingle( const IndexCatalogEntry* btreeState, const DiskLoc& thisLoc, const BSONObj& key ) const { int pos; diff --git a/src/mongo/db/structure/btree/btree.h b/src/mongo/db/structure/btree/btree.h index b83b85fe97b..8f3f87e889d 100644 --- a/src/mongo/db/structure/btree/btree.h +++ b/src/mongo/db/structure/btree/btree.h @@ -41,7 +41,7 @@ namespace mongo { - class BtreeInMemoryState; + class IndexCatalogEntry; class IndexDescriptor; /** @@ -653,6 +653,9 @@ namespace mongo { protected: _KeyNode& k(int i) { return static_cast< BucketBasics<V> * >(this)->_k(i); } public: + + static const BtreeBucket<V>* asVersion( Record* rec ); + const KeyNode keyNode(int i) const { return static_cast< const BucketBasics<V> * >(this)->keyNode(i); } bool isHead() const { return this->parent.isNull(); } @@ -671,14 +674,14 @@ namespace mongo { * likewise below in bt_insert() etc. */ private: - bool exists(const BtreeInMemoryState* btreeState, const DiskLoc &thisLoc, const Key& key ) const; + bool exists(const IndexCatalogEntry* btreeState, const DiskLoc &thisLoc, const Key& key ) const; public: /** * @param self - Don't complain about ourself already being in the index case. * @return true = There is a duplicate used key. */ - bool wouldCreateDup(const BtreeInMemoryState* btreeState, + bool wouldCreateDup(const IndexCatalogEntry* btreeState, const DiskLoc& thisLoc, const Key& key, const DiskLoc& self) const; @@ -689,7 +692,7 @@ namespace mongo { * and init()-ed. This bucket is suitable to for use as a new root * or any other new node in the tree. */ - static DiskLoc addBucket(BtreeInMemoryState* btreeState); + static DiskLoc addBucket(IndexCatalogEntry* btreeState); /** * Preconditions: none @@ -698,7 +701,7 @@ namespace mongo { * deallocated from pdfile storage. * - The memory at thisLoc is invalidated, and 'this' is invalidated. */ - void deallocBucket(BtreeInMemoryState* btreeState, const DiskLoc thisLoc ); + void deallocBucket(IndexCatalogEntry* btreeState, const DiskLoc thisLoc ); /** * Preconditions: @@ -714,7 +717,7 @@ namespace mongo { * and @return 0. The root of the btree may be changed, so * 'this'/thisLoc may no longer be the root upon return. */ - int bt_insert(BtreeInMemoryState* btreeState, + int bt_insert(IndexCatalogEntry* btreeState, const DiskLoc thisLoc, const DiskLoc recordLoc, const BSONObj& key, @@ -729,7 +732,7 @@ namespace mongo { * invalidate 'this' / thisLoc and change the head. * - If key / recordLoc are not in the btree, @return false and do nothing. */ - bool unindex(BtreeInMemoryState* btreeState, + bool unindex(IndexCatalogEntry* btreeState, const DiskLoc thisLoc, const BSONObj& key, const DiskLoc recordLoc) const; @@ -741,7 +744,7 @@ namespace mongo { * @found - returns true if exact match found. note you can get back a position * result even if found is false. */ - DiskLoc locate(const BtreeInMemoryState* btreeState, + DiskLoc locate(const IndexCatalogEntry* btreeState, const DiskLoc& thisLoc, const BSONObj& key, int& pos, @@ -749,7 +752,7 @@ namespace mongo { const DiskLoc& recordLoc, int direction=1) const; - DiskLoc locate(const BtreeInMemoryState* btreeState, + DiskLoc locate(const IndexCatalogEntry* btreeState, const DiskLoc& thisLoc, const Key& key, int& pos, @@ -764,7 +767,7 @@ namespace mongo { * findSingle code. * @return the record location of the first match */ - DiskLoc findSingle( const BtreeInMemoryState* btreeState, + DiskLoc findSingle( const IndexCatalogEntry* btreeState, const DiskLoc& thisLoc, const BSONObj& key ) const; @@ -775,7 +778,7 @@ namespace mongo { DiskLoc advance(const DiskLoc& thisLoc, int& keyOfs, int direction, const char *caller) const; /** Advance in specified direction to the specified key */ - void advanceTo(const BtreeInMemoryState* btreeState, + void advanceTo(const IndexCatalogEntry* btreeState, DiskLoc &thisLoc, int &keyOfs, const BSONObj &keyBegin, @@ -786,7 +789,7 @@ namespace mongo { int direction) const; /** Locate a key with fields comprised of a combination of keyBegin fields and keyEnd fields. */ - static void customLocate(const BtreeInMemoryState* btreeState, + static void customLocate(const IndexCatalogEntry* btreeState, DiskLoc& locInOut, int& keyOfs, const BSONObj& keyBegin, @@ -825,7 +828,7 @@ namespace mongo { * - This bucket is deallocated from pdfile storage. * - 'this' and thisLoc are invalidated. */ - void delBucket(BtreeInMemoryState* btreeState, const DiskLoc thisLoc ); + void delBucket(IndexCatalogEntry* btreeState, const DiskLoc thisLoc ); /** * Preconditions: 0 <= p < n @@ -834,7 +837,7 @@ namespace mongo { * - 'this' and thisLoc may be invalidated. * - The tree head may change. */ - void delKeyAtPos(BtreeInMemoryState* btreeSate, + void delKeyAtPos(IndexCatalogEntry* btreeSate, const DiskLoc thisLoc, int p ); @@ -848,7 +851,7 @@ namespace mongo { * or merge with them and return true. Also, 'this' and thisLoc may * be invalidated and the tree head may change. */ - bool mayBalanceWithNeighbors(BtreeInMemoryState* btreeState, const DiskLoc thisLoc); + bool mayBalanceWithNeighbors(IndexCatalogEntry* btreeState, const DiskLoc thisLoc); /** * Preconditions: @@ -861,7 +864,7 @@ namespace mongo { * - Otherwise, balance keys between the leftIndex child and the * leftIndex + 1 child, return true, and possibly change the tree head. */ - bool tryBalanceChildren(BtreeInMemoryState* btreeState, const DiskLoc thisLoc, int leftIndex) const; + bool tryBalanceChildren(IndexCatalogEntry* btreeState, const DiskLoc thisLoc, int leftIndex) const; /** * Preconditions: @@ -872,7 +875,7 @@ namespace mongo { * child such that neither child has fewer than lowWaterMark bytes. * The tree head may change. */ - void doBalanceChildren( BtreeInMemoryState* btreeState, const DiskLoc thisLoc, int leftIndex ); + void doBalanceChildren( IndexCatalogEntry* btreeState, const DiskLoc thisLoc, int leftIndex ); /** * Preconditions: @@ -886,7 +889,7 @@ namespace mongo { * The previous key in thisLoc at index leftIndex and all keys with * indexes greater than split in lchild are moved to rchild. */ - void doBalanceLeftToRight( BtreeInMemoryState* btreeState, + void doBalanceLeftToRight( IndexCatalogEntry* btreeState, const DiskLoc thisLoc, int leftIndex, int split, BtreeBucket<V> *l, const DiskLoc lchild, BtreeBucket<V> *r, const DiskLoc rchild ); @@ -903,7 +906,7 @@ namespace mongo { * with indexes less than split - l->n - 1 in rchild are moved to * lchild. */ - void doBalanceRightToLeft( BtreeInMemoryState* btreeState, + void doBalanceRightToLeft( IndexCatalogEntry* btreeState, const DiskLoc thisLoc, int leftIndex, int split, BtreeBucket<V> *l, const DiskLoc lchild, BtreeBucket<V> *r, const DiskLoc rchild ); @@ -917,7 +920,7 @@ namespace mongo { * - The tree may be updated recursively, resulting in 'this' and * thisLoc being invalidated and the tree head being changed. */ - void doMergeChildren(BtreeInMemoryState* btreeState,const DiskLoc thisLoc, int leftIndex ); + void doMergeChildren(IndexCatalogEntry* btreeState,const DiskLoc thisLoc, int leftIndex ); /** * Preconditions: @@ -928,7 +931,7 @@ namespace mongo { * to them are updated, and the tree head may change. * - nextChild replaces thisLoc in the btree structure. */ - void replaceWithNextChild( BtreeInMemoryState* btreeState, const DiskLoc thisLoc ); + void replaceWithNextChild( IndexCatalogEntry* btreeState, const DiskLoc thisLoc ); /** * @return true iff the leftIndex and leftIndex + 1 children both exist, @@ -975,7 +978,7 @@ namespace mongo { * into one of the split buckets, and lchild/rchild set appropriately. * Splitting may occur recursively, possibly changing the tree head. */ - void split(BtreeInMemoryState* btreeState, + void split(IndexCatalogEntry* btreeState, const DiskLoc thisLoc, int keypos, const DiskLoc recordLoc, const Key& key, const DiskLoc lchild, const DiskLoc rchild); @@ -996,18 +999,18 @@ namespace mongo { * This function will always modify thisLoc, but it's marked const because * it commonly relies on the specialized writ]e intent mechanism of basicInsert(). */ - void insertHere(BtreeInMemoryState* btreeState, + void insertHere(IndexCatalogEntry* btreeState, const DiskLoc thisLoc, int keypos, const DiskLoc recordLoc, const Key& key, const DiskLoc lchild, const DiskLoc rchild ) const; /** bt_insert() is basically just a wrapper around this. */ - int _insert(BtreeInMemoryState* btreeState, + int _insert(IndexCatalogEntry* btreeState, const DiskLoc thisLoc, const DiskLoc recordLoc, const Key& key, bool dupsallowed, const DiskLoc lChild, const DiskLoc rChild ) const; - bool find(const BtreeInMemoryState* btreeState, + bool find(const IndexCatalogEntry* btreeState, const Key& key, const DiskLoc &recordLoc, int& pos, @@ -1034,7 +1037,7 @@ namespace mongo { * head. * - childForPos( keypos ) will be orphaned. */ - void setInternalKey( BtreeInMemoryState* btreeState, + void setInternalKey( IndexCatalogEntry* btreeState, const DiskLoc thisLoc, int keypos, const DiskLoc recordLoc, @@ -1055,7 +1058,7 @@ namespace mongo { * - If the key cannot be replaced, it will be marked as unused. This * is only expected in legacy btrees. */ - void deleteInternalKey( BtreeInMemoryState* btreeState, const DiskLoc thisLoc, int keypos ); + void deleteInternalKey( IndexCatalogEntry* btreeState, const DiskLoc thisLoc, int keypos ); public: /** simply builds and returns a dup key error message string */ static string dupKeyError( const IndexDescriptor* idx , const Key& key ); diff --git a/src/mongo/db/structure/btree/btreebuilder.cpp b/src/mongo/db/structure/btree/btreebuilder.cpp index c1378d4a8ae..1cf32d9bd63 100644 --- a/src/mongo/db/structure/btree/btreebuilder.cpp +++ b/src/mongo/db/structure/btree/btreebuilder.cpp @@ -44,14 +44,13 @@ #include "mongo/db/repl/is_master.h" #include "mongo/db/stats/counters.h" #include "mongo/db/structure/btree/btree.h" -#include "mongo/db/structure/btree/state.h" namespace mongo { /* --- BtreeBuilder --- */ template<class V> - BtreeBuilder<V>::BtreeBuilder(bool dupsAllowed, BtreeInMemoryState* btreeState ): + BtreeBuilder<V>::BtreeBuilder(bool dupsAllowed, IndexCatalogEntry* btreeState ): _dupsAllowed(dupsAllowed), _btreeState(btreeState), _numAdded(0) { diff --git a/src/mongo/db/structure/btree/btreebuilder.h b/src/mongo/db/structure/btree/btreebuilder.h index c98ef59a6e7..154c0de6c49 100644 --- a/src/mongo/db/structure/btree/btreebuilder.h +++ b/src/mongo/db/structure/btree/btreebuilder.h @@ -32,7 +32,7 @@ namespace mongo { - class BtreeInMemoryState; + class IndexCatalogEntry; /** * build btree from the bottom up @@ -43,7 +43,7 @@ namespace mongo { typedef typename V::Key Key; bool _dupsAllowed; - BtreeInMemoryState* _btreeState; + IndexCatalogEntry* _btreeState; /** Number of keys added to btree. */ unsigned long long _numAdded; @@ -61,7 +61,7 @@ namespace mongo { void mayCommitProgressDurably(); public: - BtreeBuilder(bool dupsAllowed, BtreeInMemoryState* idx); + BtreeBuilder(bool dupsAllowed, IndexCatalogEntry* idx); /** * Preconditions: 'key' is > or >= last key passed to this function (depends on _dupsAllowed) diff --git a/src/mongo/db/structure/btree/state-inl.h b/src/mongo/db/structure/btree/state-inl.h deleted file mode 100644 index 4a3271c1bb6..00000000000 --- a/src/mongo/db/structure/btree/state-inl.h +++ /dev/null @@ -1,45 +0,0 @@ -// state-inl.h - -/** -* Copyright (C) 2008 10gen Inc. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License, version 3, -* as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -* -* As a special exception, the copyright holders give permission to link the -* code of portions of this program with the OpenSSL library under certain -* conditions as described in each individual source file and distribute -* linked combinations including the program with the OpenSSL library. You -* must comply with the GNU Affero General Public License in all respects for -* all of the code used other than as permitted herein. If you modify file(s) -* with this exception, you may extend this exception to your version of the -* file(s), but you are not obligated to do so. If you do not wish to do so, -* delete this exception statement from your version. If you delete this -* exception statement from all source files in the program, then also delete -* it in the license file. -*/ - -#include "mongo/db/memconcept.h" -#include "mongo/db/pdfile.h" // XXX-ERH :( -#include "mongo/db/structure/btree/state.h" -#include "mongo/db/structure/record_store.h" - -namespace mongo { - - template< class V > - const BtreeBucket<V>* BtreeInMemoryState::getBucket( const DiskLoc& loc ) const { - Record* record = _recordStore->recordFor( loc ); - memconcept::is(record, memconcept::concept::btreebucket, "", 8192); - return reinterpret_cast<const BtreeBucket<V>*>( record->data() ); - } - -} diff --git a/src/mongo/db/structure/btree/state.cpp b/src/mongo/db/structure/btree/state.cpp deleted file mode 100644 index 3a8bfbb7daa..00000000000 --- a/src/mongo/db/structure/btree/state.cpp +++ /dev/null @@ -1,140 +0,0 @@ -// state.cpp - -/** -* Copyright (C) 2008 10gen Inc. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License, version 3, -* as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -* -* As a special exception, the copyright holders give permission to link the -* code of portions of this program with the OpenSSL library under certain -* conditions as described in each individual source file and distribute -* linked combinations including the program with the OpenSSL library. You -* must comply with the GNU Affero General Public License in all respects for -* all of the code used other than as permitted herein. If you modify file(s) -* with this exception, you may extend this exception to your version of the -* file(s), but you are not obligated to do so. If you do not wish to do so, -* delete this exception statement from your version. If you delete this -* exception statement from all source files in the program, then also delete -* it in the license file. -*/ - -#include "mongo/db/structure/btree/state.h" - -#include "mongo/db/index/index_descriptor.h" -#include "mongo/db/pdfile.h" -#include "mongo/db/storage/extent_manager.h" -#include "mongo/db/structure/record_store.h" - -namespace mongo { - - BtreeInMemoryState::BtreeInMemoryState( Collection* collection, - const IndexDescriptor* descriptor, - RecordStore* recordStore ) - : _collection( collection ), - _descriptor( descriptor ), - _recordStore( recordStore ), - _ordering( Ordering::make( descriptor->keyPattern() ) ) { - _isReady = false; - _isMultikeySet = false; - _head.Null(); - } - - int BtreeInMemoryState::_indexNo() const { - NamespaceDetails* nsd = _collection->details(); - int idxNo = nsd->_catalogFindIndexByName( _descriptor->indexName(), true ); - fassert( 17333, idxNo >= 0 ); - return idxNo; - } - - const DiskLoc& BtreeInMemoryState::head() const { - if ( _head.isNull() ) { - _head = _catalogFindHeadFromDisk(); - return _head; - } - - DEV { - if ( _head != _catalogFindHeadFromDisk() ) { - log() << "_head: " << _head - << " _catalogFindHeadFromDisk(): " << _catalogFindHeadFromDisk(); - } - verify( _head == _catalogFindHeadFromDisk() ); - } - - return _head; - } - - DiskLoc BtreeInMemoryState::_catalogFindHeadFromDisk() const { - NamespaceDetails* nsd = _collection->details(); - int idxNo = _indexNo(); - return nsd->idx( idxNo ).head; - } - - void BtreeInMemoryState::setHead( DiskLoc newHead ) { - NamespaceDetails* nsd = _collection->details(); - int idxNo = _indexNo(); - IndexDetails& id = nsd->idx( idxNo ); - id.head.writing() = newHead; - _head = newHead; - } - - void BtreeInMemoryState::setMultikey() { - NamespaceDetails* nsd = _collection->details(); - int idxNo = _indexNo(); - if ( nsd->setIndexIsMultikey( idxNo, true ) ) - _collection->infoCache()->clearQueryCache(); - - _isMultikeySet = true; - _isMultikey = true; - } - - bool BtreeInMemoryState::isMultikey() const { - if ( _isMultikeySet ) { - DEV { - NamespaceDetails* nsd = _collection->details(); - int idxNo = _indexNo(); - verify( _isMultikey == nsd->isMultikey( idxNo ) ); - } - return _isMultikey; - } - - NamespaceDetails* nsd = _collection->details(); - int idxNo = _indexNo(); - _isMultikey = nsd->isMultikey( idxNo ); - _isMultikeySet = true; - return _isMultikey; - } - - - bool BtreeInMemoryState::isReady() const { - DEV _debugCheckVerifyReady(); - return _isReady; - } - - void BtreeInMemoryState::setIsReady( bool isReady ) { - _isReady = isReady; - DEV _debugCheckVerifyReady(); - if ( isReady ) { - // get caches ready - head(); - isMultikey(); - - fassert( 17339, _head == _catalogFindHeadFromDisk() ); - fassert( 17340, _isMultikey == _collection->details()->isMultikey( _indexNo() ) ); - } - } - - void BtreeInMemoryState::_debugCheckVerifyReady() const { - bool real = _indexNo() < _collection->getIndexCatalog()->numIndexesReady(); - verify( real == _isReady ); - } -} diff --git a/src/mongo/db/structure/btree/state.h b/src/mongo/db/structure/btree/state.h deleted file mode 100644 index be190060e05..00000000000 --- a/src/mongo/db/structure/btree/state.h +++ /dev/null @@ -1,122 +0,0 @@ -// state.h - -/** -* Copyright (C) 2008 10gen Inc. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License, version 3, -* as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -* -* As a special exception, the copyright holders give permission to link the -* code of portions of this program with the OpenSSL library under certain -* conditions as described in each individual source file and distribute -* linked combinations including the program with the OpenSSL library. You -* must comply with the GNU Affero General Public License in all respects for -* all of the code used other than as permitted herein. If you modify file(s) -* with this exception, you may extend this exception to your version of the -* file(s), but you are not obligated to do so. If you do not wish to do so, -* delete this exception statement from your version. If you delete this -* exception statement from all source files in the program, then also delete -* it in the license file. -*/ - -#pragma once - -#include "mongo/base/disallow_copying.h" -#include "mongo/db/diskloc.h" -#include "mongo/db/jsobj.h" -#include "mongo/bson/ordering.h" - -namespace mongo { - - class Collection; - class IndexCatalog; - class IndexDetails; - class IndexDescriptor; - class RecordStore; - - /** - * This class is maybe temporary, and terribly named - * its goal is to keep the state and data structure associated with a btree in one place - * previously, the btree code called back out of its world through globals, which is bad - * the goal here is to make the btree at least a sane visitorish pattern - * so this is passed to each method, and it can be operated on - * long term, the containmenent should be flipped - */ - class BtreeInMemoryState { - MONGO_DISALLOW_COPYING( BtreeInMemoryState ); - public: - BtreeInMemoryState( Collection* collection, - const IndexDescriptor* descriptor, - RecordStore* recordStore ); - - const Collection* collection() const { return _collection; } - - const IndexDescriptor* descriptor() const { return _descriptor; } - const Ordering& ordering() const { return _ordering; } - - RecordStore* recordStore() { return _recordStore.get(); } - const RecordStore* recordStore() const { return _recordStore.get(); } - - // ---- - - const DiskLoc& head() const; - - void setHead( DiskLoc newHead ); - - bool isMultikey() const; - - void setMultikey(); - - // if this ready is ready for queries - bool isReady() const; - // ------------ - - - template< class V > - const BtreeBucket<V>* getHeadBucket() const { return getBucket<V>( head() ); } - - template< class V > - const BtreeBucket<V>* getBucket( const DiskLoc& loc ) const; - - private: - - int _indexNo() const; - - void setIsReady( bool isReady ); - - void _debugCheckVerifyReady() const; - - DiskLoc _catalogFindHeadFromDisk() const; - - // --------- - - // the collection this index is over, not storage for the index - Collection* _collection; // not-owned here - - const IndexDescriptor* _descriptor; // not-owned here - - // the record store for this index (where its buckets go) - scoped_ptr<RecordStore> _recordStore; // OWNED HERE - - Ordering _ordering; - - bool _isReady; // cache of NamespaceDetails - - mutable DiskLoc _head; // cache of IndexDetails or Null - - mutable bool _isMultikeySet; - mutable bool _isMultikey; // cache of NamespaceDetails - - friend class IndexCatalog; - }; - -} |