diff options
author | Antonin Kral <a.kral@bobek.cz> | 2010-08-11 12:38:57 +0200 |
---|---|---|
committer | Antonin Kral <a.kral@bobek.cz> | 2010-08-11 12:38:57 +0200 |
commit | 7645618fd3914cb8a20561625913c20d49504a49 (patch) | |
tree | 8370f846f58f6d71165b7a0e2eda04648584ec76 /db/index.cpp | |
parent | 68c73c3c7608b4c87f07440dc3232801720b1168 (diff) | |
download | mongodb-7645618fd3914cb8a20561625913c20d49504a49.tar.gz |
Imported Upstream version 1.6.0
Diffstat (limited to 'db/index.cpp')
-rw-r--r-- | db/index.cpp | 243 |
1 files changed, 17 insertions, 226 deletions
diff --git a/db/index.cpp b/db/index.cpp index 6931d93..04eca73 100644 --- a/db/index.cpp +++ b/db/index.cpp @@ -16,7 +16,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "stdafx.h" +#include "pch.h" #include "namespace.h" #include "index.h" #include "btree.h" @@ -25,32 +25,6 @@ namespace mongo { - map<string,IndexPlugin*> * IndexPlugin::_plugins; - - IndexType::IndexType( const IndexPlugin * plugin , const IndexSpec * spec ) - : _plugin( plugin ) , _spec( spec ){ - - } - - IndexType::~IndexType(){ - } - - const BSONObj& IndexType::keyPattern() const { - return _spec->keyPattern; - } - - IndexPlugin::IndexPlugin( const string& name ) - : _name( name ){ - if ( ! _plugins ) - _plugins = new map<string,IndexPlugin*>(); - (*_plugins)[name] = this; - } - - int IndexType::compare( const BSONObj& l , const BSONObj& r ) const { - return l.woCompare( r , _spec->keyPattern ); - } - - int removeFromSysIndexes(const char *ns, const char *idxName) { string system_indexes = cc().database()->name + ".system.indexes"; BSONObjBuilder b; @@ -111,172 +85,6 @@ namespace mongo { wassert( n == 1 ); } - void IndexSpec::reset( const IndexDetails * details ){ - _details = details; - reset( details->info ); - } - - void IndexSpec::reset( const DiskLoc& loc ){ - info = loc.obj(); - keyPattern = info["key"].embeddedObjectUserCheck(); - if ( keyPattern.objsize() == 0 ) { - out() << info.toString() << endl; - assert(false); - } - _init(); - } - - - void IndexSpec::_init(){ - assert( keyPattern.objsize() ); - - string pluginName = ""; - - BSONObjIterator i( keyPattern ); - BSONObjBuilder nullKeyB; - while( i.more() ) { - BSONElement e = i.next(); - _fieldNames.push_back( e.fieldName() ); - _fixed.push_back( BSONElement() ); - nullKeyB.appendNull( "" ); - if ( e.type() == String ){ - uassert( 13007 , "can only have 1 index plugin / bad index key pattern" , pluginName.size() == 0 ); - pluginName = e.valuestr(); - } - - } - - _nullKey = nullKeyB.obj(); - - BSONObjBuilder b; - b.appendNull( "" ); - _nullObj = b.obj(); - _nullElt = _nullObj.firstElement(); - - if ( pluginName.size() ){ - IndexPlugin * plugin = IndexPlugin::get( pluginName ); - if ( ! plugin ){ - log() << "warning: can't find plugin [" << pluginName << "]" << endl; - } - else { - _indexType.reset( plugin->generate( this ) ); - } - } - _finishedInit = true; - } - - - void IndexSpec::getKeys( const BSONObj &obj, BSONObjSetDefaultOrder &keys ) const { - if ( _indexType.get() ){ - _indexType->getKeys( obj , keys ); - return; - } - vector<const char*> fieldNames( _fieldNames ); - vector<BSONElement> fixed( _fixed ); - _getKeys( fieldNames , fixed , obj, keys ); - if ( keys.empty() ) - keys.insert( _nullKey ); - } - - void IndexSpec::_getKeys( vector<const char*> fieldNames , vector<BSONElement> fixed , const BSONObj &obj, BSONObjSetDefaultOrder &keys ) const { - BSONElement arrElt; - unsigned arrIdx = ~0; - for( unsigned i = 0; i < fieldNames.size(); ++i ) { - if ( *fieldNames[ i ] == '\0' ) - continue; - BSONElement e = obj.getFieldDottedOrArray( fieldNames[ i ] ); - if ( e.eoo() ) - e = _nullElt; // no matching field - if ( e.type() != Array ) - fieldNames[ i ] = ""; // no matching field or non-array match - if ( *fieldNames[ i ] == '\0' ) - fixed[ i ] = e; // no need for further object expansion (though array expansion still possible) - if ( e.type() == Array && arrElt.eoo() ) { // we only expand arrays on a single path -- track the path here - arrIdx = i; - arrElt = e; - } - // enforce single array path here - uassert( 10088 , "cannot index parallel arrays", e.type() != Array || e.rawdata() == arrElt.rawdata() ); - } - - bool allFound = true; // have we found elements for all field names in the key spec? - for( vector<const char*>::const_iterator i = fieldNames.begin(); i != fieldNames.end(); ++i ){ - if ( **i != '\0' ){ - allFound = false; - break; - } - } - - bool insertArrayNull = false; - - if ( allFound ) { - if ( arrElt.eoo() ) { - // no terminal array element to expand - BSONObjBuilder b(_sizeTracker); - for( vector< BSONElement >::iterator i = fixed.begin(); i != fixed.end(); ++i ) - b.appendAs( *i, "" ); - keys.insert( b.obj() ); - } - else { - // terminal array element to expand, so generate all keys - BSONObjIterator i( arrElt.embeddedObject() ); - if ( i.more() ){ - while( i.more() ) { - BSONObjBuilder b(_sizeTracker); - for( unsigned j = 0; j < fixed.size(); ++j ) { - if ( j == arrIdx ) - b.appendAs( i.next(), "" ); - else - b.appendAs( fixed[ j ], "" ); - } - keys.insert( b.obj() ); - } - } - else if ( fixed.size() > 1 ){ - insertArrayNull = true; - } - } - } else { - // nonterminal array element to expand, so recurse - assert( !arrElt.eoo() ); - BSONObjIterator i( arrElt.embeddedObject() ); - if ( i.more() ){ - while( i.more() ) { - BSONElement e = i.next(); - if ( e.type() == Object ) - _getKeys( fieldNames, fixed, e.embeddedObject(), keys ); - } - } - else { - insertArrayNull = true; - } - } - - if ( insertArrayNull ){ - // x : [] - need to insert undefined - BSONObjBuilder b(_sizeTracker); - for( unsigned j = 0; j < fixed.size(); ++j ) { - if ( j == arrIdx ){ - b.appendUndefined( "" ); - } - else { - BSONElement e = fixed[j]; - if ( e.eoo() ) - b.appendNull( "" ); - else - b.appendAs( e , "" ); - } - } - keys.insert( b.obj() ); - } - - } - - /* Pull out the relevant key objects from obj, so we - can index them. Note that the set is multiple elements - only when it's a "multikey" array. - Keys will be left empty if key not found in the object. - */ void IndexDetails::getKeysFromObject( const BSONObj& obj, BSONObjSetDefaultOrder& keys) const { getSpec().getKeys( obj, keys ); } @@ -297,7 +105,7 @@ namespace mongo { } } - void getIndexChanges(vector<IndexChanges>& v, NamespaceDetails& d, BSONObj newObj, BSONObj oldObj) { + void getIndexChanges(vector<IndexChanges>& v, NamespaceDetails& d, BSONObj newObj, BSONObj oldObj, bool &changedId) { int z = d.nIndexesBeingBuilt(); v.resize(z); NamespaceDetails::IndexIterator i = d.ii(); @@ -311,6 +119,9 @@ namespace mongo { d.setIndexIsMultikey(i); setDifference(ch.oldkeys, ch.newkeys, ch.removed); setDifference(ch.newkeys, ch.oldkeys, ch.added); + if ( ch.removed.size() > 0 && ch.added.size() > 0 && idx.isIdIndex() ) { + changedId = true; + } } } @@ -390,7 +201,7 @@ namespace mongo { return false; } sourceCollection = nsdetails(sourceNS.c_str()); - log() << "info: creating collection " << sourceNS << " on add index\n"; + tlog() << "info: creating collection " << sourceNS << " on add index\n"; assert( sourceCollection ); } @@ -422,40 +233,20 @@ namespace mongo { return true; } - bool anyElementNamesMatch( const BSONObj& a , const BSONObj& b ){ - BSONObjIterator x(a); - while ( x.more() ){ - BSONElement e = x.next(); - BSONObjIterator y(b); - while ( y.more() ){ - BSONElement f = y.next(); - FieldCompareResult res = compareDottedFieldNames( e.fieldName() , f.fieldName() ); - if ( res == SAME || res == LEFT_SUBFIELD || res == RIGHT_SUBFIELD ) - return true; - } - } - return false; - } - - IndexSuitability IndexSpec::suitability( const BSONObj& query , const BSONObj& order ) const { - if ( _indexType.get() ) - return _indexType->suitability( query , order ); - return _suitability( query , order ); - } - - IndexSuitability IndexSpec::_suitability( const BSONObj& query , const BSONObj& order ) const { - // TODO: optimize - if ( anyElementNamesMatch( keyPattern , query ) == 0 && anyElementNamesMatch( keyPattern , order ) == 0 ) - return USELESS; - return HELPFUL; - } - IndexSuitability IndexType::suitability( const BSONObj& query , const BSONObj& order ) const { - return _spec->_suitability( query , order ); + void IndexSpec::reset( const IndexDetails * details ){ + _details = details; + reset( details->info ); } - bool IndexType::scanAndOrderRequired( const BSONObj& query , const BSONObj& order ) const { - return ! order.isEmpty(); + void IndexSpec::reset( const DiskLoc& loc ){ + info = loc.obj(); + keyPattern = info["key"].embeddedObjectUserCheck(); + if ( keyPattern.objsize() == 0 ) { + out() << info.toString() << endl; + assert(false); + } + _init(); } } |