/** * Copyright (C) 2013 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 . * * 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 #include "mongo/db/storage/index_details.h" // For IndexDetails. #include "mongo/db/jsobj.h" #include "mongo/db/namespace_details.h" // For NamespaceDetails. #include "mongo/db/structure/collection.h" #include "mongo/util/stacktrace.h" namespace mongo { class IndexCatalog; /** * OnDiskIndexData (aka IndexDetails) is memory-mapped on-disk index data. * It contains two DiskLocs: * The first points to the head of the index. This is currently turned into a Btree node. * The second points to a BSONObj which describes the index. */ typedef IndexDetails OnDiskIndexData; /** * A cache of information computed from the memory-mapped per-index data (OnDiskIndexData). * Contains accessors for the various immutable index parameters, and an accessor for the * mutable "head" pointer which is index-specific. * * All synchronization is the responsibility of the caller. */ class IndexDescriptor { public: /** * OnDiskIndexData is a pointer to the memory mapped per-index data. * infoObj is a copy of the index-describing BSONObj contained in the OnDiskIndexData. */ IndexDescriptor(Collection* collection, int indexNumber, OnDiskIndexData* data, BSONObj infoObj) : _magic(123987), _collection(collection), _indexNumber(indexNumber), _onDiskData(data), _infoObj(infoObj.getOwned()), _numFields(infoObj.getObjectField("key").nFields()), _keyPattern(infoObj.getObjectField("key").getOwned()), _indexName(infoObj.getStringField("name")), _parentNS(infoObj.getStringField("ns")), _isIdIndex(IndexDetails::isIdIndexPattern( _keyPattern )), _sparse(infoObj["sparse"].trueValue()), _dropDups(infoObj["dropDups"].trueValue()), _unique( _isIdIndex || infoObj["unique"].trueValue() ) { _indexNamespace = _parentNS + ".$" + _indexNamespace; _version = 0; BSONElement e = _infoObj["v"]; if ( e.isNumber() ) { _version = e.numberInt(); } } ~IndexDescriptor() { _magic = 555; } // XXX this is terrible IndexDescriptor* clone() const { return new IndexDescriptor(_collection, _indexNumber, _onDiskData, _infoObj); } // // Information about the key pattern. // /** * Return the user-provided index key pattern. * Example: {geo: "2dsphere", nonGeo: 1} * Example: {foo: 1, bar: -1} */ const BSONObj& keyPattern() const { _checkOk(); return _keyPattern; } // How many fields do we index / are in the key pattern? int getNumFields() const { _checkOk(); return _numFields; } // // Information about the index's namespace / collection. // // Return the name of the index. const string& indexName() const { _checkOk(); return _indexName; } // Return the name of the indexed collection. const string& parentNS() const { return _parentNS; } // Return the name of this index's storage area (database.table.$index) const string& indexNamespace() const { return _indexNamespace; } // // Properties every index has // // Return what version of index this is. int version() const { return _version; } // May each key only occur once? bool unique() const { return _unique; } // Is dropDups set on this index? bool dropDups() const { return _dropDups; } // Is this index sparse? bool isSparse() const { return _sparse; } // Is this index multikey? bool isMultikey() const { _checkOk(); return _collection->details()->isMultikey(_indexNumber); } bool isIdIndex() const { _checkOk(); return _isIdIndex; } // // Properties that are Index-specific. // // Allow access to arbitrary fields in the per-index info object. Some indices stash // index-specific data there. BSONElement getInfoElement(const string& name) { return _infoObj[name]; } // // "Internals" of accessing the index, used by IndexAccessMethod(s). // // Return the memory-mapped index data block. OnDiskIndexData& getOnDisk() { _checkOk(); return *_onDiskData; } // Return the mutable head of the index. const DiskLoc& getHead() const { _checkOk(); return _onDiskData->head; } // Return a (rather compact) string representation. string toString() const { _checkOk(); return _infoObj.toString(); } // Return the info object. const BSONObj& infoObj() const { _checkOk(); return _infoObj; } // Set multikey attribute. We never unset it. void setMultikey() { _collection->getIndexCatalog()->markMultikey( this ); } // Is this index being created in the background? bool isBackgroundIndex() const { return _indexNumber >= _collection->details()->getCompletedIndexCount(); } // this is the collection over which the index is over Collection* getIndexedCollection() const { return _collection; } // this is the owner of this IndexDescriptor IndexCatalog* getIndexCatalog() const { return _collection->getIndexCatalog(); } private: void _checkOk() const { if ( _magic == 123987 ) return; log() << "uh oh: " << (void*)(this) << " " << _magic; verify(0); } int getIndexNumber() const { return _indexNumber; } int _magic; // Related catalog information of the parent collection Collection* _collection; // What # index are we in the catalog represented by _namespaceDetails? Needed for setting // and getting multikey. int _indexNumber; OnDiskIndexData* _onDiskData; // The BSONObj describing the index. Accessed through the various members above. const BSONObj _infoObj; // --- cached data from _infoObj int64_t _numFields; // How many fields are indexed? BSONObj _keyPattern; string _indexName; string _parentNS; string _indexNamespace; bool _isIdIndex; bool _sparse; bool _dropDups; bool _unique; int _version; friend class IndexCatalog; }; } // namespace mongo