diff options
Diffstat (limited to 'src/mongo/db/hasher.cpp')
-rw-r--r-- | src/mongo/db/hasher.cpp | 120 |
1 files changed, 57 insertions, 63 deletions
diff --git a/src/mongo/db/hasher.cpp b/src/mongo/db/hasher.cpp index 3ae131a7dee..b0a22380bff 100644 --- a/src/mongo/db/hasher.cpp +++ b/src/mongo/db/hasher.cpp @@ -40,79 +40,73 @@ namespace mongo { - using std::unique_ptr; +using std::unique_ptr; - Hasher::Hasher( HashSeed seed ) : _seed( seed ) { - md5_init( &_md5State ); - md5_append( &_md5State , reinterpret_cast< const md5_byte_t * >( & _seed ) , sizeof( _seed ) ); - } +Hasher::Hasher(HashSeed seed) : _seed(seed) { + md5_init(&_md5State); + md5_append(&_md5State, reinterpret_cast<const md5_byte_t*>(&_seed), sizeof(_seed)); +} - void Hasher::addData( const void * keyData , size_t numBytes ) { - md5_append( &_md5State , static_cast< const md5_byte_t * >( keyData ), numBytes ); - } +void Hasher::addData(const void* keyData, size_t numBytes) { + md5_append(&_md5State, static_cast<const md5_byte_t*>(keyData), numBytes); +} - void Hasher::finish( HashDigest out ) { - md5_finish( &_md5State , out ); - } +void Hasher::finish(HashDigest out) { + md5_finish(&_md5State, out); +} - long long int BSONElementHasher::hash64( const BSONElement& e , HashSeed seed ){ - unique_ptr<Hasher> h( HasherFactory::createHasher( seed ) ); - recursiveHash( h.get() , e , false ); - HashDigest d; - h->finish(d); - //HashDigest is actually 16 bytes, but we just get 8 via truncation - // NOTE: assumes little-endian - return *reinterpret_cast< long long int * >( d ); - } +long long int BSONElementHasher::hash64(const BSONElement& e, HashSeed seed) { + unique_ptr<Hasher> h(HasherFactory::createHasher(seed)); + recursiveHash(h.get(), e, false); + HashDigest d; + h->finish(d); + // HashDigest is actually 16 bytes, but we just get 8 via truncation + // NOTE: assumes little-endian + return *reinterpret_cast<long long int*>(d); +} - void BSONElementHasher::recursiveHash( Hasher* h , - const BSONElement& e , - bool includeFieldName ) { +void BSONElementHasher::recursiveHash(Hasher* h, const BSONElement& e, bool includeFieldName) { + int canonicalType = e.canonicalType(); + h->addData(&canonicalType, sizeof(canonicalType)); - int canonicalType = e.canonicalType(); - h->addData( &canonicalType , sizeof( canonicalType ) ); + if (includeFieldName) { + h->addData(e.fieldName(), e.fieldNameSize()); + } - if ( includeFieldName ){ - h->addData( e.fieldName() , e.fieldNameSize() ); + if (!e.mayEncapsulate()) { + // if there are no embedded objects (subobjects or arrays), + // compute the hash, squashing numeric types to 64-bit ints + if (e.isNumber()) { + long long int i = e.safeNumberLong(); // well-defined for troublesome doubles + h->addData(&i, sizeof(i)); + } else { + h->addData(e.value(), e.valuesize()); } - - if ( !e.mayEncapsulate() ){ - //if there are no embedded objects (subobjects or arrays), - //compute the hash, squashing numeric types to 64-bit ints - if ( e.isNumber() ){ - long long int i = e.safeNumberLong(); //well-defined for troublesome doubles - h->addData( &i , sizeof( i ) ); - } - else { - h->addData( e.value() , e.valuesize() ); - } + } else { + // else identify the subobject. + // hash any preceding stuff (in the case of codeWscope) + // then each sub-element + // then finish with the EOO element. + BSONObj b; + if (e.type() == CodeWScope) { + h->addData(e.codeWScopeCode(), e.codeWScopeCodeLen()); + b = e.codeWScopeObject(); + } else { + b = e.embeddedObject(); } - else { - //else identify the subobject. - //hash any preceding stuff (in the case of codeWscope) - //then each sub-element - //then finish with the EOO element. - BSONObj b; - if ( e.type() == CodeWScope ) { - h->addData( e.codeWScopeCode() , e.codeWScopeCodeLen() ); - b = e.codeWScopeObject(); - } - else { - b = e.embeddedObject(); - } - BSONObjIterator i(b); - while( i.moreWithEOO() ) { - BSONElement el = i.next(); - recursiveHash( h , el , true ); - } + BSONObjIterator i(b); + while (i.moreWithEOO()) { + BSONElement el = i.next(); + recursiveHash(h, el, true); } } +} - struct HasherUnitTest : public StartupTest { - void run() { - // Hard-coded check to ensure the hash function is consistent across platforms - BSONObj o = BSON( "check" << 42 ); - verify( BSONElementHasher::hash64( o.firstElement(), 0 ) == -944302157085130861LL ); - } - } hasherUnitTest; +struct HasherUnitTest : public StartupTest { + void run() { + // Hard-coded check to ensure the hash function is consistent across platforms + BSONObj o = BSON("check" << 42); + verify(BSONElementHasher::hash64(o.firstElement(), 0) == -944302157085130861LL); + } +} hasherUnitTest; } |