summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHossein Ghahramanzadeh <hgsilverman@gmail.com>2022-01-29 07:05:03 (GMT)
committerHossein Ghahramanzadeh <hgsilverman@gmail.com>2022-01-31 18:22:37 (GMT)
commit2eadda6e0072d47ddea1dc24a1ed63abb995cdfe (patch)
treee66a18b662830fb28fcb53f395d851096a49d740
parent28e1da21d8d677bc98f12ccc7fc159ff19e8e817 (diff)
downloadgoogletest-2eadda6e0072d47ddea1dc24a1ed63abb995cdfe.zip
googletest-2eadda6e0072d47ddea1dc24a1ed63abb995cdfe.tar.gz
googletest-2eadda6e0072d47ddea1dc24a1ed63abb995cdfe.tar.bz2
Do constant time matching for exact match filters.
-rw-r--r--googletest/src/gtest.cc19
1 files changed, 16 insertions, 3 deletions
diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc
index 04266dc..c04aac6 100644
--- a/googletest/src/gtest.cc
+++ b/googletest/src/gtest.cc
@@ -50,6 +50,7 @@
#include <map>
#include <ostream> // NOLINT
#include <sstream>
+#include <unordered_set>
#include <vector>
#include "gtest/gtest-assertion-result.h"
@@ -725,6 +726,11 @@ static bool PatternMatchesString(const std::string& name_str,
return true;
}
+static bool IsGlobPattern(const std::string& pattern) {
+ return std::any_of(pattern.begin(), pattern.end(),
+ [](const char c) { return c == '?' || c == '*'; });
+}
+
namespace {
class UnitTestFilter {
@@ -734,13 +740,19 @@ class UnitTestFilter {
// Constructs a filter from a string of patterns separated by `:`.
explicit UnitTestFilter(const std::string& filter) {
// By design "" filter matches "" string.
- SplitString(filter, ':', &patterns_);
+ SplitString(filter, ':', &glob_patterns_);
+ const auto exact_match_pattern_begin = std::partition(
+ glob_patterns_.begin(), glob_patterns_.end(), &IsGlobPattern);
+ exact_match_patterns_.insert(exact_match_pattern_begin,
+ glob_patterns_.end());
+ glob_patterns_.erase(exact_match_pattern_begin, glob_patterns_.end());
}
// Returns true if and only if name matches at least one of the patterns in
// the filter.
bool MatchesName(const std::string& name) const {
- return std::any_of(patterns_.begin(), patterns_.end(),
+ return exact_match_patterns_.count(name) ||
+ std::any_of(glob_patterns_.begin(), glob_patterns_.end(),
[&name](const std::string& pattern) {
return PatternMatchesString(
name, pattern.c_str(),
@@ -749,7 +761,8 @@ class UnitTestFilter {
}
private:
- std::vector<std::string> patterns_;
+ std::vector<std::string> glob_patterns_;
+ std::unordered_set<std::string> exact_match_patterns_;
};
class PositiveAndNegativeUnitTestFilter {