summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/base/SConscript2
-rw-r--r--src/mongo/base/fast_string_key.h86
-rw-r--r--src/mongo/base/fast_string_key_test.cpp202
-rw-r--r--src/mongo/db/projection.cpp6
-rw-r--r--src/mongo/db/projection.h5
5 files changed, 5 insertions, 296 deletions
diff --git a/src/mongo/base/SConscript b/src/mongo/base/SConscript
index 9b0bdeacb53..104d1a555cb 100644
--- a/src/mongo/base/SConscript
+++ b/src/mongo/base/SConscript
@@ -31,5 +31,3 @@ env.CppUnitTest('parse_number_test', ['parse_number_test.cpp'], LIBDEPS=['base']
env.CppUnitTest('initializer_test', ['initializer_test.cpp'], LIBDEPS=['base'])
-env.CppUnitTest('fast_string_key_test', ['fast_string_key_test.cpp'], LIBDEPS=[])
-
diff --git a/src/mongo/base/fast_string_key.h b/src/mongo/base/fast_string_key.h
deleted file mode 100644
index 6e6c724d8d5..00000000000
--- a/src/mongo/base/fast_string_key.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* 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.
- */
-
-#pragma once
-
-#include <string>
-#include <boost/functional/hash.hpp>
-
-#include "mongo/base/string_data.h"
-
-namespace mongo {
-
- /** This class should be a mostly drop-in replacement for std::string as keys in maps and sets.
- * The main advantage over std::string is that you can do lookups using c-strings without
- * constructing a std::string and copying the query to a heap-allocated buffer.
- *
- * NOTE: This is not a general purpose class. You should never create variables of this type.
- *
- * WARNING: this class does not support string with embedded NUL bytes. It is most useful for
- * holding the equivalent of BSONObj fieldNames which do not support NUL either.
- */
- class FastStringKey {
- public:
- /*implicit*/ FastStringKey(const char* s) : _str(s) {}
- /*implicit*/ FastStringKey(const std::string& s) : _str(s.c_str()) {}
- /*implicit*/ FastStringKey(const StringData& s) : _str(s.data()) {}
-
- /** This should only be called by containers when adding a new element
- *
- * This class assumes that lookups in containers don't copy the query object. This isn't
- * guaranteed by the standard, but based on the required signatures no sane implementation
- * would. If some STL implementation did copy the query object, we'd be no worse off than
- * with just using std::string.
- */
- FastStringKey(const FastStringKey& source) {
- if (source._holder)
- _holder = source._holder;
- else
- _holder = boost::shared_ptr<char>(strdup(source._str), free);
-
- _str = _holder.get();
- }
-
-
- const char* c_str() const { return _str; }
-
- bool operator < (const FastStringKey& rhs) const { return strcmp(_str, rhs._str) < 0; }
- bool operator == (const FastStringKey& rhs) const { return strcmp(_str, rhs._str) == 0; }
-
- /** This class is compliant with the TR1 std::hash interface.
- * To use it, use unordered_set<FastStringKey, FastStringKey::hash>.
- * We can't specialize std::hash easily because it may be called std::tr1::hash
- */
- class hash {
- public:
- size_t operator() (const FastStringKey& str) const {
- const char* begin = str.c_str();
- const char* end = begin + strlen(begin);
-
- // TODO maybe consider alternate hashing algorithms
- return boost::hash_range(begin, end);
- }
- };
-
- protected: // only subclass is in fast_string_key_test.cpp
- bool isOwned() const { return _holder != NULL; }
-
- private:
- const char* _str;
- boost::shared_ptr<char> _holder; // NULL if not copied
-
- void operator= (const FastStringKey&); // not defined
- };
-}
diff --git a/src/mongo/base/fast_string_key_test.cpp b/src/mongo/base/fast_string_key_test.cpp
deleted file mode 100644
index 741b9c30627..00000000000
--- a/src/mongo/base/fast_string_key_test.cpp
+++ /dev/null
@@ -1,202 +0,0 @@
-/* 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.
- */
-
-/**
- * Unit tests of the FastStringKey type.
- */
-
-#include <mongo/pch.h> // needed for mongoutils str.h
-
-#include "mongo/base/fast_string_key.h"
-
-#include <map>
-#include <set>
-#include <boost/unordered_map.hpp>
-#include <boost/unordered_set.hpp>
-
-#include "mongo/platform/unordered_map.h"
-#include "mongo/platform/unordered_set.h"
-#include "mongo/util/mongoutils/str.h"
-#include "mongo/unittest/unittest.h"
-
-namespace {
- using namespace std;
- using namespace mongo;
- using namespace mongoutils;
-
- // This does extra checking that the map/set types use this class as expected
- class FastStringKeyStrict : public FastStringKey {
- public:
- // can't use "using" on constructor
- /*implicit*/ FastStringKeyStrict(const char* s) : FastStringKey(s) {}
- /*implicit*/ FastStringKeyStrict(const std::string& s) : FastStringKey(s) {}
- /*implicit*/ FastStringKeyStrict(const StringData& s) : FastStringKey(s) {}
-
- FastStringKeyStrict(const FastStringKeyStrict& s) : FastStringKey(s) {
- ASSERT_TRUE(allow_FastStringKey_copies);
- }
-
- bool operator < (const FastStringKeyStrict& rhs) const {
- // at least one operand should be owned since it is in the map/set
- ASSERT_TRUE(this->isOwned() || rhs.isOwned());
-
- return FastStringKey::operator<(rhs);
- }
- bool operator == (const FastStringKeyStrict& rhs) const {
- // at least one operand should be owned since it is in the map/set
- ASSERT_TRUE(this->isOwned() || rhs.isOwned());
-
- return FastStringKey::operator==(rhs);
- }
-
- friend class DisallowCopies;
- class DisallowCopies {
- public:
- DisallowCopies() { FastStringKeyStrict::allow_FastStringKey_copies = false; }
- ~DisallowCopies() { FastStringKeyStrict::allow_FastStringKey_copies = true; }
- };
-
- private:
- void assertOneOwned(const FastStringKeyStrict& rhs) const {
- }
-
- static bool allow_FastStringKey_copies;
- };
- bool FastStringKeyStrict::allow_FastStringKey_copies = true;
-
- template <typename Map>
- void fillMap(Map& m) {
- m[""] = 1;
- m["a"] = 1;
- m["aa"] = 1;
- m["bb"] = 1;
- m[string("b")] = 1;
- m[StringData("abracadabra")] = 1;
- }
-
- template <typename Map>
- void fillMapPairs(Map& m) {
- m.insert(make_pair("", 1));
- m.insert(make_pair("a", 1));
- m.insert(make_pair("aa", 1));
- m.insert(make_pair("bb", 1));
- m.insert(make_pair(string("b"), 1));
- m.insert(make_pair(StringData("abracadabra"), 1));
- }
-
- template <typename Set>
- void fillSet(Set& s) {
- s.insert("");
- s.insert("a");
- s.insert("aa");
- s.insert("bb");
- s.insert(string("b"));
- s.insert(StringData("abracadabra"));
- }
-
- template <typename StringType, typename MapOrSet>
- void checkGeneric(const MapOrSet& ms, unsigned fills) {
- FastStringKeyStrict::DisallowCopies no_copying_while_reading;
-
- ASSERT_EQUALS(ms.size(), 6u * fills);
-
- ASSERT_EQUALS(ms.count(StringType("")), fills);
- ASSERT_EQUALS(ms.count(StringType("a")), fills);
- ASSERT_EQUALS(ms.count(StringType("aa")), fills);
- ASSERT_EQUALS(ms.count(StringType("bb")), fills);
- ASSERT_EQUALS(ms.count(StringType("b")), fills);
- ASSERT_EQUALS(ms.count(StringType("abracadabra")), fills);
-
- ASSERT_EQUALS(ms.count(StringType("no such key")), 0u);
- }
-
- // Makes the TEMPLATE_TEST_INSTANCEs below easier to read
- enum IsMulti{Single=false, Multi=true};
-
- template<typename ContainerType, void(*fillFunc)(ContainerType&), IsMulti isMulti>
- TEMPLATE_TEST(FastStringKeyTest, TestContainer) {
- ContainerType cont;
-
- fillFunc(cont);
- unsigned fills = 1;
-
- checkGeneric<const char*>(cont, fills);
- checkGeneric<string>(cont, fills);
- checkGeneric<StringData>(cont, fills);
-
- fillFunc(cont);
- if (isMulti) fills++;
-
- checkGeneric<const char*>(cont, isMulti?2:1);
- checkGeneric<string>(cont, isMulti?2:1);
- checkGeneric<StringData>(cont, isMulti?2:1);
- }
- // Map tests
- TEMPLATE_TEST_INSTANCE(FastStringKeyTest, TestContainer,
- map<FastStringKeyStrict, int>,
- fillMap, Single);
- TEMPLATE_TEST_INSTANCE(FastStringKeyTest, TestContainer,
- multimap<FastStringKeyStrict, int>,
- fillMapPairs, Multi);
- TEMPLATE_TEST_INSTANCE(FastStringKeyTest, TestContainer,
- unordered_map<FastStringKeyStrict, int, FastStringKey::hash>,
- fillMap, Single);
- TEMPLATE_TEST_INSTANCE(FastStringKeyTest, TestContainer,
- boost::unordered_map<FastStringKeyStrict, int, FastStringKey::hash>,
- fillMap, Single);
- TEMPLATE_TEST_INSTANCE(FastStringKeyTest, TestContainer,
- boost::unordered_multimap<FastStringKeyStrict, int, FastStringKey::hash>,
- fillMapPairs, Multi);
-
- // Set tests
- TEMPLATE_TEST_INSTANCE(FastStringKeyTest, TestContainer,
- set<FastStringKeyStrict>,
- fillSet, Single);
- TEMPLATE_TEST_INSTANCE(FastStringKeyTest, TestContainer,
- multiset<FastStringKeyStrict>,
- fillSet, Multi);
- TEMPLATE_TEST_INSTANCE(FastStringKeyTest, TestContainer,
- unordered_set<FastStringKeyStrict, FastStringKey::hash>,
- fillSet, Single);
- TEMPLATE_TEST_INSTANCE(FastStringKeyTest, TestContainer,
- boost::unordered_set<FastStringKeyStrict, FastStringKey::hash>,
- fillSet, Single);
- TEMPLATE_TEST_INSTANCE(FastStringKeyTest, TestContainer,
- boost::unordered_multiset<FastStringKeyStrict, FastStringKey::hash>,
- fillSet, Multi);
-
- TEST(FastStringKeyTest, HashUniqueness) {
- // Test all 0 and 1 char strings for hash uniqueness
- // This test isn't strictly guaranteed to pass, but if it doesn't we would want to know.
- // If it passes once, it will continue passing unless the hash function changes.
-
- unordered_map<size_t, string> hashes;
-
- for (char c='\0'; c < '\x7f'; c++) {
- const char str[] = {c, '\0'};
- const size_t hash = FastStringKey::hash()(str);
-
- if (hashes.count(hash)) {
- FAIL(str::stream() << "duplicate hash detected!"
- << " hash: " << hash
- << " str1: \"" << hashes[hash] << "\" " << int(hashes[hash][0])
- << " str2: \"" << str << "\" " << int(str[0])
- );
- }
-
- hashes[hash] = str;
- }
- }
-}
diff --git a/src/mongo/db/projection.cpp b/src/mongo/db/projection.cpp
index 08960de6b1a..6c598f6daa7 100644
--- a/src/mongo/db/projection.cpp
+++ b/src/mongo/db/projection.cpp
@@ -176,8 +176,8 @@ namespace mongo {
MatchDetails arrayDetails;
arrayDetails.requestElemMatchKey();
if ( matcher->second->matches( in, &arrayDetails ) ) {
- log(4) << "Matched array on field: " << matcher->first.c_str() << endl
- << " from array: " << in.getField( matcher->first.c_str() ) << endl
+ log(4) << "Matched array on field: " << matcher->first << endl
+ << " from array: " << in.getField( matcher->first ) << endl
<< " in object: " << in << endl
<< " at position: " << arrayDetails.elemMatchKey() << endl;
FieldMap::const_iterator field = _fields.find( e.fieldName() );
@@ -192,7 +192,7 @@ namespace mongo {
arrayDetails.elemMatchKey() ).eoo() );
a.append( in.getField( e.fieldName() ).Obj()
.getField( arrayDetails.elemMatchKey() ) );
- o.appendArray( matcher->first.c_str(), a.arr() );
+ o.appendArray( matcher->first, a.arr() );
append( b, o.done().firstElement(), details, arrayOpType );
}
}
diff --git a/src/mongo/db/projection.h b/src/mongo/db/projection.h
index 7f31601d7bb..c4844f7a146 100644
--- a/src/mongo/db/projection.h
+++ b/src/mongo/db/projection.h
@@ -18,7 +18,6 @@
#pragma once
#include "mongo/pch.h"
-#include "mongo/base/fast_string_key.h"
#include "jsobj.h"
namespace mongo {
@@ -141,7 +140,7 @@ namespace mongo {
bool _special; // true if this level can't be skipped or included without recursing
//TODO: benchmark vector<pair> vs map
- typedef map<FastStringKey, boost::shared_ptr<Projection> > FieldMap;
+ typedef map<string, boost::shared_ptr<Projection> > FieldMap;
FieldMap _fields;
BSONObj _source;
bool _includeID;
@@ -151,7 +150,7 @@ namespace mongo {
int _limit;
// used for $elemMatch and positional operator ($)
- typedef map<FastStringKey, shared_ptr<Matcher> > Matchers;
+ typedef map<string, shared_ptr<Matcher> > Matchers;
Matchers _matchers;
ArrayOpType _arrayOpType;