summaryrefslogtreecommitdiff
path: root/src/mongo/db/keypattern.h
diff options
context:
space:
mode:
authorAlberto Lerner <alerner@10gen.com>2013-01-16 10:36:40 -0500
committerAlberto Lerner <alerner@10gen.com>2013-01-16 10:36:40 -0500
commitfd1bc4895b51dc65185ac5fa633bb0435860b936 (patch)
treef6594a3da5b2b975daced141c862544b98171def /src/mongo/db/keypattern.h
parent45772b7c149307803a3b0052b2468e2b254e19be (diff)
downloadmongo-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.h36
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