summaryrefslogtreecommitdiff
path: root/db/index.cpp
diff options
context:
space:
mode:
authorAntonin Kral <a.kral@bobek.cz>2010-08-11 12:38:57 +0200
committerAntonin Kral <a.kral@bobek.cz>2010-08-11 12:38:57 +0200
commit7645618fd3914cb8a20561625913c20d49504a49 (patch)
tree8370f846f58f6d71165b7a0e2eda04648584ec76 /db/index.cpp
parent68c73c3c7608b4c87f07440dc3232801720b1168 (diff)
downloadmongodb-7645618fd3914cb8a20561625913c20d49504a49.tar.gz
Imported Upstream version 1.6.0
Diffstat (limited to 'db/index.cpp')
-rw-r--r--db/index.cpp243
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();
}
}