summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Stearn <mathias@10gen.com>2010-03-01 17:57:27 -0500
committerMathias Stearn <mathias@10gen.com>2010-03-01 19:53:43 -0500
commita72123ced13783728a9c8fbc4bafe3992f8b40d6 (patch)
treefd4b7c7af6bab102560c2aada6283ffff270ccb5
parentdc54b5b6e058ec82ec6e0777ba6f90e3631ceebe (diff)
downloadmongo-a72123ced13783728a9c8fbc4bafe3992f8b40d6.tar.gz
better regex prefix matching
-rw-r--r--db/matcher.cpp46
-rw-r--r--db/matcher.h1
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() {}