Merge pull request #3746 from IYP-Programer-Yeah:use-constant-time-lookup-for-exact-match
PiperOrigin-RevId: 427179775 Change-Id: I9928be2421d559acf0e0f03643ce0b856b63f737
This commit is contained in:
commit
504eb98953
@ -50,6 +50,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <ostream> // NOLINT
|
#include <ostream> // NOLINT
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "gtest/gtest-assertion-result.h"
|
#include "gtest/gtest-assertion-result.h"
|
||||||
@ -727,6 +728,11 @@ static bool PatternMatchesString(const std::string& name_str,
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
bool IsGlobPattern(const std::string& pattern) {
|
||||||
|
return std::any_of(pattern.begin(), pattern.end(),
|
||||||
|
[](const char c) { return c == '?' || c == '*'; });
|
||||||
|
}
|
||||||
|
|
||||||
class UnitTestFilter {
|
class UnitTestFilter {
|
||||||
public:
|
public:
|
||||||
UnitTestFilter() = default;
|
UnitTestFilter() = default;
|
||||||
@ -734,13 +740,24 @@ class UnitTestFilter {
|
|||||||
// Constructs a filter from a string of patterns separated by `:`.
|
// Constructs a filter from a string of patterns separated by `:`.
|
||||||
explicit UnitTestFilter(const std::string& filter) {
|
explicit UnitTestFilter(const std::string& filter) {
|
||||||
// By design "" filter matches "" string.
|
// By design "" filter matches "" string.
|
||||||
SplitString(filter, ':', &patterns_);
|
std::vector<std::string> 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
|
// Returns true if and only if name matches at least one of the patterns in
|
||||||
// the filter.
|
// the filter.
|
||||||
bool MatchesName(const std::string& name) const {
|
bool MatchesName(const std::string& name) const {
|
||||||
return std::any_of(patterns_.begin(), patterns_.end(),
|
return exact_match_patterns_.count(name) > 0 ||
|
||||||
|
std::any_of(glob_patterns_.begin(), glob_patterns_.end(),
|
||||||
[&name](const std::string& pattern) {
|
[&name](const std::string& pattern) {
|
||||||
return PatternMatchesString(
|
return PatternMatchesString(
|
||||||
name, pattern.c_str(),
|
name, pattern.c_str(),
|
||||||
@ -749,7 +766,8 @@ class UnitTestFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::string> patterns_;
|
std::vector<std::string> glob_patterns_;
|
||||||
|
std::unordered_set<std::string> exact_match_patterns_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PositiveAndNegativeUnitTestFilter {
|
class PositiveAndNegativeUnitTestFilter {
|
||||||
|
Loading…
Reference in New Issue
Block a user