diff options
author | Alberto Lerner <alerner@10gen.com> | 2013-01-16 10:36:40 -0500 |
---|---|---|
committer | Alberto Lerner <alerner@10gen.com> | 2013-01-16 10:36:40 -0500 |
commit | fd1bc4895b51dc65185ac5fa633bb0435860b936 (patch) | |
tree | f6594a3da5b2b975daced141c862544b98171def /src/mongo/db/keypattern.h | |
parent | 45772b7c149307803a3b0052b2468e2b254e19be (diff) | |
download | mongo-fd1bc4895b51dc65185ac5fa633bb0435860b936.tar.gz |
SERVER-5710 Changed KeyPattern.hasField() sematics to consider dotted field prefixes.
Diffstat (limited to 'src/mongo/db/keypattern.h')
-rw-r--r-- | src/mongo/db/keypattern.h | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/src/mongo/db/keypattern.h b/src/mongo/db/keypattern.h index fae49bb931a..a25ce2b87e5 100644 --- a/src/mongo/db/keypattern.h +++ b/src/mongo/db/keypattern.h @@ -20,6 +20,7 @@ #include "mongo/base/string_data.h" #include "mongo/db/jsobj.h" +#include "mongo/platform/unordered_set.h" #include "mongo/util/mongoutils/str.h" namespace mongo { @@ -47,7 +48,10 @@ namespace mongo { */ class KeyPattern { public: - KeyPattern( const BSONObj& pattern ): _pattern( pattern ) {} + /* + * We are allowing implicit conversion from BSON + */ + KeyPattern( const BSONObj& pattern ); /* * Returns a BSON representation of this KeyPattern. @@ -55,10 +59,12 @@ namespace mongo { BSONObj toBSON() const { return _pattern; } /* - * Returns true if the given fieldname is the name of one element of the (potentially) - * compound key described by this KeyPattern. + * Returns true if the given fieldname is the (dotted prefix of the) name of one + * element of the (potentially) compound key described by this KeyPattern. */ - bool hasField( const StringData& fieldname ) const { return _pattern.hasField( fieldname ); } + bool hasField( const StringData& fieldname ) const { + return _prefixes.find( fieldname ) != _prefixes.end(); + } /* * Gets the element of this pattern corresponding to the given fieldname. @@ -159,12 +165,33 @@ namespace mongo { private: BSONObj _pattern; + + // Each field in the '_pattern' may be itself a dotted field. We store all the prefixes + // of each field here. For instance, if a pattern is { 'a.b.c': 1, x: 1 }, we'll store + // here 'a', 'a.b', 'a.b.c', and 'x'. + // + // Since we're indexing into '_pattern's field names, it must stay constant after + // constructed. + struct PrefixHasher { + size_t operator()( const StringData& strData ) const { + size_t result = 0; + const char* p = strData.rawData(); + for (size_t len = strData.size(); len > 0; len-- ) { + result = ( result * 131 ) + *p++; + } + return result; + } + }; + unordered_set<StringData, PrefixHasher> _prefixes; + bool isAscending( const BSONElement& fieldExpression ) const { return ( fieldExpression.isNumber() && fieldExpression.numberInt() == 1 ); } + bool isDescending( const BSONElement& fieldExpression ) const { return ( fieldExpression.isNumber() && fieldExpression.numberInt() == -1 ); } + bool isHashed( const BSONElement& fieldExpression ) const { return mongoutils::str::equals( fieldExpression.valuestrsafe() , "hashed" ); } @@ -178,5 +205,4 @@ namespace mongo { }; - } // namespace mongo |