Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: components/url_matcher/url_matcher.cc

Issue 219613002: Add support for matching query parameters in URLMatcher (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixes comments from Dominic Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/url_matcher/url_matcher.h ('k') | components/url_matcher/url_matcher_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/url_matcher/url_matcher.h" 5 #include "components/url_matcher/url_matcher.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <iterator> 8 #include <iterator>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 243
244 // 244 //
245 // URLMatcherConditionFactory 245 // URLMatcherConditionFactory
246 // 246 //
247 247
248 namespace { 248 namespace {
249 // These are symbols that are not contained in 7-bit ASCII used in GURLs. 249 // These are symbols that are not contained in 7-bit ASCII used in GURLs.
250 const char kBeginningOfURL[] = {static_cast<char>(-1), 0}; 250 const char kBeginningOfURL[] = {static_cast<char>(-1), 0};
251 const char kEndOfDomain[] = {static_cast<char>(-2), 0}; 251 const char kEndOfDomain[] = {static_cast<char>(-2), 0};
252 const char kEndOfPath[] = {static_cast<char>(-3), 0}; 252 const char kEndOfPath[] = {static_cast<char>(-3), 0};
253 const char kEndOfURL[] = {static_cast<char>(-4), 0}; 253 const char kQueryComponentDelimiter[] = {static_cast<char>(-4), 0};
254 const char kEndOfURL[] = {static_cast<char>(-5), 0};
255 const char kQuerySeparator = '&';
Bernhard Bauer 2014/04/09 08:42:38 This constant does not match the comment at the be
254 } // namespace 256 } // namespace
255 257
256 URLMatcherConditionFactory::URLMatcherConditionFactory() : id_counter_(0) {} 258 URLMatcherConditionFactory::URLMatcherConditionFactory() : id_counter_(0) {}
257 259
258 URLMatcherConditionFactory::~URLMatcherConditionFactory() { 260 URLMatcherConditionFactory::~URLMatcherConditionFactory() {
259 STLDeleteElements(&substring_pattern_singletons_); 261 STLDeleteElements(&substring_pattern_singletons_);
260 STLDeleteElements(&regex_pattern_singletons_); 262 STLDeleteElements(&regex_pattern_singletons_);
261 STLDeleteElements(&origin_and_path_regex_pattern_singletons_); 263 STLDeleteElements(&origin_and_path_regex_pattern_singletons_);
262 } 264 }
263 265
264 std::string URLMatcherConditionFactory::CanonicalizeURLForComponentSearches( 266 std::string URLMatcherConditionFactory::CanonicalizeURLForComponentSearches(
265 const GURL& url) const { 267 const GURL& url) const {
266 return kBeginningOfURL + CanonicalizeHostname(url.host()) + kEndOfDomain + 268 return kBeginningOfURL + CanonicalizeHostname(url.host()) + kEndOfDomain +
267 url.path() + kEndOfPath + 269 url.path() + kEndOfPath +
268 (url.has_query() ? "?" + url.query() : std::string()) + kEndOfURL; 270 (url.has_query() ? CanonicalizeQuery(url.query(), true, true)
271 : std::string()) +
272 kEndOfURL;
269 } 273 }
270 274
271 URLMatcherCondition URLMatcherConditionFactory::CreateHostPrefixCondition( 275 URLMatcherCondition URLMatcherConditionFactory::CreateHostPrefixCondition(
272 const std::string& prefix) { 276 const std::string& prefix) {
273 return CreateCondition(URLMatcherCondition::HOST_PREFIX, 277 return CreateCondition(URLMatcherCondition::HOST_PREFIX,
274 kBeginningOfURL + CanonicalizeHostname(prefix)); 278 kBeginningOfURL + CanonicalizeHostname(prefix));
275 } 279 }
276 280
277 URLMatcherCondition URLMatcherConditionFactory::CreateHostSuffixCondition( 281 URLMatcherCondition URLMatcherConditionFactory::CreateHostSuffixCondition(
278 const std::string& suffix) { 282 const std::string& suffix) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 URLMatcherCondition URLMatcherConditionFactory::CreatePathEqualsCondition( 314 URLMatcherCondition URLMatcherConditionFactory::CreatePathEqualsCondition(
311 const std::string& str) { 315 const std::string& str) {
312 return CreateCondition(URLMatcherCondition::PATH_EQUALS, 316 return CreateCondition(URLMatcherCondition::PATH_EQUALS,
313 kEndOfDomain + str + kEndOfPath); 317 kEndOfDomain + str + kEndOfPath);
314 } 318 }
315 319
316 URLMatcherCondition URLMatcherConditionFactory::CreateQueryPrefixCondition( 320 URLMatcherCondition URLMatcherConditionFactory::CreateQueryPrefixCondition(
317 const std::string& prefix) { 321 const std::string& prefix) {
318 std::string pattern; 322 std::string pattern;
319 if (!prefix.empty() && prefix[0] == '?') 323 if (!prefix.empty() && prefix[0] == '?')
320 pattern = kEndOfPath + prefix; 324 pattern = kEndOfPath + CanonicalizeQuery(prefix.substr(1), true, false);
321 else 325 else
322 pattern = kEndOfPath + ('?' + prefix); 326 pattern = kEndOfPath + CanonicalizeQuery(prefix, true, false);
323 327
324 return CreateCondition(URLMatcherCondition::QUERY_PREFIX, pattern); 328 return CreateCondition(URLMatcherCondition::QUERY_PREFIX, pattern);
325 } 329 }
326 330
327 URLMatcherCondition URLMatcherConditionFactory::CreateQuerySuffixCondition( 331 URLMatcherCondition URLMatcherConditionFactory::CreateQuerySuffixCondition(
328 const std::string& suffix) { 332 const std::string& suffix) {
329 if (!suffix.empty() && suffix[0] == '?') { 333 if (!suffix.empty() && suffix[0] == '?') {
330 return CreateQueryEqualsCondition(suffix); 334 return CreateQueryEqualsCondition(suffix);
331 } else { 335 } else {
332 return CreateCondition(URLMatcherCondition::QUERY_SUFFIX, 336 return CreateCondition(URLMatcherCondition::QUERY_SUFFIX,
333 suffix + kEndOfURL); 337 CanonicalizeQuery(suffix, false, true) + kEndOfURL);
334 } 338 }
335 } 339 }
336 340
337 URLMatcherCondition URLMatcherConditionFactory::CreateQueryContainsCondition( 341 URLMatcherCondition URLMatcherConditionFactory::CreateQueryContainsCondition(
338 const std::string& str) { 342 const std::string& str) {
339 if (!str.empty() && str[0] == '?') 343 if (!str.empty() && str[0] == '?')
340 return CreateQueryPrefixCondition(str); 344 return CreateQueryPrefixCondition(str);
341 else 345 else
342 return CreateCondition(URLMatcherCondition::QUERY_CONTAINS, str); 346 return CreateCondition(URLMatcherCondition::QUERY_CONTAINS, str);
343 } 347 }
344 348
345 URLMatcherCondition URLMatcherConditionFactory::CreateQueryEqualsCondition( 349 URLMatcherCondition URLMatcherConditionFactory::CreateQueryEqualsCondition(
346 const std::string& str) { 350 const std::string& str) {
347 std::string pattern; 351 std::string pattern;
348 if (!str.empty() && str[0] == '?') 352 if (!str.empty() && str[0] == '?')
349 pattern = kEndOfPath + str + kEndOfURL; 353 pattern =
354 kEndOfPath + CanonicalizeQuery(str.substr(1), true, true) + kEndOfURL;
350 else 355 else
351 pattern = kEndOfPath + ('?' + str) + kEndOfURL; 356 pattern = kEndOfPath + CanonicalizeQuery(str, true, true) + kEndOfURL;
352 357
353 return CreateCondition(URLMatcherCondition::QUERY_EQUALS, pattern); 358 return CreateCondition(URLMatcherCondition::QUERY_EQUALS, pattern);
354 } 359 }
355 360
356 URLMatcherCondition 361 URLMatcherCondition
357 URLMatcherConditionFactory::CreateHostSuffixPathPrefixCondition( 362 URLMatcherConditionFactory::CreateHostSuffixPathPrefixCondition(
358 const std::string& host_suffix, 363 const std::string& host_suffix,
359 const std::string& path_prefix) { 364 const std::string& path_prefix) {
360 return CreateCondition(URLMatcherCondition::HOST_SUFFIX_PATH_PREFIX, 365 return CreateCondition(URLMatcherCondition::HOST_SUFFIX_PATH_PREFIX,
361 host_suffix + kEndOfDomain + path_prefix); 366 host_suffix + kEndOfDomain + path_prefix);
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 } 520 }
516 521
517 std::string URLMatcherConditionFactory::CanonicalizeHostname( 522 std::string URLMatcherConditionFactory::CanonicalizeHostname(
518 const std::string& hostname) const { 523 const std::string& hostname) const {
519 if (!hostname.empty() && hostname[0] == '.') 524 if (!hostname.empty() && hostname[0] == '.')
520 return hostname; 525 return hostname;
521 else 526 else
522 return "." + hostname; 527 return "." + hostname;
523 } 528 }
524 529
530 // This function prepares the query string by replacing query separator with a
531 // magic value (|kQueryComponentDelimiter|). When the boolean
532 // |prepend_beginning_of_query_component| is true the function prepends the
533 // query with the same magic. This is done to locate the start of a key value
534 // pair in the query string. The parameter |query| is passed by value
535 // intentionally, since it is locally modified.
536 std::string URLMatcherConditionFactory::CanonicalizeQuery(
537 std::string query,
538 bool prepend_beginning_of_query_component,
539 bool append_end_of_query_component) const {
540 for (std::string::iterator it = query.begin(); it != query.end(); ++it) {
541 if (*it == kQuerySeparator)
542 *it = kQueryComponentDelimiter[0];
543 }
544 if (prepend_beginning_of_query_component)
545 query = kQueryComponentDelimiter + query;
546 if (append_end_of_query_component)
547 query += kQueryComponentDelimiter;
548 return query;
549 }
550
525 bool URLMatcherConditionFactory::StringPatternPointerCompare::operator()( 551 bool URLMatcherConditionFactory::StringPatternPointerCompare::operator()(
526 StringPattern* lhs, 552 StringPattern* lhs,
527 StringPattern* rhs) const { 553 StringPattern* rhs) const {
528 if (lhs == NULL && rhs != NULL) return true; 554 if (lhs == NULL && rhs != NULL) return true;
529 if (lhs != NULL && rhs != NULL) 555 if (lhs != NULL && rhs != NULL)
530 return lhs->pattern() < rhs->pattern(); 556 return lhs->pattern() < rhs->pattern();
531 // Either both are NULL or only rhs is NULL. 557 // Either both are NULL or only rhs is NULL.
532 return false; 558 return false;
533 } 559 }
534 560
535 // 561 //
562 // URLQueryElementMatcherCondition
563 //
564
565 URLQueryElementMatcherCondition::URLQueryElementMatcherCondition(
566 const std::string& key,
567 const std::string& value,
568 QueryValueMatchType query_value_match_type,
569 QueryElementType query_element_type,
570 Type match_type,
571 URLMatcherConditionFactory* factory) {
572 match_type_ = match_type;
573
574 if (query_element_type == ELEMENT_TYPE_KEY_VALUE) {
575 key_ = kQueryComponentDelimiter + key + std::string("=");
Bernhard Bauer 2014/04/09 08:42:38 Explicit string constructor isn't necessary here.
576 value_ = value;
577 } else {
578 key_ = kQueryComponentDelimiter + key;
579 value_ = std::string();
580 }
581
582 if (query_value_match_type == QUERY_VALUE_MATCH_EXACT)
583 value_ += kQueryComponentDelimiter;
584
585 // If |value_| is empty no need to find the |key_| and verify if the value
586 // matches. Simply checking the presence of key is sufficient, which is done
587 // by MATCH_ANY
588 if (value_.empty())
589 match_type_ = MATCH_ANY;
590
591 URLMatcherCondition condition;
592 // If |match_type_| is MATCH_ANY, then we could simply look for the
593 // combination of |key_| + |value_|, which can be efficiently done by
594 // SubstringMatcher
595 if (match_type_ == MATCH_ANY)
596 condition = factory->CreateQueryContainsCondition(key_ + value_);
597 else
598 condition = factory->CreateQueryContainsCondition(key_);
599 string_pattern_ = condition.string_pattern();
600
601 key_length_ = key_.length();
602 value_length_ = value_.length();
603 }
604
605 URLQueryElementMatcherCondition::~URLQueryElementMatcherCondition() {}
606
607 bool URLQueryElementMatcherCondition::operator<(
608 const URLQueryElementMatcherCondition& rhs) const {
609 if (match_type_ != rhs.match_type_)
610 return match_type_ < rhs.match_type_;
611 if (string_pattern_ != NULL && rhs.string_pattern_ != NULL)
612 return *string_pattern_ < *rhs.string_pattern_;
613 if (string_pattern_ == NULL && rhs.string_pattern_ != NULL)
614 return true;
615 // Either string_pattern_ != NULL && rhs.string_pattern_ == NULL,
616 // or both are NULL.
617 return false;
618 }
619
620 bool URLQueryElementMatcherCondition::IsMatch(
621 const std::string& url_for_component_searches) const {
622 switch (match_type_) {
623 case MATCH_ANY: {
624 // For MATCH_ANY, no additional verification step is needed. We can trust
625 // the SubstringMatcher to do the verification.
626 return true;
627 }
628 case MATCH_ALL: {
629 size_t start = 0;
630 int found = 0;
631 size_t offset;
632 while ((offset = url_for_component_searches.find(key_, start)) !=
633 std::string::npos) {
634 if (url_for_component_searches.compare(
635 offset + key_length_, value_length_, value_) != 0) {
636 return false;
637 } else {
638 ++found;
639 }
640 start = offset + key_length_ + value_length_ - 1;
641 }
642 return !!found;
643 }
644 case MATCH_FIRST: {
645 size_t offset = url_for_component_searches.find(key_);
646 return url_for_component_searches.compare(
647 offset + key_length_, value_length_, value_) == 0;
648 }
649 case MATCH_LAST: {
650 size_t offset = url_for_component_searches.rfind(key_);
651 return url_for_component_searches.compare(
652 offset + key_length_, value_length_, value_) == 0;
653 }
654 }
655 NOTREACHED();
656 return false;
657 }
658
659 //
536 // URLMatcherSchemeFilter 660 // URLMatcherSchemeFilter
537 // 661 //
538 662
539 URLMatcherSchemeFilter::URLMatcherSchemeFilter(const std::string& filter) 663 URLMatcherSchemeFilter::URLMatcherSchemeFilter(const std::string& filter)
540 : filters_(1) { 664 : filters_(1) {
541 filters_.push_back(filter); 665 filters_.push_back(filter);
542 } 666 }
543 667
544 URLMatcherSchemeFilter::URLMatcherSchemeFilter( 668 URLMatcherSchemeFilter::URLMatcherSchemeFilter(
545 const std::vector<std::string>& filters) 669 const std::vector<std::string>& filters)
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 URLMatcherConditionSet::URLMatcherConditionSet( 722 URLMatcherConditionSet::URLMatcherConditionSet(
599 ID id, 723 ID id,
600 const Conditions& conditions, 724 const Conditions& conditions,
601 scoped_ptr<URLMatcherSchemeFilter> scheme_filter, 725 scoped_ptr<URLMatcherSchemeFilter> scheme_filter,
602 scoped_ptr<URLMatcherPortFilter> port_filter) 726 scoped_ptr<URLMatcherPortFilter> port_filter)
603 : id_(id), 727 : id_(id),
604 conditions_(conditions), 728 conditions_(conditions),
605 scheme_filter_(scheme_filter.Pass()), 729 scheme_filter_(scheme_filter.Pass()),
606 port_filter_(port_filter.Pass()) {} 730 port_filter_(port_filter.Pass()) {}
607 731
732 URLMatcherConditionSet::URLMatcherConditionSet(
733 ID id,
734 const Conditions& conditions,
735 const QueryConditions& query_conditions,
736 scoped_ptr<URLMatcherSchemeFilter> scheme_filter,
737 scoped_ptr<URLMatcherPortFilter> port_filter)
738 : id_(id),
739 conditions_(conditions),
740 query_conditions_(query_conditions),
741 scheme_filter_(scheme_filter.Pass()),
742 port_filter_(port_filter.Pass()) {}
743
608 bool URLMatcherConditionSet::IsMatch( 744 bool URLMatcherConditionSet::IsMatch(
609 const std::set<StringPattern::ID>& matching_patterns, 745 const std::set<StringPattern::ID>& matching_patterns,
610 const GURL& url) const { 746 const GURL& url) const {
747 return IsMatch(matching_patterns, url, std::string());
748 }
749
750 bool URLMatcherConditionSet::IsMatch(
751 const std::set<StringPattern::ID>& matching_patterns,
752 const GURL& url,
753 const std::string& url_for_component_searches) const {
611 for (Conditions::const_iterator i = conditions_.begin(); 754 for (Conditions::const_iterator i = conditions_.begin();
612 i != conditions_.end(); ++i) { 755 i != conditions_.end(); ++i) {
613 if (!i->IsMatch(matching_patterns, url)) 756 if (!i->IsMatch(matching_patterns, url))
614 return false; 757 return false;
615 } 758 }
616 if (scheme_filter_.get() && !scheme_filter_->IsMatch(url)) 759 if (scheme_filter_.get() && !scheme_filter_->IsMatch(url))
617 return false; 760 return false;
618 if (port_filter_.get() && !port_filter_->IsMatch(url)) 761 if (port_filter_.get() && !port_filter_->IsMatch(url))
619 return false; 762 return false;
763 if (query_conditions_.empty())
764 return true;
765 // The loop is duplicated below for performance reasons. If all query elements
766 // are not found, no need to verify match that is expected to take more
767 // cycles.
768 for (QueryConditions::const_iterator i = query_conditions_.begin();
769 i != query_conditions_.end();
770 ++i) {
771 if (!ContainsKey(matching_patterns, i->string_pattern()->id()))
772 return false;
773 }
774 for (QueryConditions::const_iterator i = query_conditions_.begin();
775 i != query_conditions_.end();
776 ++i) {
777 if (!i->IsMatch(url_for_component_searches))
778 return false;
779 }
620 return true; 780 return true;
621 } 781 }
622 782
623 // 783 //
624 // URLMatcher 784 // URLMatcher
625 // 785 //
626 786
627 URLMatcher::URLMatcher() {} 787 URLMatcher::URLMatcher() {}
628 788
629 URLMatcher::~URLMatcher() {} 789 URLMatcher::~URLMatcher() {}
(...skipping 23 matching lines...) Expand all
653 void URLMatcher::ClearUnusedConditionSets() { 813 void URLMatcher::ClearUnusedConditionSets() {
654 UpdateConditionFactory(); 814 UpdateConditionFactory();
655 } 815 }
656 816
657 std::set<URLMatcherConditionSet::ID> URLMatcher::MatchURL( 817 std::set<URLMatcherConditionSet::ID> URLMatcher::MatchURL(
658 const GURL& url) const { 818 const GURL& url) const {
659 // Find all IDs of StringPatterns that match |url|. 819 // Find all IDs of StringPatterns that match |url|.
660 // See URLMatcherConditionFactory for the canonicalization of URLs and the 820 // See URLMatcherConditionFactory for the canonicalization of URLs and the
661 // distinction between full url searches and url component searches. 821 // distinction between full url searches and url component searches.
662 std::set<StringPattern::ID> matches; 822 std::set<StringPattern::ID> matches;
823 std::string url_for_component_searches;
824
663 if (!full_url_matcher_.IsEmpty()) { 825 if (!full_url_matcher_.IsEmpty()) {
664 full_url_matcher_.Match( 826 full_url_matcher_.Match(
665 condition_factory_.CanonicalizeURLForFullSearches(url), &matches); 827 condition_factory_.CanonicalizeURLForFullSearches(url), &matches);
666 } 828 }
667 if (!url_component_matcher_.IsEmpty()) { 829 if (!url_component_matcher_.IsEmpty()) {
668 url_component_matcher_.Match( 830 url_for_component_searches =
669 condition_factory_.CanonicalizeURLForComponentSearches(url), &matches); 831 condition_factory_.CanonicalizeURLForComponentSearches(url);
832 url_component_matcher_.Match(url_for_component_searches, &matches);
670 } 833 }
671 if (!regex_set_matcher_.IsEmpty()) { 834 if (!regex_set_matcher_.IsEmpty()) {
672 regex_set_matcher_.Match( 835 regex_set_matcher_.Match(
673 condition_factory_.CanonicalizeURLForRegexSearches(url), &matches); 836 condition_factory_.CanonicalizeURLForRegexSearches(url), &matches);
674 } 837 }
675 if (!origin_and_path_regex_set_matcher_.IsEmpty()) { 838 if (!origin_and_path_regex_set_matcher_.IsEmpty()) {
676 origin_and_path_regex_set_matcher_.Match( 839 origin_and_path_regex_set_matcher_.Match(
677 condition_factory_.CanonicalizeURLForOriginAndPathRegexSearches(url), 840 condition_factory_.CanonicalizeURLForOriginAndPathRegexSearches(url),
678 &matches); 841 &matches);
679 } 842 }
(...skipping 11 matching lines...) Expand all
691 substring_match_triggers_.find(*i); 854 substring_match_triggers_.find(*i);
692 if (triggered_condition_sets_iter == substring_match_triggers_.end()) 855 if (triggered_condition_sets_iter == substring_match_triggers_.end())
693 continue; // Not all substring matches are triggers for a condition set. 856 continue; // Not all substring matches are triggers for a condition set.
694 const std::set<URLMatcherConditionSet::ID>& condition_sets = 857 const std::set<URLMatcherConditionSet::ID>& condition_sets =
695 triggered_condition_sets_iter->second; 858 triggered_condition_sets_iter->second;
696 for (std::set<URLMatcherConditionSet::ID>::const_iterator j = 859 for (std::set<URLMatcherConditionSet::ID>::const_iterator j =
697 condition_sets.begin(); j != condition_sets.end(); ++j) { 860 condition_sets.begin(); j != condition_sets.end(); ++j) {
698 URLMatcherConditionSets::const_iterator condition_set_iter = 861 URLMatcherConditionSets::const_iterator condition_set_iter =
699 url_matcher_condition_sets_.find(*j); 862 url_matcher_condition_sets_.find(*j);
700 DCHECK(condition_set_iter != url_matcher_condition_sets_.end()); 863 DCHECK(condition_set_iter != url_matcher_condition_sets_.end());
701 if (condition_set_iter->second->IsMatch(matches, url)) 864 if (condition_set_iter->second->IsMatch(
865 matches, url, url_for_component_searches))
702 result.insert(*j); 866 result.insert(*j);
703 } 867 }
704 } 868 }
705 869
706 return result; 870 return result;
707 } 871 }
708 872
709 bool URLMatcher::IsEmpty() const { 873 bool URLMatcher::IsEmpty() const {
710 return condition_factory_.IsEmpty() && 874 return condition_factory_.IsEmpty() &&
711 url_matcher_condition_sets_.empty() && 875 url_matcher_condition_sets_.empty() &&
(...skipping 23 matching lines...) Expand all
735 for (URLMatcherConditionSet::Conditions::const_iterator condition_iter = 899 for (URLMatcherConditionSet::Conditions::const_iterator condition_iter =
736 conditions.begin(); condition_iter != conditions.end(); 900 conditions.begin(); condition_iter != conditions.end();
737 ++condition_iter) { 901 ++condition_iter) {
738 // If we are called to process Full URL searches, ignore others, and 902 // If we are called to process Full URL searches, ignore others, and
739 // vice versa. (Regex conditions are updated in UpdateRegexSetMatcher.) 903 // vice versa. (Regex conditions are updated in UpdateRegexSetMatcher.)
740 if (!condition_iter->IsRegexCondition() && 904 if (!condition_iter->IsRegexCondition() &&
741 !condition_iter->IsOriginAndPathRegexCondition() && 905 !condition_iter->IsOriginAndPathRegexCondition() &&
742 full_url_conditions == condition_iter->IsFullURLCondition()) 906 full_url_conditions == condition_iter->IsFullURLCondition())
743 new_patterns.insert(condition_iter->string_pattern()); 907 new_patterns.insert(condition_iter->string_pattern());
744 } 908 }
909
910 if (full_url_conditions)
911 continue;
912
913 const URLMatcherConditionSet::QueryConditions& query_conditions =
914 condition_set_iter->second->query_conditions();
915 for (URLMatcherConditionSet::QueryConditions::const_iterator
916 query_condition_iter = query_conditions.begin();
917 query_condition_iter != query_conditions.end();
918 ++query_condition_iter) {
919 new_patterns.insert(query_condition_iter->string_pattern());
920 }
745 } 921 }
746 922
747 // This is the set of patterns that were registered before this function 923 // This is the set of patterns that were registered before this function
748 // is called. 924 // is called.
749 std::set<const StringPattern*>& registered_patterns = 925 std::set<const StringPattern*>& registered_patterns =
750 full_url_conditions ? registered_full_url_patterns_ 926 full_url_conditions ? registered_full_url_patterns_
751 : registered_url_component_patterns_; 927 : registered_url_component_patterns_;
752 928
753 // Add all patterns that are in new_patterns but not in registered_patterns. 929 // Add all patterns that are in new_patterns but not in registered_patterns.
754 std::vector<const StringPattern*> patterns_to_register = 930 std::vector<const StringPattern*> patterns_to_register =
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 condition_set_iter != url_matcher_condition_sets_.end(); 986 condition_set_iter != url_matcher_condition_sets_.end();
811 ++condition_set_iter) { 987 ++condition_set_iter) {
812 const URLMatcherConditionSet::Conditions& conditions = 988 const URLMatcherConditionSet::Conditions& conditions =
813 condition_set_iter->second->conditions(); 989 condition_set_iter->second->conditions();
814 for (URLMatcherConditionSet::Conditions::const_iterator condition_iter = 990 for (URLMatcherConditionSet::Conditions::const_iterator condition_iter =
815 conditions.begin(); condition_iter != conditions.end(); 991 conditions.begin(); condition_iter != conditions.end();
816 ++condition_iter) { 992 ++condition_iter) {
817 const StringPattern* pattern = condition_iter->string_pattern(); 993 const StringPattern* pattern = condition_iter->string_pattern();
818 substring_pattern_frequencies[pattern->id()]++; 994 substring_pattern_frequencies[pattern->id()]++;
819 } 995 }
996
997 const URLMatcherConditionSet::QueryConditions& query_conditions =
998 condition_set_iter->second->query_conditions();
999 for (URLMatcherConditionSet::QueryConditions::const_iterator
1000 query_condition_iter = query_conditions.begin();
1001 query_condition_iter != query_conditions.end();
1002 ++query_condition_iter) {
1003 const StringPattern* pattern = query_condition_iter->string_pattern();
1004 substring_pattern_frequencies[pattern->id()]++;
1005 }
820 } 1006 }
821 1007
822 // Update trigger conditions: Determine for each URLMatcherConditionSet which 1008 // Update trigger conditions: Determine for each URLMatcherConditionSet which
823 // URLMatcherCondition contains a StringPattern that occurs least 1009 // URLMatcherCondition contains a StringPattern that occurs least
824 // frequently in this URLMatcher. We assume that this condition is very 1010 // frequently in this URLMatcher. We assume that this condition is very
825 // specific and occurs rarely in URLs. If a match occurs for this 1011 // specific and occurs rarely in URLs. If a match occurs for this
826 // URLMatcherCondition, we want to test all other URLMatcherCondition in the 1012 // URLMatcherCondition, we want to test all other URLMatcherCondition in the
827 // respective URLMatcherConditionSet as well to see whether the entire 1013 // respective URLMatcherConditionSet as well to see whether the entire
828 // URLMatcherConditionSet is considered matching. 1014 // URLMatcherConditionSet is considered matching.
829 substring_match_triggers_.clear(); 1015 substring_match_triggers_.clear();
(...skipping 11 matching lines...) Expand all
841 // We skip the first element in the following loop. 1027 // We skip the first element in the following loop.
842 ++condition_iter; 1028 ++condition_iter;
843 for (; condition_iter != conditions.end(); ++condition_iter) { 1029 for (; condition_iter != conditions.end(); ++condition_iter) {
844 StringPattern::ID current_id = 1030 StringPattern::ID current_id =
845 condition_iter->string_pattern()->id(); 1031 condition_iter->string_pattern()->id();
846 if (substring_pattern_frequencies[trigger] > 1032 if (substring_pattern_frequencies[trigger] >
847 substring_pattern_frequencies[current_id]) { 1033 substring_pattern_frequencies[current_id]) {
848 trigger = current_id; 1034 trigger = current_id;
849 } 1035 }
850 } 1036 }
1037
1038 const URLMatcherConditionSet::QueryConditions& query_conditions =
1039 condition_set_iter->second->query_conditions();
1040 for (URLMatcherConditionSet::QueryConditions::const_iterator
1041 query_condition_iter = query_conditions.begin();
1042 query_condition_iter != query_conditions.end();
1043 ++query_condition_iter) {
1044 StringPattern::ID current_id =
1045 query_condition_iter->string_pattern()->id();
1046 if (substring_pattern_frequencies[trigger] >
1047 substring_pattern_frequencies[current_id]) {
1048 trigger = current_id;
1049 }
1050 }
1051
851 substring_match_triggers_[trigger].insert(condition_set_iter->second->id()); 1052 substring_match_triggers_[trigger].insert(condition_set_iter->second->id());
852 } 1053 }
853 } 1054 }
854 1055
855 void URLMatcher::UpdateConditionFactory() { 1056 void URLMatcher::UpdateConditionFactory() {
856 std::set<StringPattern::ID> used_patterns; 1057 std::set<StringPattern::ID> used_patterns;
857 for (URLMatcherConditionSets::const_iterator condition_set_iter = 1058 for (URLMatcherConditionSets::const_iterator condition_set_iter =
858 url_matcher_condition_sets_.begin(); 1059 url_matcher_condition_sets_.begin();
859 condition_set_iter != url_matcher_condition_sets_.end(); 1060 condition_set_iter != url_matcher_condition_sets_.end();
860 ++condition_set_iter) { 1061 ++condition_set_iter) {
861 const URLMatcherConditionSet::Conditions& conditions = 1062 const URLMatcherConditionSet::Conditions& conditions =
862 condition_set_iter->second->conditions(); 1063 condition_set_iter->second->conditions();
863 for (URLMatcherConditionSet::Conditions::const_iterator condition_iter = 1064 for (URLMatcherConditionSet::Conditions::const_iterator condition_iter =
864 conditions.begin(); condition_iter != conditions.end(); 1065 conditions.begin(); condition_iter != conditions.end();
865 ++condition_iter) { 1066 ++condition_iter) {
866 used_patterns.insert(condition_iter->string_pattern()->id()); 1067 used_patterns.insert(condition_iter->string_pattern()->id());
867 } 1068 }
1069 const URLMatcherConditionSet::QueryConditions& query_conditions =
1070 condition_set_iter->second->query_conditions();
1071 for (URLMatcherConditionSet::QueryConditions::const_iterator
1072 query_condition_iter = query_conditions.begin();
1073 query_condition_iter != query_conditions.end();
1074 ++query_condition_iter) {
1075 used_patterns.insert(query_condition_iter->string_pattern()->id());
1076 }
868 } 1077 }
869 condition_factory_.ForgetUnusedPatterns(used_patterns); 1078 condition_factory_.ForgetUnusedPatterns(used_patterns);
870 } 1079 }
871 1080
872 void URLMatcher::UpdateInternalDatastructures() { 1081 void URLMatcher::UpdateInternalDatastructures() {
873 UpdateSubstringSetMatcher(false); 1082 UpdateSubstringSetMatcher(false);
874 UpdateSubstringSetMatcher(true); 1083 UpdateSubstringSetMatcher(true);
875 UpdateRegexSetMatcher(); 1084 UpdateRegexSetMatcher();
876 UpdateTriggers(); 1085 UpdateTriggers();
877 UpdateConditionFactory(); 1086 UpdateConditionFactory();
878 } 1087 }
879 1088
880 } // namespace url_matcher 1089 } // namespace url_matcher
OLDNEW
« no previous file with comments | « components/url_matcher/url_matcher.h ('k') | components/url_matcher/url_matcher_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698