// 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 . */ #pragma once #include "../pch.h" #include "diskloc.h" #include "jsobj.h" #include 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 shared_ptr 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::iterator i = _plugins->find( name ); if ( i == _plugins->end() ) return 0; return i->second; } string getName() const { return _name; } private: string _name; static map * _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 fieldNames , vector fixed , const BSONObj &obj, BSONObjSetDefaultOrder &keys ) const; BSONSizeTracker _sizeTracker; vector _fieldNames; vector _fixed; BSONObj _nullKey; BSONObj _nullObj; BSONElement _nullElt; shared_ptr _indexType; const IndexDetails * _details; void _init(); public: bool _finishedInit; friend class IndexType; }; } // namespace mongo