From 341cd83dd1784a38ff6a25f72c6b81a58ea85de0 Mon Sep 17 00:00:00 2001 From: Eliot Horowitz Date: Thu, 10 Dec 2009 16:38:47 -0500 Subject: [PATCH] finish + switch to simpler+cleaner new object from mod code --- db/update.cpp | 43 ++++++++++++++++++++++++++++++++++------- db/update.h | 2 +- dbtests/updatetests.cpp | 19 +++++++++--------- 3 files changed, 47 insertions(+), 17 deletions(-) diff --git a/db/update.cpp b/db/update.cpp index 95cb371ca22..da71facd4aa 100644 --- a/db/update.cpp +++ b/db/update.cpp @@ -81,6 +81,40 @@ namespace mongo { bb.done(); break; } + + case PULL: + case PULL_ALL: { + uassert( "$pull/$pullAll can only be applied to an array" , in.type() == Array ); + BSONObjBuilder bb( b.subarrayStart( shortFieldName ) ); + + int n = 0; + + BSONObjIterator i( in.embeddedObject() ); + while ( i.more() ){ + BSONElement e = i.next(); + bool allowed = true; + + if ( op == PULL ){ + allowed = e.woCompare( elt , false ) != 0; + } + else { + BSONObjIterator j( elt.embeddedObject() ); + while( j.more() ) { + BSONElement arrJ = j.next(); + if ( e.woCompare( arrJ, false ) == 0 ){ + allowed = false; + break; + } + } + } + + if ( allowed ) + bb.appendAs( e , bb.numStr( n++ ) ); + } + + bb.done(); + break; + } case POP: { uassert( "$pop can only be applied to an array" , in.type() == Array ); @@ -117,7 +151,7 @@ namespace mongo { bb.done(); break; } - + default: stringstream ss; ss << "Mod::apply can't handle type: " << op; @@ -269,7 +303,6 @@ namespace mongo { ModHolder::iterator mend = _mods.lower_bound( root + "{" ); set onedownseen; - list toadd; // TODO: remove. this is a hack to make new and old impls. identical. when testing is complete, we should remove while ( e.type() && m != mend ){ string field = root + e.fieldName(); @@ -290,7 +323,7 @@ namespace mongo { continue; } case LEFT_BEFORE: - toadd.push_back( &(m->second) ); + _appendNewFromMods( root , m->second , b , onedownseen ); m++; continue; case SAME: @@ -315,10 +348,6 @@ namespace mongo { e = es.next(); } - for ( list::iterator i=toadd.begin(); i!=toadd.end(); i++ ) - _appendNewFromMods( root , **i , b , onedownseen ); - - for ( ; m != mend; m++ ){ _appendNewFromMods( root , m->second , b , onedownseen ); } diff --git a/db/update.h b/db/update.h index f622c83b255..de23b67e672 100644 --- a/db/update.h +++ b/db/update.h @@ -226,7 +226,7 @@ namespace mongo { BSONObj createNewFromMods_r( const BSONObj &obj ); BSONObj createNewFromMods( const BSONObj &obj ){ - return createNewFromMods_l( obj ); + return createNewFromMods_r( obj ); } /** diff --git a/dbtests/updatetests.cpp b/dbtests/updatetests.cpp index 7caa2d5b4c0..3e09aeba178 100644 --- a/dbtests/updatetests.cpp +++ b/dbtests/updatetests.cpp @@ -550,17 +550,18 @@ namespace UpdateTests { void test( BSONObj morig , BSONObj in , BSONObj wanted ){ - - int its = 1000; - double o = _test( morig , in , wanted , false , its ); - double n = _test( morig , in , wanted , true , its ); - double r = o / n; - cout << " new is : " << r << " x faster" << endl; + if ( false ){ + int its = 1000; + double o = _test( morig , in , wanted , false , its ); + double n = _test( morig , in , wanted , true , its ); + double r = o / n; + cout << " new is : " << r << " x faster" << endl; + } BSONObj m = morig.copy(); ModSet set; set.getMods( m ); - + BSONObj out = set.createNewFromMods( in ); ASSERT_EQUALS( wanted , out ); } @@ -596,7 +597,7 @@ namespace UpdateTests { BSONObj m = BSON( "$inc" << BSON( "x" << 1 ) ); test( m , BSON( "x" << 5 ) , BSON( "x" << 6 ) ); test( m , BSON( "a" << 5 ) , BSON( "a" << 5 << "x" << 1 ) ); - test( m , BSON( "z" << 5 ) , BSON( "z" << 5 << "x" << 1 ) ); + test( m , BSON( "z" << 5 ) , BSON( "x" << 1 << "z" << 5 ) ); } }; @@ -620,7 +621,7 @@ namespace UpdateTests { test( BSON( "$set" << BSON( "x" << 17 ) ) , BSONObj() , BSON( "x" << 17 ) ); test( BSON( "$set" << BSON( "x" << 17 ) ) , BSON( "x" << 5 ) , BSON( "x" << 17 ) ); - test( BSON( "$set" << BSON( "x.a" << 17 ) ) , BSON( "z" << 5 ) , BSON( "z" << 5 << "x" << BSON( "a" << 17 ) ) ); + test( BSON( "$set" << BSON( "x.a" << 17 ) ) , BSON( "z" << 5 ) , BSON( "x" << BSON( "a" << 17 )<< "z" << 5 ) ); } };