From 9c2ed42daa8fbbef4a919c21ec564e2db55e8d60 Mon Sep 17 00:00:00 2001 From: Mark Benvenuto Date: Sat, 20 Jun 2015 00:22:50 -0400 Subject: SERVER-18579: Clang-Format - reformat code, no comment reflow --- src/mongo/db/hasher_test.cpp | 665 +++++++++++++++++++++---------------------- 1 file changed, 320 insertions(+), 345 deletions(-) (limited to 'src/mongo/db/hasher_test.cpp') diff --git a/src/mongo/db/hasher_test.cpp b/src/mongo/db/hasher_test.cpp index 0966bfbf3f8..4dbf147e768 100644 --- a/src/mongo/db/hasher_test.cpp +++ b/src/mongo/db/hasher_test.cpp @@ -38,348 +38,323 @@ namespace mongo { namespace { - // Helper methods - long long hashIt( const BSONObj& object, int seed ) { - return BSONElementHasher::hash64( object.firstElement(), seed ); - } - long long hashIt( const BSONObj& object ) { - int seed = 0; - return hashIt( object, seed ); - } - - // Test different oids hash to different things - TEST( BSONElementHasher, DifferentOidsAreDifferentHashes ) { - int seed = 0; - - long long int oidHash = BSONElementHasher::hash64( - BSONObjBuilder().genOID().obj().firstElement() , seed ); - long long int oidHash2 = BSONElementHasher::hash64( - BSONObjBuilder().genOID().obj().firstElement() , seed ); - long long int oidHash3 = BSONElementHasher::hash64( - BSONObjBuilder().genOID().obj().firstElement() , seed ); - - ASSERT_NOT_EQUALS( oidHash , oidHash2 ); - ASSERT_NOT_EQUALS( oidHash , oidHash3 ); - ASSERT_NOT_EQUALS( oidHash3 , oidHash2 ); - } - - // Test 32-bit ints, 64-bit ints, doubles hash to same thing - TEST( BSONElementHasher, ConsistentHashOfIntLongAndDouble ) { - int i = 3; - BSONObj p1 = BSON("a" << i); - long long int intHash = hashIt( p1 ); - - long long int ilong = 3; - BSONObj p2 = BSON("a" << ilong); - long long int longHash = hashIt( p2 ); - - double d = 3.1; - BSONObj p3 = BSON("a" << d); - long long int doubleHash = hashIt( p3 ); - - ASSERT_EQUALS( intHash, longHash ); - ASSERT_EQUALS( doubleHash, longHash ); - } - - // Test different ints don't hash to same thing - TEST( BSONElementHasher, DifferentIntHashesDiffer ) { - ASSERT_NOT_EQUALS( - hashIt( BSON("a" << 3) ) , - hashIt( BSON("a" << 4) ) - ); - } - - // Test seed makes a difference - TEST( BSONElementHasher, SeedMatters ) { - ASSERT_NOT_EQUALS( - hashIt( BSON("a" << 4), 0 ) , - hashIt( BSON("a" << 4), 1 ) - ); - } - - // Test strings hash to different things - TEST( BSONElementHasher, IntAndStringHashesDiffer ) { - ASSERT_NOT_EQUALS( - hashIt( BSON("a" << 3) ) , - hashIt( BSON("a" << "3") ) - ); - } - - // Test regexps and strings hash to different things - TEST( BSONElementHasher, RegexAndStringHashesDiffer ) { - BSONObjBuilder builder; - - ASSERT_NOT_EQUALS( - hashIt( BSON("a" << "3") ) , - hashIt( builder.appendRegex("a","3").obj() ) - ); - } - - // Test arrays and subobject hash to different things - TEST( BSONElementHasher, ArrayAndSubobjectHashesDiffer ) { - ASSERT_NOT_EQUALS( - hashIt( fromjson("{a : {'0' : 0 , '1' : 1}}") ) , - hashIt( fromjson("{a : [0,1]}") ) - ); - } - - // Testing sub-document grouping - TEST( BSONElementHasher, SubDocumentGroupingHashesDiffer ) { - ASSERT_NOT_EQUALS( - hashIt( fromjson("{x : {a : {}, b : 1}}") ) , - hashIt( fromjson("{x : {a : {b : 1}}}") ) - ); - } - - // Testing codeWscope scope squashing - TEST( BSONElementHasher, CodeWithScopeSquashesScopeIntsAndDoubles ) { - int seed = 0; - - BSONObjBuilder b1; - b1.appendCodeWScope("a","print('this is some stupid code')", BSON("a" << 3)); - BSONObj p10 = b1.obj(); - - BSONObjBuilder b2; - b2.appendCodeWScope("a","print('this is some stupid code')", BSON("a" << 3.1)); - - BSONObjBuilder b3; - b3.appendCodeWScope("a","print('this is \nsome stupider code')", BSON("a" << 3)); - ASSERT_EQUALS( - BSONElementHasher::hash64( p10.firstElement() , seed ) , - BSONElementHasher::hash64( b2.obj().firstElement() , seed ) - ); - ASSERT_NOT_EQUALS( - BSONElementHasher::hash64( p10.firstElement() , seed ) , - BSONElementHasher::hash64( b3.obj().firstElement() , seed ) - ); - } - - // Test some recursive squashing - TEST( BSONElementHasher, RecursiveSquashingIntsAndDoubles ) { - ASSERT_EQUALS( - hashIt( fromjson("{x : {a : 3 , b : [ 3.1, {c : 3 }]}}") ) , - hashIt( fromjson("{x : {a : 3.1 , b : [ 3, {c : 3.0}]}}") ) - ); - } - - // Test minkey and maxkey don't hash to same thing - TEST( BSONElementHasher, MinKeyMaxKeyHashesDiffer ) { - ASSERT_NOT_EQUALS( - hashIt( BSON("a" << MAXKEY) ) , - hashIt( BSON("a" << MINKEY) ) - ); - } - - // Test squashing very large doubles and very small doubles - TEST( BSONElementHasher, VeryLargeAndSmallDoubles ) { - long long maxInt = std::numeric_limits::max(); - double smallerDouble = maxInt/2; - double biggerDouble = ( (double)maxInt )*( (double)maxInt ); - ASSERT_NOT_EQUALS( - hashIt( BSON("a" << maxInt ) ) , - hashIt( BSON("a" << smallerDouble ) ) - ); - ASSERT_EQUALS( - hashIt( BSON("a" << maxInt ) ) , - hashIt( BSON("a" << biggerDouble ) ) - ); - - long long minInt = std::numeric_limits::min(); - double negativeDouble = -( (double)maxInt )*( (double)maxInt ); - ASSERT_EQUALS( - hashIt( BSON("a" << minInt ) ) , - hashIt( BSON("a" << negativeDouble ) ) - ); - } - - // Remaining tests are hard-coded checks to ensure the hash function is - // consistent across platforms and server versions - // - // All of the values in the remaining tests have been determined experimentally. - TEST( BSONElementHasher, HashIntOrLongOrDouble ) { - BSONObj o = BSON( "check" << 42 ); - ASSERT_EQUALS( hashIt( o ), -944302157085130861LL ); - o = BSON( "check" << 42.123 ); - ASSERT_EQUALS( hashIt( o ), -944302157085130861LL ); - o = BSON( "check" << (long long) 42 ); - ASSERT_EQUALS( hashIt( o ), -944302157085130861LL ); - - o = BSON( "check" << 0 ); - ASSERT_EQUALS( hashIt( o ), 4854801880128277513LL ); - o = BSON( "check" << 0.456 ); - ASSERT_EQUALS( hashIt( o ), 4854801880128277513LL ); - o = BSON( "check" << (long long) 0 ); - ASSERT_EQUALS( hashIt( o ), 4854801880128277513LL ); - // NAN is treated as zero. - o = BSON( "check" << std::numeric_limits::signaling_NaN() ); - ASSERT_EQUALS( hashIt( o ), 4854801880128277513LL ); - o = BSON( "check" << std::numeric_limits::quiet_NaN() ); - ASSERT_EQUALS( hashIt( o ), 4854801880128277513LL ); - - o = BSON( "check" << 1 ); - ASSERT_EQUALS( hashIt( o ), 5902408780260971510LL ); - o = BSON( "check" << 1.987 ); - ASSERT_EQUALS( hashIt( o ), 5902408780260971510LL ); - o = BSON( "check" << (long long) 1 ); - ASSERT_EQUALS( hashIt( o ), 5902408780260971510LL ); - - o = BSON( "check" << -1 ); - ASSERT_EQUALS( hashIt( o ), 1140205862565771219LL ); - o = BSON( "check" << -1.789 ); - ASSERT_EQUALS( hashIt( o ), 1140205862565771219LL ); - o = BSON( "check" << (long long) -1 ); - ASSERT_EQUALS( hashIt( o ), 1140205862565771219LL ); - - o = BSON( "check" << std::numeric_limits::min() ); - ASSERT_EQUALS( hashIt( o ), 6165898260261354870LL ); - o = BSON( "check" << (double) std::numeric_limits::min() ); - ASSERT_EQUALS( hashIt( o ), 6165898260261354870LL ); - o = BSON( "check" << (long long) std::numeric_limits::min() ); - ASSERT_EQUALS( hashIt( o ), 6165898260261354870LL ); - - o = BSON( "check" << std::numeric_limits::max() ); - ASSERT_EQUALS( hashIt( o ), 1143184177162245883LL ); - o = BSON( "check" << (double) std::numeric_limits::max() ); - ASSERT_EQUALS( hashIt( o ), 1143184177162245883LL ); - o = BSON( "check" << (long long) std::numeric_limits::max() ); - ASSERT_EQUALS( hashIt( o ), 1143184177162245883LL ); - - // Large/small double values. - ASSERT( std::numeric_limits::max() < std::numeric_limits::max() ); - o = BSON( "check" << std::numeric_limits::max() ); - ASSERT_EQUALS( hashIt( o ), 921523596458303250LL ); - o = BSON( "check" << std::numeric_limits::max() ); // 9223372036854775807 - ASSERT_EQUALS( hashIt( o ), 921523596458303250LL ); - - // Have to create our own small double. - // std::numeric_limits::lowest() - Not available until C++11 - // std::numeric_limits::min() - Closest positive value to zero, not most negative. - double smallDouble = - std::numeric_limits::max(); - ASSERT( smallDouble < static_cast( std::numeric_limits::min() ) ); - o = BSON( "check" << smallDouble ); - ASSERT_EQUALS( hashIt( o ), 4532067210535695462LL ); - o = BSON( "check" << std::numeric_limits::min() ); // -9223372036854775808 - ASSERT_EQUALS( hashIt( o ), 4532067210535695462LL ); - } - - TEST( BSONElementHasher, HashMinKey ) { - BSONObj o = BSON( "check" << MINKEY ); - ASSERT_EQUALS( hashIt( o ), 7961148599568647290LL ); - } - - TEST( BSONElementHasher, HashMaxKey ) { - BSONObj o = BSON( "check" << MAXKEY ); - ASSERT_EQUALS( hashIt( o ), 5504842513779440750LL ); - } - - TEST( BSONElementHasher, HashUndefined ) { - BSONObj o = BSON( "check" << BSONUndefined ); - ASSERT_EQUALS( hashIt( o ), 40158834000849533LL ); - } - - TEST( BSONElementHasher, HashNull ) { - BSONObj o = BSON( "check" << BSONNULL ); - ASSERT_EQUALS( hashIt( o ), 2338878944348059895LL ); - } - - TEST( BSONElementHasher, HashString ) { - BSONObj o = BSON( "check" << "abc" ); - ASSERT_EQUALS( hashIt( o ), 8478485326885698097LL ); - o = BSON( "check" << BSONSymbol( "abc" ) ); - ASSERT_EQUALS( hashIt( o ), 8478485326885698097LL ); - - o = BSON( "check" << "" ); - ASSERT_EQUALS( hashIt( o ), 2049396243249673340LL ); - o = BSON( "check" << BSONSymbol( "" ) ); - ASSERT_EQUALS( hashIt( o ), 2049396243249673340LL ); - } - - TEST( BSONElementHasher, HashObject ) { - BSONObj o = BSON( "check" << BSON( "a" << "abc" << "b" << 123LL ) ); - ASSERT_EQUALS( hashIt( o ), 4771603801758380216LL ); - - o = BSON( "check" << BSONObj() ); - ASSERT_EQUALS( hashIt( o ), 7980500913326740417LL ); - } - - TEST( BSONElementHasher, HashArray ) { - BSONObj o = BSON( "check" << BSON_ARRAY( "bar" << "baz" << "qux" ) ); - ASSERT_EQUALS( hashIt( o ), -2938911267422831539LL ); - - o = BSON( "check" << BSONArray() ); - ASSERT_EQUALS( hashIt( o ), 8849948234993459283LL ); - } - - TEST( BSONElementHasher, HashBinary ) { - uint8_t bytes[] = { 0, 1, 2, 3, 4, 6 }; - BSONObj o = BSON( "check" << BSONBinData( bytes, 6, BinDataGeneral ) ); - ASSERT_EQUALS( hashIt( o ), 7252465090394235301LL ); - - o = BSON( "check" << BSONBinData( bytes, 6, bdtCustom ) ); - ASSERT_EQUALS( hashIt( o ), 5736670452907618262LL ); - - uint8_t uuidBytes[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; - o = BSON( "check" << BSONBinData( uuidBytes, 16, newUUID ) ); - ASSERT_EQUALS( hashIt( o ), 6084661258071355978LL ); - } - - TEST( BSONElementHasher, HashObjectId ) { - BSONObj o = BSON( "check" << OID( "010203040506070809101112" ) ); - ASSERT_EQUALS( hashIt( o ), -5588663249627035708LL ); - - o = BSON( "check" << OID( "000000000000000000000000" ) ); - ASSERT_EQUALS( hashIt( o ), -4293118519463489418LL ); - } - - TEST( BSONElementHasher, HashBoolean ) { - BSONObj o = BSON( "check" << true ); - ASSERT_EQUALS( hashIt( o ), 6405873908747105701LL ); - - o = BSON( "check" << false ); - ASSERT_EQUALS( hashIt( o ), 6289544573401934092LL ); - } - - TEST( BSONElementHasher, HashTimeStamp ) { - BSONObjBuilder builder1; - BSONObjBuilder builder2; - - BSONObj o = BSON( "check" << Date_t::fromMillisSinceEpoch( 0x5566778811223344LL ) ); - ASSERT_EQUALS( hashIt( o ), 4476222765095560467LL ); - o = builder1.append( "check", Timestamp(0x55667788LL, 0x11223344LL) ).obj(); - ASSERT_EQUALS( hashIt( o ), 4873046866288452390LL ); - - o = BSON( "check" << Date_t() ); - ASSERT_EQUALS( hashIt( o ), -1178696894582842035LL ); - o = builder2.appendTimestamp( "check", 0 ).obj(); - ASSERT_EQUALS( hashIt( o ), -7867208682377458672LL ); - } - - TEST( BSONElementHasher, HashRegEx ) { - BSONObj o = BSON( "check" << BSONRegEx( "mongodb" ) ); - ASSERT_EQUALS( hashIt( o ), -7275792090268217043LL ); - - o = BSON( "check" << BSONRegEx( ".*", "i" ) ); - ASSERT_EQUALS( hashIt( o ), 7095855029187981886LL ); - } - - TEST( BSONElementHasher, HashDBRef ) { - BSONObj o = BSON( "check" << BSONDBRef( "c", OID( "010203040506070809101112" ) ) ); - ASSERT_EQUALS( hashIt( o ), 940175826736461384LL ); - - o = BSON( "check" << BSONDBRef( "db.c", OID( "010203040506070809101112" ) ) ); - ASSERT_EQUALS( hashIt( o ), 2426768198104018194LL ); - } - - TEST( BSONElementHasher, HashCode ) { - BSONObj o = BSON( "check" << BSONCode( "func f() { return 1; }" ) ); - ASSERT_EQUALS( hashIt( o ), 6861638109178014270LL ); - } - - TEST( BSONElementHasher, HashCodeWScope ) { - BSONObj o = BSON( "check" << - BSONCodeWScope( "func f() { return 1; }", BSON( "c" << true ) ) ); - ASSERT_EQUALS( hashIt( o ), 501342939894575968LL ); - } - -} // namespace -} // namespace mongo +// Helper methods +long long hashIt(const BSONObj& object, int seed) { + return BSONElementHasher::hash64(object.firstElement(), seed); +} +long long hashIt(const BSONObj& object) { + int seed = 0; + return hashIt(object, seed); +} + +// Test different oids hash to different things +TEST(BSONElementHasher, DifferentOidsAreDifferentHashes) { + int seed = 0; + + long long int oidHash = + BSONElementHasher::hash64(BSONObjBuilder().genOID().obj().firstElement(), seed); + long long int oidHash2 = + BSONElementHasher::hash64(BSONObjBuilder().genOID().obj().firstElement(), seed); + long long int oidHash3 = + BSONElementHasher::hash64(BSONObjBuilder().genOID().obj().firstElement(), seed); + + ASSERT_NOT_EQUALS(oidHash, oidHash2); + ASSERT_NOT_EQUALS(oidHash, oidHash3); + ASSERT_NOT_EQUALS(oidHash3, oidHash2); +} + +// Test 32-bit ints, 64-bit ints, doubles hash to same thing +TEST(BSONElementHasher, ConsistentHashOfIntLongAndDouble) { + int i = 3; + BSONObj p1 = BSON("a" << i); + long long int intHash = hashIt(p1); + + long long int ilong = 3; + BSONObj p2 = BSON("a" << ilong); + long long int longHash = hashIt(p2); + + double d = 3.1; + BSONObj p3 = BSON("a" << d); + long long int doubleHash = hashIt(p3); + + ASSERT_EQUALS(intHash, longHash); + ASSERT_EQUALS(doubleHash, longHash); +} + +// Test different ints don't hash to same thing +TEST(BSONElementHasher, DifferentIntHashesDiffer) { + ASSERT_NOT_EQUALS(hashIt(BSON("a" << 3)), hashIt(BSON("a" << 4))); +} + +// Test seed makes a difference +TEST(BSONElementHasher, SeedMatters) { + ASSERT_NOT_EQUALS(hashIt(BSON("a" << 4), 0), hashIt(BSON("a" << 4), 1)); +} + +// Test strings hash to different things +TEST(BSONElementHasher, IntAndStringHashesDiffer) { + ASSERT_NOT_EQUALS(hashIt(BSON("a" << 3)), + hashIt(BSON("a" + << "3"))); +} + +// Test regexps and strings hash to different things +TEST(BSONElementHasher, RegexAndStringHashesDiffer) { + BSONObjBuilder builder; + + ASSERT_NOT_EQUALS(hashIt(BSON("a" + << "3")), + hashIt(builder.appendRegex("a", "3").obj())); +} + +// Test arrays and subobject hash to different things +TEST(BSONElementHasher, ArrayAndSubobjectHashesDiffer) { + ASSERT_NOT_EQUALS(hashIt(fromjson("{a : {'0' : 0 , '1' : 1}}")), + hashIt(fromjson("{a : [0,1]}"))); +} + +// Testing sub-document grouping +TEST(BSONElementHasher, SubDocumentGroupingHashesDiffer) { + ASSERT_NOT_EQUALS(hashIt(fromjson("{x : {a : {}, b : 1}}")), + hashIt(fromjson("{x : {a : {b : 1}}}"))); +} + +// Testing codeWscope scope squashing +TEST(BSONElementHasher, CodeWithScopeSquashesScopeIntsAndDoubles) { + int seed = 0; + + BSONObjBuilder b1; + b1.appendCodeWScope("a", "print('this is some stupid code')", BSON("a" << 3)); + BSONObj p10 = b1.obj(); + + BSONObjBuilder b2; + b2.appendCodeWScope("a", "print('this is some stupid code')", BSON("a" << 3.1)); + + BSONObjBuilder b3; + b3.appendCodeWScope("a", "print('this is \nsome stupider code')", BSON("a" << 3)); + ASSERT_EQUALS(BSONElementHasher::hash64(p10.firstElement(), seed), + BSONElementHasher::hash64(b2.obj().firstElement(), seed)); + ASSERT_NOT_EQUALS(BSONElementHasher::hash64(p10.firstElement(), seed), + BSONElementHasher::hash64(b3.obj().firstElement(), seed)); +} + +// Test some recursive squashing +TEST(BSONElementHasher, RecursiveSquashingIntsAndDoubles) { + ASSERT_EQUALS(hashIt(fromjson("{x : {a : 3 , b : [ 3.1, {c : 3 }]}}")), + hashIt(fromjson("{x : {a : 3.1 , b : [ 3, {c : 3.0}]}}"))); +} + +// Test minkey and maxkey don't hash to same thing +TEST(BSONElementHasher, MinKeyMaxKeyHashesDiffer) { + ASSERT_NOT_EQUALS(hashIt(BSON("a" << MAXKEY)), hashIt(BSON("a" << MINKEY))); +} + +// Test squashing very large doubles and very small doubles +TEST(BSONElementHasher, VeryLargeAndSmallDoubles) { + long long maxInt = std::numeric_limits::max(); + double smallerDouble = maxInt / 2; + double biggerDouble = ((double)maxInt) * ((double)maxInt); + ASSERT_NOT_EQUALS(hashIt(BSON("a" << maxInt)), hashIt(BSON("a" << smallerDouble))); + ASSERT_EQUALS(hashIt(BSON("a" << maxInt)), hashIt(BSON("a" << biggerDouble))); + + long long minInt = std::numeric_limits::min(); + double negativeDouble = -((double)maxInt) * ((double)maxInt); + ASSERT_EQUALS(hashIt(BSON("a" << minInt)), hashIt(BSON("a" << negativeDouble))); +} + +// Remaining tests are hard-coded checks to ensure the hash function is +// consistent across platforms and server versions +// +// All of the values in the remaining tests have been determined experimentally. +TEST(BSONElementHasher, HashIntOrLongOrDouble) { + BSONObj o = BSON("check" << 42); + ASSERT_EQUALS(hashIt(o), -944302157085130861LL); + o = BSON("check" << 42.123); + ASSERT_EQUALS(hashIt(o), -944302157085130861LL); + o = BSON("check" << (long long)42); + ASSERT_EQUALS(hashIt(o), -944302157085130861LL); + + o = BSON("check" << 0); + ASSERT_EQUALS(hashIt(o), 4854801880128277513LL); + o = BSON("check" << 0.456); + ASSERT_EQUALS(hashIt(o), 4854801880128277513LL); + o = BSON("check" << (long long)0); + ASSERT_EQUALS(hashIt(o), 4854801880128277513LL); + // NAN is treated as zero. + o = BSON("check" << std::numeric_limits::signaling_NaN()); + ASSERT_EQUALS(hashIt(o), 4854801880128277513LL); + o = BSON("check" << std::numeric_limits::quiet_NaN()); + ASSERT_EQUALS(hashIt(o), 4854801880128277513LL); + + o = BSON("check" << 1); + ASSERT_EQUALS(hashIt(o), 5902408780260971510LL); + o = BSON("check" << 1.987); + ASSERT_EQUALS(hashIt(o), 5902408780260971510LL); + o = BSON("check" << (long long)1); + ASSERT_EQUALS(hashIt(o), 5902408780260971510LL); + + o = BSON("check" << -1); + ASSERT_EQUALS(hashIt(o), 1140205862565771219LL); + o = BSON("check" << -1.789); + ASSERT_EQUALS(hashIt(o), 1140205862565771219LL); + o = BSON("check" << (long long)-1); + ASSERT_EQUALS(hashIt(o), 1140205862565771219LL); + + o = BSON("check" << std::numeric_limits::min()); + ASSERT_EQUALS(hashIt(o), 6165898260261354870LL); + o = BSON("check" << (double)std::numeric_limits::min()); + ASSERT_EQUALS(hashIt(o), 6165898260261354870LL); + o = BSON("check" << (long long)std::numeric_limits::min()); + ASSERT_EQUALS(hashIt(o), 6165898260261354870LL); + + o = BSON("check" << std::numeric_limits::max()); + ASSERT_EQUALS(hashIt(o), 1143184177162245883LL); + o = BSON("check" << (double)std::numeric_limits::max()); + ASSERT_EQUALS(hashIt(o), 1143184177162245883LL); + o = BSON("check" << (long long)std::numeric_limits::max()); + ASSERT_EQUALS(hashIt(o), 1143184177162245883LL); + + // Large/small double values. + ASSERT(std::numeric_limits::max() < std::numeric_limits::max()); + o = BSON("check" << std::numeric_limits::max()); + ASSERT_EQUALS(hashIt(o), 921523596458303250LL); + o = BSON("check" << std::numeric_limits::max()); // 9223372036854775807 + ASSERT_EQUALS(hashIt(o), 921523596458303250LL); + + // Have to create our own small double. + // std::numeric_limits::lowest() - Not available until C++11 + // std::numeric_limits::min() - Closest positive value to zero, not most negative. + double smallDouble = -std::numeric_limits::max(); + ASSERT(smallDouble < static_cast(std::numeric_limits::min())); + o = BSON("check" << smallDouble); + ASSERT_EQUALS(hashIt(o), 4532067210535695462LL); + o = BSON("check" << std::numeric_limits::min()); // -9223372036854775808 + ASSERT_EQUALS(hashIt(o), 4532067210535695462LL); +} + +TEST(BSONElementHasher, HashMinKey) { + BSONObj o = BSON("check" << MINKEY); + ASSERT_EQUALS(hashIt(o), 7961148599568647290LL); +} + +TEST(BSONElementHasher, HashMaxKey) { + BSONObj o = BSON("check" << MAXKEY); + ASSERT_EQUALS(hashIt(o), 5504842513779440750LL); +} + +TEST(BSONElementHasher, HashUndefined) { + BSONObj o = BSON("check" << BSONUndefined); + ASSERT_EQUALS(hashIt(o), 40158834000849533LL); +} + +TEST(BSONElementHasher, HashNull) { + BSONObj o = BSON("check" << BSONNULL); + ASSERT_EQUALS(hashIt(o), 2338878944348059895LL); +} + +TEST(BSONElementHasher, HashString) { + BSONObj o = BSON("check" + << "abc"); + ASSERT_EQUALS(hashIt(o), 8478485326885698097LL); + o = BSON("check" << BSONSymbol("abc")); + ASSERT_EQUALS(hashIt(o), 8478485326885698097LL); + + o = BSON("check" + << ""); + ASSERT_EQUALS(hashIt(o), 2049396243249673340LL); + o = BSON("check" << BSONSymbol("")); + ASSERT_EQUALS(hashIt(o), 2049396243249673340LL); +} + +TEST(BSONElementHasher, HashObject) { + BSONObj o = BSON("check" << BSON("a" + << "abc" + << "b" << 123LL)); + ASSERT_EQUALS(hashIt(o), 4771603801758380216LL); + + o = BSON("check" << BSONObj()); + ASSERT_EQUALS(hashIt(o), 7980500913326740417LL); +} + +TEST(BSONElementHasher, HashArray) { + BSONObj o = BSON("check" << BSON_ARRAY("bar" + << "baz" + << "qux")); + ASSERT_EQUALS(hashIt(o), -2938911267422831539LL); + + o = BSON("check" << BSONArray()); + ASSERT_EQUALS(hashIt(o), 8849948234993459283LL); +} + +TEST(BSONElementHasher, HashBinary) { + uint8_t bytes[] = {0, 1, 2, 3, 4, 6}; + BSONObj o = BSON("check" << BSONBinData(bytes, 6, BinDataGeneral)); + ASSERT_EQUALS(hashIt(o), 7252465090394235301LL); + + o = BSON("check" << BSONBinData(bytes, 6, bdtCustom)); + ASSERT_EQUALS(hashIt(o), 5736670452907618262LL); + + uint8_t uuidBytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + o = BSON("check" << BSONBinData(uuidBytes, 16, newUUID)); + ASSERT_EQUALS(hashIt(o), 6084661258071355978LL); +} + +TEST(BSONElementHasher, HashObjectId) { + BSONObj o = BSON("check" << OID("010203040506070809101112")); + ASSERT_EQUALS(hashIt(o), -5588663249627035708LL); + + o = BSON("check" << OID("000000000000000000000000")); + ASSERT_EQUALS(hashIt(o), -4293118519463489418LL); +} + +TEST(BSONElementHasher, HashBoolean) { + BSONObj o = BSON("check" << true); + ASSERT_EQUALS(hashIt(o), 6405873908747105701LL); + + o = BSON("check" << false); + ASSERT_EQUALS(hashIt(o), 6289544573401934092LL); +} + +TEST(BSONElementHasher, HashTimeStamp) { + BSONObjBuilder builder1; + BSONObjBuilder builder2; + + BSONObj o = BSON("check" << Date_t::fromMillisSinceEpoch(0x5566778811223344LL)); + ASSERT_EQUALS(hashIt(o), 4476222765095560467LL); + o = builder1.append("check", Timestamp(0x55667788LL, 0x11223344LL)).obj(); + ASSERT_EQUALS(hashIt(o), 4873046866288452390LL); + + o = BSON("check" << Date_t()); + ASSERT_EQUALS(hashIt(o), -1178696894582842035LL); + o = builder2.appendTimestamp("check", 0).obj(); + ASSERT_EQUALS(hashIt(o), -7867208682377458672LL); +} + +TEST(BSONElementHasher, HashRegEx) { + BSONObj o = BSON("check" << BSONRegEx("mongodb")); + ASSERT_EQUALS(hashIt(o), -7275792090268217043LL); + + o = BSON("check" << BSONRegEx(".*", "i")); + ASSERT_EQUALS(hashIt(o), 7095855029187981886LL); +} + +TEST(BSONElementHasher, HashDBRef) { + BSONObj o = BSON("check" << BSONDBRef("c", OID("010203040506070809101112"))); + ASSERT_EQUALS(hashIt(o), 940175826736461384LL); + + o = BSON("check" << BSONDBRef("db.c", OID("010203040506070809101112"))); + ASSERT_EQUALS(hashIt(o), 2426768198104018194LL); +} + +TEST(BSONElementHasher, HashCode) { + BSONObj o = BSON("check" << BSONCode("func f() { return 1; }")); + ASSERT_EQUALS(hashIt(o), 6861638109178014270LL); +} + +TEST(BSONElementHasher, HashCodeWScope) { + BSONObj o = BSON("check" << BSONCodeWScope("func f() { return 1; }", BSON("c" << true))); + ASSERT_EQUALS(hashIt(o), 501342939894575968LL); +} + +} // namespace +} // namespace mongo -- cgit v1.2.1