diff options
author | Eliot Horowitz <eliot@10gen.com> | 2012-10-15 01:53:17 -0400 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2012-10-15 18:07:06 -0400 |
commit | dcbef4a3e5367c09182e05455e3cca4b70b8a37a (patch) | |
tree | 275ae9546f6cf4cb65a7911fb90daaef6a99d9a5 | |
parent | 3a15fac7d854802c99ed287ba2d8f0bd6d09212b (diff) | |
download | mongo-dcbef4a3e5367c09182e05455e3cca4b70b8a37a.tar.gz |
add new test namespacestring_test
add methods to hash and compare strings that are full namespaces
but only hash/compare the db part
-rw-r--r-- | src/mongo/SConscript | 3 | ||||
-rw-r--r-- | src/mongo/db/namespacestring.h | 65 | ||||
-rw-r--r-- | src/mongo/db/namespacestring_test.cpp | 65 | ||||
-rw-r--r-- | src/mongo/dbtests/basictests.cpp | 14 |
4 files changed, 133 insertions, 14 deletions
diff --git a/src/mongo/SConscript b/src/mongo/SConscript index a41318001df..c29bfcffcf2 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -65,6 +65,9 @@ env.CppUnitTest('bson_field_test', ['bson/bson_field_test.cpp'], env.CppUnitTest('bson_validate_test', ['bson/bson_validate_test.cpp'], LIBDEPS=['bson']) +env.CppUnitTest('namespacestring_test', ['db/namespacestring_test.cpp'], + LIBDEPS=['bson']) + commonFiles = [ "pch.cpp", "buildinfo.cpp", "db/hasher.cpp", diff --git a/src/mongo/db/namespacestring.h b/src/mongo/db/namespacestring.h index 92421e2d453..5d0832750fc 100644 --- a/src/mongo/db/namespacestring.h +++ b/src/mongo/db/namespacestring.h @@ -159,5 +159,70 @@ namespace mongo { massert(10088, "nsToDatabase: ns too long", i < (size_t)MaxDatabaseNameLen); return ns.substr( 0 , i ); } + + /** + * NamespaceDBHash and NamespaceDBEquals allow you to do something like + * unordered_map<string,int,NamespaceDBHash,NamespaceDBEquals> + * and use the full namespace for the string + * but comparisons are done only on the db piece + */ + + /** + * this can change, do not store on disk + */ + inline int nsDBHash( const string& ns ) { + int hash = 7; + for ( size_t i = 0; i < ns.size(); i++ ) { + if ( ns[i] == '.' ) + break; + hash += 11 * ( ns[i] ); + hash *= 3; + } + return hash; + } + + inline bool nsDBEquals( const string& a, const string& b ) { + for ( size_t i = 0; i < a.size(); i++ ) { + + if ( a[i] == '.' ) { + // b has to either be done or a '.' + + if ( b.size() == i ) + return true; + + if ( b[i] == '.' ) + return true; + + return false; + } + + // a is another character + if ( b.size() == i ) + return false; + + if ( b[i] != a[i] ) + return false; + } + + // a is done + // make sure b is done + if ( b.size() == a.size() || + b[a.size()] == '.' ) + return true; + + return false; + } + + struct NamespaceDBHash { + int operator()( const string& ns ) const { + return nsDBHash( ns ); + } + }; + struct NamespaceDBEquals { + bool operator()( const string& a, const string& b ) const { + return nsDBEquals( a, b ); + } + }; + } diff --git a/src/mongo/db/namespacestring_test.cpp b/src/mongo/db/namespacestring_test.cpp new file mode 100644 index 00000000000..11428e969ba --- /dev/null +++ b/src/mongo/db/namespacestring_test.cpp @@ -0,0 +1,65 @@ +// namespacestring_test.cpp + +/* Copyright 2012 10gen Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mongo/unittest/unittest.h" + +#include "mongo/db/namespacestring.h" + +namespace mongo { + + + TEST( NamespaceStringTest, DatabaseValidNames ) { + ASSERT( NamespaceString::validDBName( "foo" ) ); + ASSERT( ! NamespaceString::validDBName( "foo/bar" ) ); + ASSERT( ! NamespaceString::validDBName( "foo bar" ) ); + ASSERT( ! NamespaceString::validDBName( "foo.bar" ) ); + + ASSERT( NamespaceString::normal( "asdads" ) ); + ASSERT( ! NamespaceString::normal( "asda$ds" ) ); + ASSERT( NamespaceString::normal( "local.oplog.$main" ) ); + } + + TEST( NamespaceStringTest, DBHash ) { + ASSERT_EQUALS( nsDBHash( "foo" ), nsDBHash( "foo" ) ); + ASSERT_EQUALS( nsDBHash( "foo" ), nsDBHash( "foo.a" ) ); + ASSERT_EQUALS( nsDBHash( "foo" ), nsDBHash( "foo." ) ); + + ASSERT_EQUALS( nsDBHash( "" ), nsDBHash( "" ) ); + ASSERT_EQUALS( nsDBHash( "" ), nsDBHash( ".a" ) ); + ASSERT_EQUALS( nsDBHash( "" ), nsDBHash( "." ) ); + + ASSERT_NOT_EQUALS( nsDBHash( "foo" ), nsDBHash( "food" ) ); + ASSERT_NOT_EQUALS( nsDBHash( "foo." ), nsDBHash( "food" ) ); + ASSERT_NOT_EQUALS( nsDBHash( "foo.d" ), nsDBHash( "food" ) ); + } + +#define testEqualsBothWays(X,Y) ASSERT_TRUE( nsDBEquals( (X), (Y) ) ); ASSERT_TRUE( nsDBEquals( (Y), (X) ) ); +#define testNotEqualsBothWays(X,Y) ASSERT_FALSE( nsDBEquals( (X), (Y) ) ); ASSERT_FALSE( nsDBEquals( (Y), (X) ) ); + + TEST( NamespaceStringTest, DBEquals ) { + testEqualsBothWays( "foo" , "foo" ); + testEqualsBothWays( "foo" , "foo.a" ); + testEqualsBothWays( "foo.a" , "foo.a" ); + testEqualsBothWays( "foo.a" , "foo.b" ); + + testNotEqualsBothWays( "foo" , "bar" ); + testNotEqualsBothWays( "foo" , "food" ); + testNotEqualsBothWays( "foo." , "food" ); + } + +} + diff --git a/src/mongo/dbtests/basictests.cpp b/src/mongo/dbtests/basictests.cpp index ded62a13049..1085fd2fc44 100644 --- a/src/mongo/dbtests/basictests.cpp +++ b/src/mongo/dbtests/basictests.cpp @@ -499,20 +499,6 @@ namespace BasicTests { } }; - class DatabaseValidNames { - public: - void run() { - ASSERT( NamespaceString::validDBName( "foo" ) ); - ASSERT( ! NamespaceString::validDBName( "foo/bar" ) ); - ASSERT( ! NamespaceString::validDBName( "foo bar" ) ); - ASSERT( ! NamespaceString::validDBName( "foo.bar" ) ); - - ASSERT( NamespaceString::normal( "asdads" ) ); - ASSERT( ! NamespaceString::normal( "asda$ds" ) ); - ASSERT( NamespaceString::normal( "local.oplog.$main" ) ); - } - }; - class DatabaseOwnsNS { public: void run() { |