summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEliot Horowitz <eliot@10gen.com>2012-10-15 01:53:17 -0400
committerEliot Horowitz <eliot@10gen.com>2012-10-15 18:07:06 -0400
commitdcbef4a3e5367c09182e05455e3cca4b70b8a37a (patch)
tree275ae9546f6cf4cb65a7911fb90daaef6a99d9a5
parent3a15fac7d854802c99ed287ba2d8f0bd6d09212b (diff)
downloadmongo-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/SConscript3
-rw-r--r--src/mongo/db/namespacestring.h65
-rw-r--r--src/mongo/db/namespacestring_test.cpp65
-rw-r--r--src/mongo/dbtests/basictests.cpp14
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() {