diff options
author | Dwight <dmerriman@gmail.com> | 2010-03-01 16:20:00 -0500 |
---|---|---|
committer | Dwight <dmerriman@gmail.com> | 2010-03-01 16:20:00 -0500 |
commit | e33b79fb107455ca2c6d534610a7d0c0f41a13e7 (patch) | |
tree | 67cc76e685e20062994a978012d60db8d4b2e3bd | |
parent | 25e157a20488044e09ac95b560d016b2e045a51b (diff) | |
parent | 05de70c790644e51a5590725cd143124089b5eab (diff) | |
download | mongo-e33b79fb107455ca2c6d534610a7d0c0f41a13e7.tar.gz |
Merge branch 'master' of git@github.com:mongodb/mongo
-rw-r--r-- | db/btree.h | 1 | ||||
-rw-r--r-- | db/btreecursor.cpp | 4 | ||||
-rw-r--r-- | db/cursor.h | 2 | ||||
-rw-r--r-- | db/query.cpp | 6 | ||||
-rw-r--r-- | dbtests/jstests.cpp | 27 | ||||
-rw-r--r-- | jstests/geo3.js | 2 | ||||
-rw-r--r-- | jstests/geo7.js | 18 | ||||
-rw-r--r-- | jstests/tool/csv1.js | 8 | ||||
-rw-r--r-- | mongo.xcodeproj/project.pbxproj | 2 | ||||
-rw-r--r-- | scripting/engine_spidermonkey.cpp | 22 | ||||
-rw-r--r-- | scripting/v8_db.cpp | 32 | ||||
-rw-r--r-- | scripting/v8_wrapper.cpp | 45 | ||||
-rw-r--r-- | tools/tool.cpp | 2 |
13 files changed, 122 insertions, 49 deletions
diff --git a/db/btree.h b/db/btree.h index 4790cd56e58..bac9584b4e6 100644 --- a/db/btree.h +++ b/db/btree.h @@ -342,7 +342,6 @@ namespace mongo { void forgetEndKey() { endKey = BSONObj(); } - virtual bool useMatcher(); private: /* Our btrees may (rarely) have "unused" keys when items are deleted. Skip past them. diff --git a/db/btreecursor.cpp b/db/btreecursor.cpp index b6c436bc9b1..ab15c443095 100644 --- a/db/btreecursor.cpp +++ b/db/btreecursor.cpp @@ -95,10 +95,6 @@ namespace mongo { } while ( !ok() && ++boundIndex_ < bounds_.size() ); } - bool BtreeCursor::useMatcher(){ - return _spec.getType() == 0; - } - /* skip unused keys. */ void BtreeCursor::skipUnusedKeys() { int u = 0; diff --git a/db/cursor.h b/db/cursor.h index a726f2062c0..c33e966d075 100644 --- a/db/cursor.h +++ b/db/cursor.h @@ -96,8 +96,6 @@ namespace mongo { virtual bool capped() const { return false; } - /* TODO: get rid of this, kind of a temp hack for geo */ - virtual bool useMatcher() { return true; } }; // strategy object implementing direction of traversal. diff --git a/db/query.cpp b/db/query.cpp index 2ef8a35c20f..99d8dabd4d6 100644 --- a/db/query.cpp +++ b/db/query.cpp @@ -473,10 +473,10 @@ namespace mongo { {} void setupMatcher() { - if ( ! _c.get() || _c->useMatcher() ) + // if ( ! _c.get() )|| _c->useMatcher() ) _matcher.reset(new CoveredIndexMatcher( qp().query() , qp().indexKey())); - else - _matcher.reset(new CoveredIndexMatcher( BSONObj() , qp().indexKey())); + // else + // _matcher.reset(new CoveredIndexMatcher( BSONObj() , qp().indexKey())); } virtual void init() { diff --git a/dbtests/jstests.cpp b/dbtests/jstests.cpp index d38081eafd9..454dcdc1d07 100644 --- a/dbtests/jstests.cpp +++ b/dbtests/jstests.cpp @@ -528,7 +528,7 @@ namespace JSTests { BSONObj out = s->getObject( "a" ); ASSERT_EQUALS( mongo::NumberLong, out.firstElement().type() ); - ASSERT( s->exec( "b = {b:a.a}", "foo", false, true, false ) ); + ASSERT( s->exec( "printjson( a ); b = {b:a.a}", "foo", false, true, false ) ); out = s->getObject( "b" ); ASSERT_EQUALS( mongo::NumberLong, out.firstElement().type() ); ASSERT_EQUALS( val, out.firstElement().numberLong() ); @@ -543,6 +543,31 @@ namespace JSTests { out = s->getObject( "d" ); ASSERT_EQUALS( NumberDouble, out.firstElement().type() ); ASSERT_EQUALS( double( val ), out.firstElement().number() ); + + ASSERT( s->exec( "e = {e:a.a.floatApprox}", "foo", false, true, false ) ); + out = s->getObject( "e" ); + ASSERT_EQUALS( NumberDouble, out.firstElement().type() ); + ASSERT_EQUALS( double( val ), out.firstElement().number() ); + + ASSERT( s->exec( "f = {f:a.a.top}", "foo", false, true, false ) ); + out = s->getObject( "f" ); + ASSERT( NumberDouble == out.firstElement().type() || NumberInt == out.firstElement().type() ); + + s->setObject( "z", BSON( "z" << (long long)( 4 ) ) ); + ASSERT( s->exec( "y = {y:z.z.top}", "foo", false, true, false ) ); + out = s->getObject( "y" ); + ASSERT_EQUALS( Undefined, out.firstElement().type() ); + + ASSERT( s->exec( "x = {x:z.z.floatApprox}", "foo", false, true, false ) ); + out = s->getObject( "x" ); + ASSERT( NumberDouble == out.firstElement().type() || NumberInt == out.firstElement().type() ); + ASSERT_EQUALS( double( 4 ), out.firstElement().number() ); + + ASSERT( s->exec( "w = {w:z.z}", "foo", false, true, false ) ); + out = s->getObject( "w" ); + ASSERT_EQUALS( mongo::NumberLong, out.firstElement().type() ); + ASSERT_EQUALS( 4, out.firstElement().numberLong() ); + } }; diff --git a/jstests/geo3.js b/jstests/geo3.js index 7d93740351f..5d1acbc4c39 100644 --- a/jstests/geo3.js +++ b/jstests/geo3.js @@ -70,11 +70,9 @@ assert.gt( filtered1.stats.objectsLoaded , filtered2.stats.objectsLoaded , "C3" testFiltering( "loc and a" ); -/* t.dropIndex( { loc : "2d" , a : 1 } ) assert.eq( 1 , t.getIndexKeys().length , "setup 4a" ) t.ensureIndex( { loc : "2d" , b : 1 } ) assert.eq( 2 , t.getIndexKeys().length , "setup 4b" ) testFiltering( "loc and b" ); -*/ diff --git a/jstests/geo7.js b/jstests/geo7.js new file mode 100644 index 00000000000..dee3f1b2428 --- /dev/null +++ b/jstests/geo7.js @@ -0,0 +1,18 @@ + +t = db.geo7; +t.drop(); + +t.insert({_id:1,y:[1,1]}) +t.insert({_id:2,y:[1,1],z:3}) +t.insert({_id:3,y:[1,1],z:4}) +t.insert({_id:4,y:[1,1],z:5}) + +t.ensureIndex({y:"2d",z:1}) + +assert.eq( 1 , t.find({y:[1,1],z:3}).itcount() , "A1" ); + +t.dropIndex({y:"2d",z:1}) + +t.ensureIndex({y:"2d"}) +assert.eq( 1 , t.find({y:[1,1],z:3}).itcount() , "A2" ); + diff --git a/jstests/tool/csv1.js b/jstests/tool/csv1.js index 55aa4b473cd..c57767454f1 100644 --- a/jstests/tool/csv1.js +++ b/jstests/tool/csv1.js @@ -4,25 +4,25 @@ t = new ToolTest( "csv1" ) c = t.startDB( "foo" ); -base = { a : 1 , b : "foo,bar" , c: 5 }; +base = { a : 1 , b : "foo,bar" , c: 5, 'd d': 6 }; assert.eq( 0 , c.count() , "setup1" ); c.insert( base ); delete base._id assert.eq( 1 , c.count() , "setup2" ); -t.runTool( "export" , "--out" , t.extFile , "-d" , t.baseName , "-c" , "foo" , "--csv" , "-f" , "a,b,c" ) +t.runTool( "export" , "--out" , t.extFile , "-d" , t.baseName , "-c" , "foo" , "--csv" , "-f" , "a,b,c,d d" ) c.drop() assert.eq( 0 , c.count() , "after drop" ) -t.runTool( "import" , "--file" , t.extFile , "-d" , t.baseName , "-c" , "foo" , "--type" , "csv" , "-f" , "a,b,c" ); +t.runTool( "import" , "--file" , t.extFile , "-d" , t.baseName , "-c" , "foo" , "--type" , "csv" , "-f" , "a,b,c,d d" ); assert.soon( "2 == c.count()" , "restore 2" ); a = c.find().sort( { a : 1 } ).toArray(); delete a[0]._id delete a[1]._id -assert.eq( tojson( { a : "a" , b : "b" , c : "c" } ) , tojson( a[1] ) , "csv parse 1" ); +assert.eq( tojson( { a : "a" , b : "b" , c : "c" , 'd d': "d d"} ) , tojson( a[1] ) , "csv parse 1" ); assert.eq( tojson( base ) , tojson(a[0]) , "csv parse 0" ) c.drop() diff --git a/mongo.xcodeproj/project.pbxproj b/mongo.xcodeproj/project.pbxproj index ca21e880008..37ca98a651c 100644 --- a/mongo.xcodeproj/project.pbxproj +++ b/mongo.xcodeproj/project.pbxproj @@ -496,6 +496,7 @@ 93BCE5A610F3FB5200FA139B /* basicPlus.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = basicPlus.js; sourceTree = "<group>"; }; 93BFA0E311330A8C0045D084 /* not2.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = not2.js; sourceTree = "<group>"; }; 93C38E940FA66622007D6E4A /* basictests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = basictests.cpp; sourceTree = "<group>"; }; + 93CC40C2113C407A00734218 /* insert1.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = insert1.js; sourceTree = "<group>"; }; 93D0C1520EF1D377005253B7 /* jsobjtests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = jsobjtests.cpp; sourceTree = "<group>"; }; 93D0C1FB0EF1E267005253B7 /* namespacetests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = namespacetests.cpp; sourceTree = "<group>"; }; 93D5A8921117A1380052C931 /* regex6.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = regex6.js; sourceTree = "<group>"; }; @@ -744,6 +745,7 @@ 934BEB9A10DFFA9600178102 /* jstests */ = { isa = PBXGroup; children = ( + 93CC40C2113C407A00734218 /* insert1.js */, 93BFA0E311330A8C0045D084 /* not2.js */, 93B9FA36112CAC3C0066ECD2 /* shellkillop.js */, 93B9F91A112C7F200066ECD2 /* set4.js */, diff --git a/scripting/engine_spidermonkey.cpp b/scripting/engine_spidermonkey.cpp index 294431c6e35..db48df15de0 100644 --- a/scripting/engine_spidermonkey.cpp +++ b/scripting/engine_spidermonkey.cpp @@ -160,9 +160,14 @@ namespace mongo { // NOTE No validation of passed in object long long toNumberLongUnsafe( JSObject *o ) { - boost::uint64_t val = - ( (boost::uint64_t)(boost::uint32_t)getNumber( o , "top" ) << 32 ) + - ( boost::uint32_t)( getNumber( o , "bottom" ) ); + boost::uint64_t val; + if ( hasProperty( o, "top" ) ) { + val = + ( (boost::uint64_t)(boost::uint32_t)getNumber( o , "top" ) << 32 ) + + ( boost::uint32_t)( getNumber( o , "bottom" ) ); + } else { + val = getNumber( o, "floatApprox" ); + } return val; } @@ -566,10 +571,13 @@ namespace mongo { case NumberLong: { boost::uint64_t val = (boost::uint64_t)e.numberLong(); JSObject * o = JS_NewObject( _context , &numberlong_class , 0 , 0 ); - // using 2 doubles here instead of a single double because certain double - // bit patterns represent undefined values and sm might trash them - setProperty( o , "top" , toval( (double)(boost::uint32_t)( val >> 32 ) ) ); - setProperty( o , "bottom" , toval( (double)(boost::uint32_t)( val & 0x00000000ffffffff ) ) ); + setProperty( o , "floatApprox" , toval( (double)(boost::int64_t)( val ) ) ); + if ( (boost::int64_t)val != (boost::int64_t)(double)(boost::int64_t)( val ) ) { + // using 2 doubles here instead of a single double because certain double + // bit patterns represent undefined values and sm might trash them + setProperty( o , "top" , toval( (double)(boost::uint32_t)( val >> 32 ) ) ); + setProperty( o , "bottom" , toval( (double)(boost::uint32_t)( val & 0x00000000ffffffff ) ) ); + } return OBJECT_TO_JSVAL( o ); } case DBRef: { diff --git a/scripting/v8_db.cpp b/scripting/v8_db.cpp index 52a581e6ea4..49b6efedfe3 100644 --- a/scripting/v8_db.cpp +++ b/scripting/v8_db.cpp @@ -603,8 +603,8 @@ namespace mongo { v8::Handle<v8::Value> numberLongInit( const v8::Arguments& args ) { - if (args.Length() != 2) { - return v8::ThrowException( v8::String::New( "NumberLong needs 2 arguments" ) ); + if (args.Length() != 1 && args.Length() != 3) { + return v8::ThrowException( v8::String::New( "NumberLong needs 1 or 3 arguments" ) ); } v8::Handle<v8::Object> it = args.This(); @@ -614,13 +614,25 @@ namespace mongo { it = f->NewInstance(); } - it->Set( v8::String::New( "top" ) , args[0] ); - it->Set( v8::String::New( "bottom" ) , args[1] ); + it->Set( v8::String::New( "floatApprox" ) , args[0] ); + if ( args.Length() == 3 ) { + it->Set( v8::String::New( "top" ) , args[1] ); + it->Set( v8::String::New( "bottom" ) , args[2] ); + } it->SetHiddenValue( v8::String::New( "__NumberLong" ), v8::Number::New( 1 ) ); return it; } + long long numberLongVal( const v8::Handle< v8::Object > &it ) { + if ( !it->Has( v8::String::New( "top" ) ) ) + return (long long)( it->Get( v8::String::New( "floatApprox" ) )->NumberValue() ); + return + (long long) + ( (unsigned long long)( it->Get( v8::String::New( "top" ) )->ToInt32()->Value() ) << 32 ) + + (unsigned)( it->Get( v8::String::New( "bottom" ) )->ToInt32()->Value() ); + } + v8::Handle<v8::Value> numberLongValueOf( const v8::Arguments& args ) { if (args.Length() != 0) { @@ -629,11 +641,9 @@ namespace mongo { v8::Handle<v8::Object> it = args.This(); - unsigned long long val = - ( (unsigned long long)( it->Get( v8::String::New( "top" ) )->ToInt32()->Value() ) << 32 ) + - (unsigned)( it->Get( v8::String::New( "bottom" ) )->ToInt32()->Value() ); + long long val = numberLongVal( it ); - return v8::Number::New( double( (long long)val ) ); + return v8::Number::New( double( val ) ); } v8::Handle<v8::Value> numberLongToNumber( const v8::Arguments& args ) { @@ -648,12 +658,10 @@ namespace mongo { v8::Handle<v8::Object> it = args.This(); - unsigned long long val = - ( (unsigned long long)( it->Get( v8::String::New( "top" ) )->ToInt32()->Value() ) << 32 ) + - (unsigned)( it->Get( v8::String::New( "bottom" ) )->ToInt32()->Value() ); + long long val = numberLongVal( it ); stringstream ss; - ss << (long long)val; + ss << val; string ret = ss.str(); return v8::String::New( ret.c_str() ); } diff --git a/scripting/v8_wrapper.cpp b/scripting/v8_wrapper.cpp index 183beff49d8..27ba3f39230 100644 --- a/scripting/v8_wrapper.cpp +++ b/scripting/v8_wrapper.cpp @@ -213,10 +213,17 @@ namespace mongo { Local<v8::Object> sub = readOnly ? readOnlyObjects->NewInstance() : internalFieldObjects->NewInstance(); unsigned long long val = f.numberLong(); v8::Function* numberLong = getNamedCons( "NumberLong" ); - v8::Handle<v8::Value> argv[2]; - argv[0] = v8::Integer::New( val >> 32 ); - argv[1] = v8::Integer::New( (unsigned long)(val & 0x00000000ffffffff) ); - o->Set( v8::String::New( f.fieldName() ), numberLong->NewInstance(2, argv) ); + if ( (long long)val == (long long)(double)(long long)(val) ) { + v8::Handle<v8::Value> argv[1]; + argv[0] = v8::Number::New( (double)(long long)( val ) ); + o->Set( v8::String::New( f.fieldName() ), numberLong->NewInstance( 1, argv ) ); + } else { + v8::Handle<v8::Value> argv[3]; + argv[0] = v8::Number::New( (double)(long long)(val) ); + argv[1] = v8::Integer::New( val >> 32 ); + argv[2] = v8::Integer::New( (unsigned long)(val & 0x00000000ffffffff) ); + o->Set( v8::String::New( f.fieldName() ), numberLong->NewInstance(3, argv) ); + } break; } @@ -339,10 +346,17 @@ namespace mongo { Local<v8::Object> sub = internalFieldObjects->NewInstance(); unsigned long long val = f.numberLong(); v8::Function* numberLong = getNamedCons( "NumberLong" ); - v8::Handle<v8::Value> argv[2]; - argv[0] = v8::Integer::New( val >> 32 ); - argv[1] = v8::Integer::New( (unsigned long)(val & 0x00000000ffffffff) ); - return numberLong->NewInstance( 2, argv ); + if ( (long long)val == (long long)(double)(long long)(val) ) { + v8::Handle<v8::Value> argv[1]; + argv[0] = v8::Number::New( (double)(long long)( val ) ); + return numberLong->NewInstance( 1, argv ); + } else { + v8::Handle<v8::Value> argv[3]; + argv[0] = v8::Number::New( (double)(long long)( val ) ); + argv[1] = v8::Integer::New( val >> 32 ); + argv[2] = v8::Integer::New( (unsigned long)(val & 0x00000000ffffffff) ); + return numberLong->NewInstance( 3, argv ); + } } case mongo::MinKey: { @@ -451,10 +465,17 @@ namespace mongo { // TODO might be nice to potentially speed this up with an indexed internal // field, but I don't yet know how to use an ObjectTemplate with a // constructor. - unsigned long long val = - ( (unsigned long long)( value->ToObject()->Get( v8::String::New( "top" ) )->ToInt32()->Value() ) << 32 ) + - (unsigned)( value->ToObject()->Get( v8::String::New( "bottom" ) )->ToInt32()->Value() ); - b.append( sname.c_str(), (long long)val ); + v8::Handle< v8::Object > it = value->ToObject(); + long long val; + if ( !it->Has( v8::String::New( "top" ) ) ) { + val = (long long)( it->Get( v8::String::New( "floatApprox" ) )->NumberValue() ); + } else { + val = (long long) + ( (unsigned long long)( it->Get( v8::String::New( "top" ) )->ToInt32()->Value() ) << 32 ) + + (unsigned)( it->Get( v8::String::New( "bottom" ) )->ToInt32()->Value() ); + } + + b.append( sname.c_str(), val ); } else if ( !value->ToObject()->GetHiddenValue( v8::String::New( "__DBPointer" ) ).IsEmpty() ) { OID oid; diff --git a/tools/tool.cpp b/tools/tool.cpp index 2e0cc6cd418..0dec5864601 100644 --- a/tools/tool.cpp +++ b/tools/tool.cpp @@ -212,7 +212,7 @@ namespace mongo { pcrecpp::StringPiece input(fields_arg); string f; - pcrecpp::RE re("([\\w\\.]+),?" ); + pcrecpp::RE re("([\\w\\.\\s]+),?" ); while ( re.Consume( &input, &f ) ){ _fields.push_back( f ); b.append( f.c_str() , 1 ); |