From 2eadda6e0072d47ddea1dc24a1ed63abb995cdfe Mon Sep 17 00:00:00 2001 From: Hossein Ghahramanzadeh Date: Sat, 29 Jan 2022 08:05:03 +0100 Subject: Do constant time matching for exact match filters. --- googletest/src/gtest.cc | 19 ++++++++++++++++--- 1 file 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 #include // NOLINT #include +#include #include #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 patterns_; + std::vector glob_patterns_; + std::unordered_set exact_match_patterns_; }; class PositiveAndNegativeUnitTestFilter { -- cgit v0.12 From d6841c040d63b6e2bc716e365d1c60d26f23b1f5 Mon Sep 17 00:00:00 2001 From: Hossein Ghahramanzadeh Date: Sat, 5 Feb 2022 17:43:21 +0100 Subject: Apply requested changes by using std::inserter with move. --- googletest/src/gtest.cc | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index c04aac6..80fa0ea 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -726,13 +726,13 @@ static bool PatternMatchesString(const std::string& name_str, return true; } -static bool IsGlobPattern(const std::string& pattern) { +namespace { + +bool IsGlobPattern(const std::string& pattern) { return std::any_of(pattern.begin(), pattern.end(), [](const char c) { return c == '?' || c == '*'; }); } -namespace { - class UnitTestFilter { public: UnitTestFilter() = default; @@ -740,12 +740,14 @@ 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, ':', &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()); + std::vector all_patterns; + SplitString(filter, ':', &all_patterns); + const auto exact_match_patterns_begin = std::partition( + all_patterns.begin(), all_patterns.end(), &IsGlobPattern); + + glob_patterns_.reserve(exact_match_patterns_begin - all_patterns.begin()); + std::move(all_patterns.begin(), exact_match_patterns_begin, std::inserter(glob_patterns_, glob_patterns_.begin())); + std::move(exact_match_patterns_begin, all_patterns.end(), std::inserter(exact_match_patterns_, exact_match_patterns_.begin())); } // Returns true if and only if name matches at least one of the patterns in -- cgit v0.12