diff options
author | Mathias Stearn <mathias@10gen.com> | 2010-03-01 17:57:27 -0500 |
---|---|---|
committer | Mathias Stearn <mathias@10gen.com> | 2010-03-01 19:53:43 -0500 |
commit | a72123ced13783728a9c8fbc4bafe3992f8b40d6 (patch) | |
tree | fd4b7c7af6bab102560c2aada6283ffff270ccb5 | |
parent | dc54b5b6e058ec82ec6e0777ba6f90e3631ceebe (diff) | |
download | mongo-a72123ced13783728a9c8fbc4bafe3992f8b40d6.tar.gz |
better regex prefix matching
-rw-r--r-- | db/matcher.cpp | 46 | ||||
-rw-r--r-- | db/matcher.h | 1 |
2 files changed, 21 insertions, 26 deletions
diff --git a/db/matcher.cpp b/db/matcher.cpp index 68379e7fe82..01c9900f2b1 100644 --- a/db/matcher.cpp +++ b/db/matcher.cpp @@ -167,38 +167,26 @@ namespace mongo { void Matcher::addRegex( const BSONElement &e, const char *fieldName, bool isNot ) { if ( fieldName == 0 ) fieldName = e.fieldName(); - const char* regex = e.regex(); - const char* flags = e.regexFlags(); - - if (!isNot){ //TODO something smarter - bool purePrefix; - string prefix = simpleRegex(regex, flags, &purePrefix); - if (purePrefix){ - { - shared_ptr< BSONObjBuilder > b( new BSONObjBuilder() ); - _builders.push_back( b ); - *b << fieldName << prefix; - addBasic(b->done().firstElement(), BSONObj::GTE , isNot); - } - { - shared_ptr< BSONObjBuilder > b( new BSONObjBuilder() ); - _builders.push_back( b ); - *b << fieldName << simpleRegexEnd(prefix); - addBasic(b->done().firstElement(), BSONObj::LT , isNot); - } - return; - } - } if ( nRegex >= 4 ) { out() << "ERROR: too many regexes in query" << endl; } else { + const char* regex = e.regex(); + const char* flags = e.regexFlags(); + RegexMatcher& rm = regexs[nRegex]; rm.re = new pcrecpp::RE(regex, flags2options(flags)); rm.fieldName = fieldName; rm.isNot = isNot; nRegex++; + + if (!isNot){ //TODO something smarter + bool purePrefix; + string prefix = simpleRegex(regex, flags, &purePrefix); + if (purePrefix) + rm.prefix = prefix; + } } } @@ -634,10 +622,16 @@ namespace mongo { extern int dump; inline bool regexMatches(RegexMatcher& rm, const BSONElement& e) { - if ( e.type() == String || e.type() == Symbol ) - return rm.re->PartialMatch(e.valuestr()); - else - return false; + switch (e.type()){ + case String: + case Symbol: + if (rm.prefix.empty()) + return rm.re->PartialMatch(e.valuestr()); + else + return !strncmp(e.valuestr(), rm.prefix.c_str(), rm.prefix.size()); + default: + return false; + } } /* See if an object matches the query. diff --git a/db/matcher.h b/db/matcher.h index 9f779fdcb50..2959624b493 100644 --- a/db/matcher.h +++ b/db/matcher.h @@ -31,6 +31,7 @@ namespace mongo { class RegexMatcher { public: const char *fieldName; + string prefix; pcrecpp::RE *re; bool isNot; RegexMatcher() : re( 0 ), isNot() {} |