This source file includes following definitions.
- IsRegexCriterion
- IsOriginAndPathRegexCriterion
- string_pattern_
- string_pattern_
- string_pattern_
- IsFullURLCondition
- IsRegexCondition
- IsOriginAndPathRegexCondition
- IsMatch
- CanonicalizeURLForComponentSearches
- CreateHostPrefixCondition
- CreateHostSuffixCondition
- CreateHostContainsCondition
- CreateHostEqualsCondition
- CreatePathPrefixCondition
- CreatePathSuffixCondition
- CreatePathContainsCondition
- CreatePathEqualsCondition
- CreateQueryPrefixCondition
- CreateQuerySuffixCondition
- CreateQueryContainsCondition
- CreateQueryEqualsCondition
- CreateHostSuffixPathPrefixCondition
- CreateHostEqualsPathPrefixCondition
- CanonicalizeURLForFullSearches
- CanonicalizeURLForRegexSearchesHelper
- CanonicalizeURLForRegexSearches
- CanonicalizeURLForOriginAndPathRegexSearches
- CreateURLPrefixCondition
- CreateURLSuffixCondition
- CreateURLContainsCondition
- CreateURLEqualsCondition
- CreateURLMatchesCondition
- CreateOriginAndPathMatchesCondition
- ForgetUnusedPatterns
- IsEmpty
- CreateCondition
- CanonicalizeHostname
- IsMatch
- IsMatch
- CreateRange
- CreateRange
- conditions_
- port_filter_
- IsMatch
- AddConditionSets
- RemoveConditionSets
- ClearUnusedConditionSets
- MatchURL
- IsEmpty
- UpdateSubstringSetMatcher
- UpdateRegexSetMatcher
- UpdateTriggers
- UpdateConditionFactory
- UpdateInternalDatastructures
#include "components/url_matcher/url_matcher.h"
#include <algorithm>
#include <iterator>
#include "base/logging.h"
#include "url/gurl.h"
#include "url/url_canon.h"
namespace url_matcher {
namespace {
bool IsRegexCriterion(URLMatcherCondition::Criterion criterion) {
return criterion == URLMatcherCondition::URL_MATCHES;
}
bool IsOriginAndPathRegexCriterion(URLMatcherCondition::Criterion criterion) {
return criterion == URLMatcherCondition::ORIGIN_AND_PATH_MATCHES;
}
}
URLMatcherCondition::URLMatcherCondition()
: criterion_(HOST_PREFIX),
string_pattern_(NULL) {}
URLMatcherCondition::~URLMatcherCondition() {}
URLMatcherCondition::URLMatcherCondition(
Criterion criterion,
const StringPattern* string_pattern)
: criterion_(criterion),
string_pattern_(string_pattern) {}
URLMatcherCondition::URLMatcherCondition(const URLMatcherCondition& rhs)
: criterion_(rhs.criterion_),
string_pattern_(rhs.string_pattern_) {}
URLMatcherCondition& URLMatcherCondition::operator=(
const URLMatcherCondition& rhs) {
criterion_ = rhs.criterion_;
string_pattern_ = rhs.string_pattern_;
return *this;
}
bool URLMatcherCondition::operator<(const URLMatcherCondition& rhs) const {
if (criterion_ < rhs.criterion_) return true;
if (criterion_ > rhs.criterion_) return false;
if (string_pattern_ != NULL && rhs.string_pattern_ != NULL)
return *string_pattern_ < *rhs.string_pattern_;
if (string_pattern_ == NULL && rhs.string_pattern_ != NULL) return true;
return false;
}
bool URLMatcherCondition::IsFullURLCondition() const {
switch (criterion_) {
case HOST_CONTAINS:
case PATH_CONTAINS:
case QUERY_CONTAINS:
case URL_PREFIX:
case URL_SUFFIX:
case URL_CONTAINS:
case URL_EQUALS:
return true;
default:
break;
}
return false;
}
bool URLMatcherCondition::IsRegexCondition() const {
return IsRegexCriterion(criterion_);
}
bool URLMatcherCondition::IsOriginAndPathRegexCondition() const {
return IsOriginAndPathRegexCriterion(criterion_);
}
bool URLMatcherCondition::IsMatch(
const std::set<StringPattern::ID>& matching_patterns,
const GURL& url) const {
DCHECK(string_pattern_);
if (!ContainsKey(matching_patterns, string_pattern_->id()))
return false;
switch (criterion_) {
case HOST_CONTAINS:
return url.host().find(string_pattern_->pattern()) !=
std::string::npos;
case PATH_CONTAINS:
return url.path().find(string_pattern_->pattern()) !=
std::string::npos;
case QUERY_CONTAINS:
return url.query().find(string_pattern_->pattern()) !=
std::string::npos;
default:
break;
}
return true;
}
namespace {
const char kBeginningOfURL[] = {static_cast<char>(-1), 0};
const char kEndOfDomain[] = {static_cast<char>(-2), 0};
const char kEndOfPath[] = {static_cast<char>(-3), 0};
const char kEndOfURL[] = {static_cast<char>(-4), 0};
}
URLMatcherConditionFactory::URLMatcherConditionFactory() : id_counter_(0) {}
URLMatcherConditionFactory::~URLMatcherConditionFactory() {
STLDeleteElements(&substring_pattern_singletons_);
STLDeleteElements(®ex_pattern_singletons_);
STLDeleteElements(&origin_and_path_regex_pattern_singletons_);
}
std::string URLMatcherConditionFactory::CanonicalizeURLForComponentSearches(
const GURL& url) const {
return kBeginningOfURL + CanonicalizeHostname(url.host()) + kEndOfDomain +
url.path() + kEndOfPath +
(url.has_query() ? "?" + url.query() : std::string()) + kEndOfURL;
}
URLMatcherCondition URLMatcherConditionFactory::CreateHostPrefixCondition(
const std::string& prefix) {
return CreateCondition(URLMatcherCondition::HOST_PREFIX,
kBeginningOfURL + CanonicalizeHostname(prefix));
}
URLMatcherCondition URLMatcherConditionFactory::CreateHostSuffixCondition(
const std::string& suffix) {
return CreateCondition(URLMatcherCondition::HOST_SUFFIX,
suffix + kEndOfDomain);
}
URLMatcherCondition URLMatcherConditionFactory::CreateHostContainsCondition(
const std::string& str) {
return CreateCondition(URLMatcherCondition::HOST_CONTAINS, str);
}
URLMatcherCondition URLMatcherConditionFactory::CreateHostEqualsCondition(
const std::string& str) {
return CreateCondition(URLMatcherCondition::HOST_EQUALS,
kBeginningOfURL + CanonicalizeHostname(str) + kEndOfDomain);
}
URLMatcherCondition URLMatcherConditionFactory::CreatePathPrefixCondition(
const std::string& prefix) {
return CreateCondition(URLMatcherCondition::PATH_PREFIX,
kEndOfDomain + prefix);
}
URLMatcherCondition URLMatcherConditionFactory::CreatePathSuffixCondition(
const std::string& suffix) {
return CreateCondition(URLMatcherCondition::PATH_SUFFIX, suffix + kEndOfPath);
}
URLMatcherCondition URLMatcherConditionFactory::CreatePathContainsCondition(
const std::string& str) {
return CreateCondition(URLMatcherCondition::PATH_CONTAINS, str);
}
URLMatcherCondition URLMatcherConditionFactory::CreatePathEqualsCondition(
const std::string& str) {
return CreateCondition(URLMatcherCondition::PATH_EQUALS,
kEndOfDomain + str + kEndOfPath);
}
URLMatcherCondition URLMatcherConditionFactory::CreateQueryPrefixCondition(
const std::string& prefix) {
std::string pattern;
if (!prefix.empty() && prefix[0] == '?')
pattern = kEndOfPath + prefix;
else
pattern = kEndOfPath + ('?' + prefix);
return CreateCondition(URLMatcherCondition::QUERY_PREFIX, pattern);
}
URLMatcherCondition URLMatcherConditionFactory::CreateQuerySuffixCondition(
const std::string& suffix) {
if (!suffix.empty() && suffix[0] == '?') {
return CreateQueryEqualsCondition(suffix);
} else {
return CreateCondition(URLMatcherCondition::QUERY_SUFFIX,
suffix + kEndOfURL);
}
}
URLMatcherCondition URLMatcherConditionFactory::CreateQueryContainsCondition(
const std::string& str) {
if (!str.empty() && str[0] == '?')
return CreateQueryPrefixCondition(str);
else
return CreateCondition(URLMatcherCondition::QUERY_CONTAINS, str);
}
URLMatcherCondition URLMatcherConditionFactory::CreateQueryEqualsCondition(
const std::string& str) {
std::string pattern;
if (!str.empty() && str[0] == '?')
pattern = kEndOfPath + str + kEndOfURL;
else
pattern = kEndOfPath + ('?' + str) + kEndOfURL;
return CreateCondition(URLMatcherCondition::QUERY_EQUALS, pattern);
}
URLMatcherCondition
URLMatcherConditionFactory::CreateHostSuffixPathPrefixCondition(
const std::string& host_suffix,
const std::string& path_prefix) {
return CreateCondition(URLMatcherCondition::HOST_SUFFIX_PATH_PREFIX,
host_suffix + kEndOfDomain + path_prefix);
}
URLMatcherCondition
URLMatcherConditionFactory::CreateHostEqualsPathPrefixCondition(
const std::string& host,
const std::string& path_prefix) {
return CreateCondition(URLMatcherCondition::HOST_EQUALS_PATH_PREFIX,
kBeginningOfURL + CanonicalizeHostname(host) + kEndOfDomain +
path_prefix);
}
std::string URLMatcherConditionFactory::CanonicalizeURLForFullSearches(
const GURL& url) const {
GURL::Replacements replacements;
replacements.ClearPassword();
replacements.ClearUsername();
replacements.ClearRef();
if (url.has_port()) {
const std::string& port = url.scheme();
if (url_canon::DefaultPortForScheme(port.c_str(), port.size()) ==
url.EffectiveIntPort()) {
replacements.ClearPort();
}
}
return kBeginningOfURL + url.ReplaceComponents(replacements).spec() +
kEndOfURL;
}
static std::string CanonicalizeURLForRegexSearchesHelper(
const GURL& url,
bool clear_query) {
GURL::Replacements replacements;
replacements.ClearPassword();
replacements.ClearUsername();
replacements.ClearRef();
if (clear_query)
replacements.ClearQuery();
if (url.has_port()) {
const std::string& port = url.scheme();
if (url_canon::DefaultPortForScheme(port.c_str(), port.size()) ==
url.EffectiveIntPort()) {
replacements.ClearPort();
}
}
return url.ReplaceComponents(replacements).spec();
}
std::string URLMatcherConditionFactory::CanonicalizeURLForRegexSearches(
const GURL& url) const {
return CanonicalizeURLForRegexSearchesHelper(url, false);
}
std::string
URLMatcherConditionFactory::CanonicalizeURLForOriginAndPathRegexSearches(
const GURL& url) const {
return CanonicalizeURLForRegexSearchesHelper(url, true);
}
URLMatcherCondition URLMatcherConditionFactory::CreateURLPrefixCondition(
const std::string& prefix) {
return CreateCondition(URLMatcherCondition::URL_PREFIX,
kBeginningOfURL + prefix);
}
URLMatcherCondition URLMatcherConditionFactory::CreateURLSuffixCondition(
const std::string& suffix) {
return CreateCondition(URLMatcherCondition::URL_SUFFIX, suffix + kEndOfURL);
}
URLMatcherCondition URLMatcherConditionFactory::CreateURLContainsCondition(
const std::string& str) {
return CreateCondition(URLMatcherCondition::URL_CONTAINS, str);
}
URLMatcherCondition URLMatcherConditionFactory::CreateURLEqualsCondition(
const std::string& str) {
return CreateCondition(URLMatcherCondition::URL_EQUALS,
kBeginningOfURL + str + kEndOfURL);
}
URLMatcherCondition URLMatcherConditionFactory::CreateURLMatchesCondition(
const std::string& regex) {
return CreateCondition(URLMatcherCondition::URL_MATCHES, regex);
}
URLMatcherCondition
URLMatcherConditionFactory::CreateOriginAndPathMatchesCondition(
const std::string& regex) {
return CreateCondition(URLMatcherCondition::ORIGIN_AND_PATH_MATCHES, regex);
}
void URLMatcherConditionFactory::ForgetUnusedPatterns(
const std::set<StringPattern::ID>& used_patterns) {
PatternSingletons::iterator i = substring_pattern_singletons_.begin();
while (i != substring_pattern_singletons_.end()) {
if (ContainsKey(used_patterns, (*i)->id())) {
++i;
} else {
delete *i;
substring_pattern_singletons_.erase(i++);
}
}
i = regex_pattern_singletons_.begin();
while (i != regex_pattern_singletons_.end()) {
if (ContainsKey(used_patterns, (*i)->id())) {
++i;
} else {
delete *i;
regex_pattern_singletons_.erase(i++);
}
}
i = origin_and_path_regex_pattern_singletons_.begin();
while (i != origin_and_path_regex_pattern_singletons_.end()) {
if (ContainsKey(used_patterns, (*i)->id())) {
++i;
} else {
delete *i;
origin_and_path_regex_pattern_singletons_.erase(i++);
}
}
}
bool URLMatcherConditionFactory::IsEmpty() const {
return substring_pattern_singletons_.empty() &&
regex_pattern_singletons_.empty() &&
origin_and_path_regex_pattern_singletons_.empty();
}
URLMatcherCondition URLMatcherConditionFactory::CreateCondition(
URLMatcherCondition::Criterion criterion,
const std::string& pattern) {
StringPattern search_pattern(pattern, 0);
PatternSingletons* pattern_singletons = NULL;
if (IsRegexCriterion(criterion))
pattern_singletons = ®ex_pattern_singletons_;
else if (IsOriginAndPathRegexCriterion(criterion))
pattern_singletons = &origin_and_path_regex_pattern_singletons_;
else
pattern_singletons = &substring_pattern_singletons_;
PatternSingletons::const_iterator iter =
pattern_singletons->find(&search_pattern);
if (iter != pattern_singletons->end()) {
return URLMatcherCondition(criterion, *iter);
} else {
StringPattern* new_pattern =
new StringPattern(pattern, id_counter_++);
pattern_singletons->insert(new_pattern);
return URLMatcherCondition(criterion, new_pattern);
}
}
std::string URLMatcherConditionFactory::CanonicalizeHostname(
const std::string& hostname) const {
if (!hostname.empty() && hostname[0] == '.')
return hostname;
else
return "." + hostname;
}
bool URLMatcherConditionFactory::StringPatternPointerCompare::operator()(
StringPattern* lhs,
StringPattern* rhs) const {
if (lhs == NULL && rhs != NULL) return true;
if (lhs != NULL && rhs != NULL)
return lhs->pattern() < rhs->pattern();
return false;
}
URLMatcherSchemeFilter::URLMatcherSchemeFilter(const std::string& filter)
: filters_(1) {
filters_.push_back(filter);
}
URLMatcherSchemeFilter::URLMatcherSchemeFilter(
const std::vector<std::string>& filters)
: filters_(filters) {}
URLMatcherSchemeFilter::~URLMatcherSchemeFilter() {}
bool URLMatcherSchemeFilter::IsMatch(const GURL& url) const {
return std::find(filters_.begin(), filters_.end(), url.scheme()) !=
filters_.end();
}
URLMatcherPortFilter::URLMatcherPortFilter(
const std::vector<URLMatcherPortFilter::Range>& ranges)
: ranges_(ranges) {}
URLMatcherPortFilter::~URLMatcherPortFilter() {}
bool URLMatcherPortFilter::IsMatch(const GURL& url) const {
int port = url.EffectiveIntPort();
for (std::vector<Range>::const_iterator i = ranges_.begin();
i != ranges_.end(); ++i) {
if (i->first <= port && port <= i->second)
return true;
}
return false;
}
URLMatcherPortFilter::Range URLMatcherPortFilter::CreateRange(int from,
int to) {
return Range(from, to);
}
URLMatcherPortFilter::Range URLMatcherPortFilter::CreateRange(int port) {
return Range(port, port);
}
URLMatcherConditionSet::~URLMatcherConditionSet() {}
URLMatcherConditionSet::URLMatcherConditionSet(
ID id,
const Conditions& conditions)
: id_(id),
conditions_(conditions) {}
URLMatcherConditionSet::URLMatcherConditionSet(
ID id,
const Conditions& conditions,
scoped_ptr<URLMatcherSchemeFilter> scheme_filter,
scoped_ptr<URLMatcherPortFilter> port_filter)
: id_(id),
conditions_(conditions),
scheme_filter_(scheme_filter.Pass()),
port_filter_(port_filter.Pass()) {}
bool URLMatcherConditionSet::IsMatch(
const std::set<StringPattern::ID>& matching_patterns,
const GURL& url) const {
for (Conditions::const_iterator i = conditions_.begin();
i != conditions_.end(); ++i) {
if (!i->IsMatch(matching_patterns, url))
return false;
}
if (scheme_filter_.get() && !scheme_filter_->IsMatch(url))
return false;
if (port_filter_.get() && !port_filter_->IsMatch(url))
return false;
return true;
}
URLMatcher::URLMatcher() {}
URLMatcher::~URLMatcher() {}
void URLMatcher::AddConditionSets(
const URLMatcherConditionSet::Vector& condition_sets) {
for (URLMatcherConditionSet::Vector::const_iterator i =
condition_sets.begin(); i != condition_sets.end(); ++i) {
DCHECK(url_matcher_condition_sets_.find((*i)->id()) ==
url_matcher_condition_sets_.end());
url_matcher_condition_sets_[(*i)->id()] = *i;
}
UpdateInternalDatastructures();
}
void URLMatcher::RemoveConditionSets(
const std::vector<URLMatcherConditionSet::ID>& condition_set_ids) {
for (std::vector<URLMatcherConditionSet::ID>::const_iterator i =
condition_set_ids.begin(); i != condition_set_ids.end(); ++i) {
DCHECK(url_matcher_condition_sets_.find(*i) !=
url_matcher_condition_sets_.end());
url_matcher_condition_sets_.erase(*i);
}
UpdateInternalDatastructures();
}
void URLMatcher::ClearUnusedConditionSets() {
UpdateConditionFactory();
}
std::set<URLMatcherConditionSet::ID> URLMatcher::MatchURL(
const GURL& url) const {
std::set<StringPattern::ID> matches;
if (!full_url_matcher_.IsEmpty()) {
full_url_matcher_.Match(
condition_factory_.CanonicalizeURLForFullSearches(url), &matches);
}
if (!url_component_matcher_.IsEmpty()) {
url_component_matcher_.Match(
condition_factory_.CanonicalizeURLForComponentSearches(url), &matches);
}
if (!regex_set_matcher_.IsEmpty()) {
regex_set_matcher_.Match(
condition_factory_.CanonicalizeURLForRegexSearches(url), &matches);
}
if (!origin_and_path_regex_set_matcher_.IsEmpty()) {
origin_and_path_regex_set_matcher_.Match(
condition_factory_.CanonicalizeURLForOriginAndPathRegexSearches(url),
&matches);
}
std::set<URLMatcherConditionSet::ID> result;
for (std::set<StringPattern::ID>::const_iterator i = matches.begin();
i != matches.end(); ++i) {
StringPatternTriggers::const_iterator triggered_condition_sets_iter =
substring_match_triggers_.find(*i);
if (triggered_condition_sets_iter == substring_match_triggers_.end())
continue;
const std::set<URLMatcherConditionSet::ID>& condition_sets =
triggered_condition_sets_iter->second;
for (std::set<URLMatcherConditionSet::ID>::const_iterator j =
condition_sets.begin(); j != condition_sets.end(); ++j) {
URLMatcherConditionSets::const_iterator condition_set_iter =
url_matcher_condition_sets_.find(*j);
DCHECK(condition_set_iter != url_matcher_condition_sets_.end());
if (condition_set_iter->second->IsMatch(matches, url))
result.insert(*j);
}
}
return result;
}
bool URLMatcher::IsEmpty() const {
return condition_factory_.IsEmpty() &&
url_matcher_condition_sets_.empty() &&
substring_match_triggers_.empty() &&
full_url_matcher_.IsEmpty() &&
url_component_matcher_.IsEmpty() &&
regex_set_matcher_.IsEmpty() &&
origin_and_path_regex_set_matcher_.IsEmpty() &&
registered_full_url_patterns_.empty() &&
registered_url_component_patterns_.empty();
}
void URLMatcher::UpdateSubstringSetMatcher(bool full_url_conditions) {
std::set<const StringPattern*> new_patterns;
for (URLMatcherConditionSets::const_iterator condition_set_iter =
url_matcher_condition_sets_.begin();
condition_set_iter != url_matcher_condition_sets_.end();
++condition_set_iter) {
const URLMatcherConditionSet::Conditions& conditions =
condition_set_iter->second->conditions();
for (URLMatcherConditionSet::Conditions::const_iterator condition_iter =
conditions.begin(); condition_iter != conditions.end();
++condition_iter) {
if (!condition_iter->IsRegexCondition() &&
!condition_iter->IsOriginAndPathRegexCondition() &&
full_url_conditions == condition_iter->IsFullURLCondition())
new_patterns.insert(condition_iter->string_pattern());
}
}
std::set<const StringPattern*>& registered_patterns =
full_url_conditions ? registered_full_url_patterns_
: registered_url_component_patterns_;
std::vector<const StringPattern*> patterns_to_register =
base::STLSetDifference<std::vector<const StringPattern*> >(
new_patterns, registered_patterns);
std::vector<const StringPattern*> patterns_to_unregister =
base::STLSetDifference<std::vector<const StringPattern*> >(
registered_patterns, new_patterns);
SubstringSetMatcher& url_matcher =
full_url_conditions ? full_url_matcher_ : url_component_matcher_;
url_matcher.RegisterAndUnregisterPatterns(patterns_to_register,
patterns_to_unregister);
registered_patterns.swap(new_patterns);
}
void URLMatcher::UpdateRegexSetMatcher() {
std::vector<const StringPattern*> new_patterns;
std::vector<const StringPattern*> new_origin_and_path_patterns;
for (URLMatcherConditionSets::const_iterator condition_set_iter =
url_matcher_condition_sets_.begin();
condition_set_iter != url_matcher_condition_sets_.end();
++condition_set_iter) {
const URLMatcherConditionSet::Conditions& conditions =
condition_set_iter->second->conditions();
for (URLMatcherConditionSet::Conditions::const_iterator condition_iter =
conditions.begin(); condition_iter != conditions.end();
++condition_iter) {
if (condition_iter->IsRegexCondition()) {
new_patterns.push_back(condition_iter->string_pattern());
} else if (condition_iter->IsOriginAndPathRegexCondition()) {
new_origin_and_path_patterns.push_back(
condition_iter->string_pattern());
}
}
}
regex_set_matcher_.ClearPatterns();
regex_set_matcher_.AddPatterns(new_patterns);
origin_and_path_regex_set_matcher_.ClearPatterns();
origin_and_path_regex_set_matcher_.AddPatterns(new_origin_and_path_patterns);
}
void URLMatcher::UpdateTriggers() {
std::map<StringPattern::ID, size_t> substring_pattern_frequencies;
for (URLMatcherConditionSets::const_iterator condition_set_iter =
url_matcher_condition_sets_.begin();
condition_set_iter != url_matcher_condition_sets_.end();
++condition_set_iter) {
const URLMatcherConditionSet::Conditions& conditions =
condition_set_iter->second->conditions();
for (URLMatcherConditionSet::Conditions::const_iterator condition_iter =
conditions.begin(); condition_iter != conditions.end();
++condition_iter) {
const StringPattern* pattern = condition_iter->string_pattern();
substring_pattern_frequencies[pattern->id()]++;
}
}
substring_match_triggers_.clear();
for (URLMatcherConditionSets::const_iterator condition_set_iter =
url_matcher_condition_sets_.begin();
condition_set_iter != url_matcher_condition_sets_.end();
++condition_set_iter) {
const URLMatcherConditionSet::Conditions& conditions =
condition_set_iter->second->conditions();
if (conditions.empty())
continue;
URLMatcherConditionSet::Conditions::const_iterator condition_iter =
conditions.begin();
StringPattern::ID trigger = condition_iter->string_pattern()->id();
++condition_iter;
for (; condition_iter != conditions.end(); ++condition_iter) {
StringPattern::ID current_id =
condition_iter->string_pattern()->id();
if (substring_pattern_frequencies[trigger] >
substring_pattern_frequencies[current_id]) {
trigger = current_id;
}
}
substring_match_triggers_[trigger].insert(condition_set_iter->second->id());
}
}
void URLMatcher::UpdateConditionFactory() {
std::set<StringPattern::ID> used_patterns;
for (URLMatcherConditionSets::const_iterator condition_set_iter =
url_matcher_condition_sets_.begin();
condition_set_iter != url_matcher_condition_sets_.end();
++condition_set_iter) {
const URLMatcherConditionSet::Conditions& conditions =
condition_set_iter->second->conditions();
for (URLMatcherConditionSet::Conditions::const_iterator condition_iter =
conditions.begin(); condition_iter != conditions.end();
++condition_iter) {
used_patterns.insert(condition_iter->string_pattern()->id());
}
}
condition_factory_.ForgetUnusedPatterns(used_patterns);
}
void URLMatcher::UpdateInternalDatastructures() {
UpdateSubstringSetMatcher(false);
UpdateSubstringSetMatcher(true);
UpdateRegexSetMatcher();
UpdateTriggers();
UpdateConditionFactory();
}
}