0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-11-30 00:56:44 +01:00
mongodb/db/indexkey.h
2011-01-04 00:40:41 -05:00

194 lines
5.8 KiB
C++

// 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 "../pch.h"
#include "diskloc.h"
#include "jsobj.h"
#include <map>
namespace mongo {
class Cursor;
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<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;
string getName() const { return _name; }
/**
* @return new keyPattern
* if nothing changes, should return keyPattern
*/
virtual BSONObj adjustIndexSpec( const BSONObj& spec ) const { return spec; }
// ------- static below -------
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;
}
/**
* @param keyPattern { x : "fts" }
* @return "" or the name
*/
static string findPluginName( const BSONObj& keyPattern );
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; // a full key with all fields null
BSONObj _nullObj; // only used for _nullElt
BSONElement _nullElt; // jstNull
int _nFields; // number of fields in the index
bool _sparse; // if the index is sparse
shared_ptr<IndexType> _indexType;
const IndexDetails * _details;
void _init();
public:
bool _finishedInit;
friend class IndexType;
};
} // namespace mongo