diff options
author | Eliot Horowitz <eliot@10gen.com> | 2010-04-13 15:23:57 -0400 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2010-04-13 15:23:57 -0400 |
commit | 61ae5fa244e5a38b1778d2bd8df21211b0edcfd1 (patch) | |
tree | 845b29b1c0e7f932b15c3d3338297cc523f7518b /db/indexkey.h | |
parent | 552fe0fc2c60202e3a437e3c37a9347b68533941 (diff) | |
download | mongo-61ae5fa244e5a38b1778d2bd8df21211b0edcfd1.tar.gz |
a bunch of refactoring for mongos linking
Diffstat (limited to 'db/indexkey.h')
-rw-r--r-- | db/indexkey.h | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/db/indexkey.h b/db/indexkey.h new file mode 100644 index 00000000000..3c98a9dd8bc --- /dev/null +++ b/db/indexkey.h @@ -0,0 +1,173 @@ +// index_key.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/>. +*/ + +#pragma once + +#include "../stdafx.h" +#include "diskloc.h" +#include "jsobj.h" +#include <map> + +namespace mongo { + + class IndexSpec; + class IndexType; // TODO: this name sucks + class IndexPlugin; + class IndexDetails; + + enum IndexSuitability { USELESS = 0 , HELPFUL = 1 , OPTIMAL = 2 }; + + /** + * this represents an instance of a index plugin + * done this way so parsing, etc... can be cached + * so if there is a FTS IndexPlugin, for each index using FTS + * there will be 1 of these, and it can have things pre-parsed, etc... + */ + class IndexType : boost::noncopyable { + public: + IndexType( const IndexPlugin * plugin , const IndexSpec * spec ); + virtual ~IndexType(); + + virtual void getKeys( const BSONObj &obj, BSONObjSetDefaultOrder &keys ) const = 0; + virtual auto_ptr<Cursor> newCursor( const BSONObj& query , const BSONObj& order , int numWanted ) const = 0; + + /** optional op : changes query to match what's in the index */ + virtual BSONObj fixKey( const BSONObj& in ) { return in; } + + /** optional op : compare 2 objects with regards to this index */ + virtual int compare( const BSONObj& l , const BSONObj& r ) const; + + /** @return plugin */ + const IndexPlugin * getPlugin() const { return _plugin; } + + const BSONObj& keyPattern() const; + + virtual IndexSuitability suitability( const BSONObj& query , const BSONObj& order ) const ; + + virtual bool scanAndOrderRequired( const BSONObj& query , const BSONObj& order ) const ; + + protected: + const IndexPlugin * _plugin; + const IndexSpec * _spec; + }; + + /** + * this represents a plugin + * a plugin could be something like full text search, sparse index, etc... + * 1 of these exists per type of index per server + * 1 IndexType is created per index using this plugin + */ + class IndexPlugin : boost::noncopyable { + public: + IndexPlugin( const string& name ); + virtual ~IndexPlugin(){} + + virtual IndexType* generate( const IndexSpec * spec ) const = 0; + + static IndexPlugin* get( const string& name ){ + if ( ! _plugins ) + return 0; + map<string,IndexPlugin*>::iterator i = _plugins->find( name ); + if ( i == _plugins->end() ) + return 0; + return i->second; + } + + string getName() const { return _name; } + private: + string _name; + static map<string,IndexPlugin*> * _plugins; + }; + + /* precomputed details about an index, used for inserting keys on updates + stored/cached in NamespaceDetailsTransient, or can be used standalone + */ + class IndexSpec { + public: + BSONObj keyPattern; // e.g., { name : 1 } + BSONObj info; // this is the same as IndexDetails::info.obj() + + IndexSpec() + : _details(0) , _finishedInit(false){ + } + + IndexSpec( const BSONObj& k , const BSONObj& m = BSONObj() ) + : keyPattern(k) , info(m) , _details(0) , _finishedInit(false){ + _init(); + } + + /** + this is a DiscLoc of an IndexDetails info + should have a key field + */ + IndexSpec( const DiskLoc& loc ){ + reset( loc ); + } + + void reset( const DiskLoc& loc ); + void reset( const IndexDetails * details ); + + void getKeys( const BSONObj &obj, BSONObjSetDefaultOrder &keys ) const; + + BSONElement missingField() const { return _nullElt; } + + string getTypeName() const { + if ( _indexType.get() ) + return _indexType->getPlugin()->getName(); + return ""; + } + + IndexType* getType() const { + return _indexType.get(); + } + + const IndexDetails * getDetails() const { + return _details; + } + + IndexSuitability suitability( const BSONObj& query , const BSONObj& order ) const ; + + protected: + + IndexSuitability _suitability( const BSONObj& query , const BSONObj& order ) const ; + + void _getKeys( vector<const char*> fieldNames , vector<BSONElement> fixed , const BSONObj &obj, BSONObjSetDefaultOrder &keys ) const; + + BSONSizeTracker _sizeTracker; + + vector<const char*> _fieldNames; + vector<BSONElement> _fixed; + BSONObj _nullKey; + + BSONObj _nullObj; + BSONElement _nullElt; + + shared_ptr<IndexType> _indexType; + + const IndexDetails * _details; + + void _init(); + + public: + bool _finishedInit; + + friend class IndexType; + }; + + +} // namespace mongo |