Skip to content

Commit 504eb98

Browse files
Merge pull request #3746 from IYP-Programer-Yeah:use-constant-time-lookup-for-exact-match
PiperOrigin-RevId: 427179775 Change-Id: I9928be2421d559acf0e0f03643ce0b856b63f737
2 parents 43efa0a + d6841c0 commit 504eb98

File tree

1 file changed

+21
-3
lines changed

1 file changed

+21
-3
lines changed

googletest/src/gtest.cc

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#include <map>
5151
#include <ostream> // NOLINT
5252
#include <sstream>
53+
#include <unordered_set>
5354
#include <vector>
5455

5556
#include "gtest/gtest-assertion-result.h"
@@ -727,20 +728,36 @@ static bool PatternMatchesString(const std::string& name_str,
727728

728729
namespace {
729730

731+
bool IsGlobPattern(const std::string& pattern) {
732+
return std::any_of(pattern.begin(), pattern.end(),
733+
[](const char c) { return c == '?' || c == '*'; });
734+
}
735+
730736
class UnitTestFilter {
731737
public:
732738
UnitTestFilter() = default;
733739

734740
// Constructs a filter from a string of patterns separated by `:`.
735741
explicit UnitTestFilter(const std::string& filter) {
736742
// By design "" filter matches "" string.
737-
SplitString(filter, ':', &patterns_);
743+
std::vector<std::string> all_patterns;
744+
SplitString(filter, ':', &all_patterns);
745+
const auto exact_match_patterns_begin = std::partition(
746+
all_patterns.begin(), all_patterns.end(), &IsGlobPattern);
747+
748+
glob_patterns_.reserve(exact_match_patterns_begin - all_patterns.begin());
749+
std::move(all_patterns.begin(), exact_match_patterns_begin,
750+
std::inserter(glob_patterns_, glob_patterns_.begin()));
751+
std::move(
752+
exact_match_patterns_begin, all_patterns.end(),
753+
std::inserter(exact_match_patterns_, exact_match_patterns_.begin()));
738754
}
739755

740756
// Returns true if and only if name matches at least one of the patterns in
741757
// the filter.
742758
bool MatchesName(const std::string& name) const {
743-
return std::any_of(patterns_.begin(), patterns_.end(),
759+
return exact_match_patterns_.count(name) > 0 ||
760+
std::any_of(glob_patterns_.begin(), glob_patterns_.end(),
744761
[&name](const std::string& pattern) {
745762
return PatternMatchesString(
746763
name, pattern.c_str(),
@@ -749,7 +766,8 @@ class UnitTestFilter {
749766
}
750767

751768
private:
752-
std::vector<std::string> patterns_;
769+
std::vector<std::string> glob_patterns_;
770+
std::unordered_set<std::string> exact_match_patterns_;
753771
};
754772

755773
class PositiveAndNegativeUnitTestFilter {

0 commit comments

Comments
 (0)