00001
00002
00019 #pragma once
00020
00021 #include "../pch.h"
00022 #include "diskloc.h"
00023 #include "jsobj.h"
00024 #include <map>
00025
00026 namespace mongo {
00027
00028 class Cursor;
00029 class IndexSpec;
00030 class IndexType;
00031 class IndexPlugin;
00032 class IndexDetails;
00033
00034 enum IndexSuitability { USELESS = 0 , HELPFUL = 1 , OPTIMAL = 2 };
00035
00042 class IndexType : boost::noncopyable {
00043 public:
00044 IndexType( const IndexPlugin * plugin , const IndexSpec * spec );
00045 virtual ~IndexType();
00046
00047 virtual void getKeys( const BSONObj &obj, BSONObjSetDefaultOrder &keys ) const = 0;
00048 virtual shared_ptr<Cursor> newCursor( const BSONObj& query , const BSONObj& order , int numWanted ) const = 0;
00049
00051 virtual BSONObj fixKey( const BSONObj& in ) { return in; }
00052
00054 virtual int compare( const BSONObj& l , const BSONObj& r ) const;
00055
00057 const IndexPlugin * getPlugin() const { return _plugin; }
00058
00059 const BSONObj& keyPattern() const;
00060
00061 virtual IndexSuitability suitability( const BSONObj& query , const BSONObj& order ) const ;
00062
00063 virtual bool scanAndOrderRequired( const BSONObj& query , const BSONObj& order ) const ;
00064
00065 protected:
00066 const IndexPlugin * _plugin;
00067 const IndexSpec * _spec;
00068 };
00069
00076 class IndexPlugin : boost::noncopyable {
00077 public:
00078 IndexPlugin( const string& name );
00079 virtual ~IndexPlugin() {}
00080
00081 virtual IndexType* generate( const IndexSpec * spec ) const = 0;
00082
00083 string getName() const { return _name; }
00084
00089 virtual BSONObj adjustIndexSpec( const BSONObj& spec ) const { return spec; }
00090
00091
00092
00093 static IndexPlugin* get( const string& name ) {
00094 if ( ! _plugins )
00095 return 0;
00096 map<string,IndexPlugin*>::iterator i = _plugins->find( name );
00097 if ( i == _plugins->end() )
00098 return 0;
00099 return i->second;
00100 }
00101
00106 static string findPluginName( const BSONObj& keyPattern );
00107
00108 private:
00109 string _name;
00110 static map<string,IndexPlugin*> * _plugins;
00111 };
00112
00113
00114
00115
00116 class IndexSpec {
00117 public:
00118 BSONObj keyPattern;
00119 BSONObj info;
00120
00121 IndexSpec()
00122 : _details(0) , _finishedInit(false) {
00123 }
00124
00125 IndexSpec( const BSONObj& k , const BSONObj& m = BSONObj() )
00126 : keyPattern(k) , info(m) , _details(0) , _finishedInit(false) {
00127 _init();
00128 }
00129
00134 IndexSpec( const DiskLoc& loc ) {
00135 reset( loc );
00136 }
00137
00138 void reset( const DiskLoc& loc );
00139 void reset( const IndexDetails * details );
00140
00141 void getKeys( const BSONObj &obj, BSONObjSetDefaultOrder &keys ) const;
00142
00143 BSONElement missingField() const { return _nullElt; }
00144
00145 string getTypeName() const {
00146 if ( _indexType.get() )
00147 return _indexType->getPlugin()->getName();
00148 return "";
00149 }
00150
00151 IndexType* getType() const {
00152 return _indexType.get();
00153 }
00154
00155 const IndexDetails * getDetails() const {
00156 return _details;
00157 }
00158
00159 IndexSuitability suitability( const BSONObj& query , const BSONObj& order ) const ;
00160
00161 protected:
00162
00163 IndexSuitability _suitability( const BSONObj& query , const BSONObj& order ) const ;
00164
00165 void _getKeys( vector<const char*> fieldNames , vector<BSONElement> fixed , const BSONObj &obj, BSONObjSetDefaultOrder &keys ) const;
00166
00167 BSONSizeTracker _sizeTracker;
00168
00169 vector<const char*> _fieldNames;
00170 vector<BSONElement> _fixed;
00171
00172 BSONObj _nullKey;
00173
00174 BSONObj _nullObj;
00175 BSONElement _nullElt;
00176
00177 int _nFields;
00178 bool _sparse;
00179
00180 shared_ptr<IndexType> _indexType;
00181
00182 const IndexDetails * _details;
00183
00184 void _init();
00185
00186 public:
00187 bool _finishedInit;
00188
00189 friend class IndexType;
00190 };
00191
00192
00193 }