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

Side by Side Diff: chrome/browser/extensions/api/declarative/url_matcher.cc

Issue 9390018: Implementation of a Matching strategy for URLs in the Declarative WebRequest API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleanup Created 8 years, 10 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/extensions/api/declarative/url_matcher.h"
6
7 #include <algorithm>
8
9 #include "base/logging.h"
10 #include "googleurl/src/gurl.h"
11
12 namespace extensions {
13
14 // This set of classes implement a mapping of URL Component Patterns, such as
15 // host_prefix, host_suffix, host_equals, ..., etc., to SubstringPatterns.
16 //
17 // The idea of this mapping is to reduce the problem of comparing many
18 // URL Component Patterns against one URL to the problem of searching many
19 // substrings in one string:
20 //
21 // ---------------------- --------------------
22 // | URL Query operator | ----translate----> | SubstringPattern |
23 // ---------------------- --------------------
24 // ^
25 // |
26 // compare
27 // |
28 // v
29 // ---------------------- --------------------
30 // | URL to compare | | |
31 // | to all URL Query | ----translate----> | String |
32 // | operators | | |
33 // ---------------------- --------------------
34 //
35 // The reason for this problem reduction is that there are efficient algorithms
36 // for searching many substrings in one string (see Aho-Corasick algorithm).
37 //
38 // Case 1: {host,path,query}_{prefix,suffix,equals} searches.
39 // ==========================================================
40 //
41 // For searches in this class, we normalize URLs as follows:
42 //
43 // Step 1:
44 // Remove scheme, port and segment from URL:
45 // -> http://www.example.com:8080/index.html?search=foo#first_match becomes
46 // www.example.com/index.html?search=foo
47 //
48 // We remove the scheme and port number because they can be checked later
49 // in a secondary filter step. We remove the segment (the #... part) because
50 // this is not guaranteed to be ASCII-7 encoded.
51 //
52 // Step 2:
53 // Translate URL to String and add the following position markers:
54 // - BU = Beginning of URL
55 // - ED = End of Domain
56 // - EP = End of Path
57 // - EU = End of URL
58 // Furthermore, the hostname is canonicalized to start with a ".".
59 //
60 // Position markers are represented as characters >127, which are therefore
61 // guaranteed not to be part of the ASCII-7 encoded URL character set.
62 //
63 // -> www.example.com/index.html?search=foo becomes
64 // BU .www.example.com ED /index.html EP ?search=foo EU
65 //
66 // -> www.example.com/index.html becomes
67 // BU .www.example.com ED /index.html EP EU
68 //
69 // Step 3:
70 // Translate URL Component Patterns as follows:
71 //
72 // host_prefix(prefix) = BU add_missing_dot_prefix(prefix)
73 // -> host_prefix("www.example") = BU .www.example
74 //
75 // host_suffix(suffix) = suffix ED
76 // -> host_suffix("example.com") = example.com ED
77 // -> host_suffix(".example.com") = .example.com ED
78 //
79 // host_equals(domain) = BU add_missing_dot_prefix(domain) ED
80 // -> host_equals("www.example.com") = BU .www.example.com ED
81 //
82 // Similarly for path query parameters ({path, query}_{prefix, suffix, equals}).
83 //
84 // With this, we can search the SubstringPatterns in the normalized URL.
85 //
86 //
87 // Case 2: url_{prefix,suffix,equals,contains} searches.
88 // =====================================================
89 //
90 // Step 1: as above
91 //
92 // Step 2:
93 // Translate URL to String and add the following position markers:
94 // - BU = Beginning of URL
95 // - EU = End of URL
96 // Furthermore, the hostname is canonicalized to start with a ".".
97 //
98 // -> www.example.com/index.html?search=foo becomes
99 // BU .www.example.com/index.html?search=foo EU
100 //
101 // url_prefix(prefix) = BU add_missing_dot_prefix(prefix)
102 // -> url_prefix("www.example") = BU .www.example
103 //
104 // url_contains(substring) = substring
105 // -> url_contains("index") = index
106 //
107 //
108 // Case 3: {host,path,query}_contains searches.
109 // ============================================
110 //
111 // These kinds of searches are not supported directly but can be derived
112 // by a combination of a url_contains() query followed by an explicit test:
113 //
114 // host_contains(str) = url_contains(str) followed by test whether str occurs
115 // in host comonent of original URL.
116 // -> host_contains("example.co") = example.co
117 // followed by gurl.host().find("example.co");
118 //
119 // [similarly for path_contains and query_contains].
120
121
122 //
123 // URLMatcherCondition
124 //
125
126 URLMatcherCondition::URLMatcherCondition()
127 : criterion_(HOST_PREFIX),
128 substring_pattern_(NULL) {}
129
130 URLMatcherCondition::URLMatcherCondition(
131 Criterion criterion,
132 const SubstringPattern* substring_pattern)
133 : criterion_(criterion),
134 substring_pattern_(substring_pattern) {}
135
136 URLMatcherCondition::URLMatcherCondition(const URLMatcherCondition& rhs)
137 : criterion_(rhs.criterion_),
138 substring_pattern_(rhs.substring_pattern_) {}
139
140 URLMatcherCondition& URLMatcherCondition::operator=(
141 const URLMatcherCondition& rhs) {
142 criterion_ = rhs.criterion_;
143 substring_pattern_ = rhs.substring_pattern_;
144 return *this;
145 }
146
147 bool URLMatcherCondition::operator<(const URLMatcherCondition& rhs) const {
148 if (criterion_ < rhs.criterion_) return true;
149 if (criterion_ > rhs.criterion_) return false;
150 if (substring_pattern_ != NULL && rhs.substring_pattern_ != NULL)
151 return *substring_pattern_ < *rhs.substring_pattern_;
152 if (substring_pattern_ == NULL && rhs.substring_pattern_ != NULL) return true;
153 // Either substring_pattern_ != NULL && rhs.substring_pattern_ == NULL,
154 // or both are NULL.
155 return false;
156 }
157
158 bool URLMatcherCondition::IsFullURLCondition() const {
159 // For these criteria the SubstringMatcher needs to be executed on the
160 // GURL that is canonlizaliced with
161 // URLMatcherConditionFactory::CanonlicalizeURLForFullSearches.
162 switch (criterion_) {
163 case HOST_CONTAINS:
164 case PATH_CONTAINS:
165 case QUERY_CONTAINS:
166 case URL_PREFIX:
167 case URL_SUFFIX:
168 case URL_CONTAINS:
169 case URL_EQUALS:
170 return true;
171 default:
172 break;
173 }
174 return false;
175 }
176
177 bool URLMatcherCondition::IsMatch(
178 const std::set<SubstringPattern::ID>& matching_substring_patterns,
179 const GURL& url) const {
180 DCHECK(substring_pattern_);
181 if (matching_substring_patterns.find(substring_pattern_->id()) ==
182 matching_substring_patterns.end())
183 return false;
184 // The criteria HOST_CONTAINS, PATH_CONTAINS, QUERY_CONTAINS are based on
185 // a substring match on the raw URL. In case of a match, we need to verify
186 // that the match was found in the correct component of the URL.
187 switch (criterion_) {
188 case HOST_CONTAINS:
189 return url.host().find(substring_pattern_->pattern()) !=
190 std::string::npos;
191 case PATH_CONTAINS:
192 return url.path().find(substring_pattern_->pattern()) !=
193 std::string::npos;
194 case QUERY_CONTAINS:
195 return url.query().find(substring_pattern_->pattern()) !=
196 std::string::npos;
197 default:
198 break;
199 }
200 return true;
201 }
202
203 //
204 // URLMatcherConditionFactory
205 //
206
207 namespace {
208 // These are symbols that are not contained in 7-bit ASCII used in GURLs.
209 char kBeginningOfURL[] = {128, 0};
210 char kEndOfDomain[] = {129, 0};
211 char kEndOfPath[] = {130, 0};
212 char kEndOfURL[] = {131, 0};
213 } // namespace
214
215 URLMatcherConditionFactory::URLMatcherConditionFactory() : id_counter_(0) {}
216
217 URLMatcherConditionFactory::~URLMatcherConditionFactory() {
218 STLDeleteElements(&pattern_singletons_);
219 }
220
221 std::string URLMatcherConditionFactory::CanonlicalizeURLForComponentSearches(
222 const GURL& url) {
223 return kBeginningOfURL + CanonicalizeHostname(url.host()) + kEndOfDomain +
224 url.path() + kEndOfPath + (url.has_query() ? "?" + url.query() : "") +
225 kEndOfURL;
226 }
227
228 URLMatcherCondition URLMatcherConditionFactory::CreateHostPrefixCondition(
229 const std::string& prefix) {
230 return CreateCondition(URLMatcherCondition::HOST_PREFIX,
231 kBeginningOfURL + CanonicalizeHostname(prefix));
232 }
233
234 URLMatcherCondition URLMatcherConditionFactory::CreateHostSuffixCondition(
235 const std::string& suffix) {
236 return CreateCondition(URLMatcherCondition::HOST_SUFFIX,
237 suffix + kEndOfDomain);
238 }
239
240 URLMatcherCondition URLMatcherConditionFactory::CreateHostContainsCondition(
241 const std::string& str) {
242 return CreateCondition(URLMatcherCondition::HOST_CONTAINS, str);
243 }
244
245 URLMatcherCondition URLMatcherConditionFactory::CreateHostEqualsCondition(
246 const std::string& str) {
247 return CreateCondition(URLMatcherCondition::HOST_EQUALS,
248 kBeginningOfURL + CanonicalizeHostname(str) + kEndOfDomain);
249 }
250
251 URLMatcherCondition URLMatcherConditionFactory::CreatePathPrefixCondition(
252 const std::string& prefix) {
253 return CreateCondition(URLMatcherCondition::PATH_PREFIX,
254 kEndOfDomain + prefix);
255 }
256
257 URLMatcherCondition URLMatcherConditionFactory::CreatePathSuffixCondition(
258 const std::string& suffix) {
259 return CreateCondition(URLMatcherCondition::HOST_SUFFIX, suffix + kEndOfPath);
260 }
261
262 URLMatcherCondition URLMatcherConditionFactory::CreatePathContainsCondition(
263 const std::string& str) {
264 return CreateCondition(URLMatcherCondition::PATH_CONTAINS, str);
265 }
266
267 URLMatcherCondition URLMatcherConditionFactory::CreatePathEqualsCondition(
268 const std::string& str) {
269 return CreateCondition(URLMatcherCondition::PATH_EQUALS,
270 kEndOfDomain + str + kEndOfPath);
271 }
272
273 URLMatcherCondition URLMatcherConditionFactory::CreateQueryPrefixCondition(
274 const std::string& prefix) {
275 return CreateCondition(URLMatcherCondition::QUERY_PREFIX,
276 kEndOfPath + prefix);
277 }
278
279 URLMatcherCondition URLMatcherConditionFactory::CreateQuerySuffixCondition(
280 const std::string& suffix) {
281 return CreateCondition(URLMatcherCondition::QUERY_SUFFIX, suffix + kEndOfURL);
282 }
283
284 URLMatcherCondition URLMatcherConditionFactory::CreateQueryContainsCondition(
285 const std::string& str) {
286 return CreateCondition(URLMatcherCondition::QUERY_CONTAINS, str);
287 }
288
289 URLMatcherCondition URLMatcherConditionFactory::CreateQueryEqualsCondition(
290 const std::string& str) {
291 return CreateCondition(URLMatcherCondition::QUERY_EQUALS,
292 kEndOfPath + str + kEndOfURL);
293 }
294
295 URLMatcherCondition
296 URLMatcherConditionFactory::CreateHostSuffixPathPrefixCondition(
297 const std::string& host_suffix,
298 const std::string& path_prefix) {
299 return CreateCondition(URLMatcherCondition::HOST_SUFFIX_PATH_PREFIX,
300 host_suffix + kEndOfDomain + path_prefix);
301 }
302
303 std::string URLMatcherConditionFactory::CanonlicalizeURLForFullSearches(
304 const GURL& url) {
305 return kBeginningOfURL + CanonicalizeHostname(url.host()) + url.path() +
306 (url.has_query() ? "?" + url.query() : "") + kEndOfURL;
307 }
308
309 URLMatcherCondition URLMatcherConditionFactory::CreateURLPrefixCondition(
310 const std::string& prefix) {
311 return CreateCondition(URLMatcherCondition::URL_PREFIX,
312 kBeginningOfURL + CanonicalizeHostname(prefix));
313 }
314
315 URLMatcherCondition URLMatcherConditionFactory::CreateURLSuffixCondition(
316 const std::string& suffix) {
317 return CreateCondition(URLMatcherCondition::URL_SUFFIX, suffix + kEndOfURL);
318 }
319
320 URLMatcherCondition URLMatcherConditionFactory::CreateURLContainsCondition(
321 const std::string& str) {
322 return CreateCondition(URLMatcherCondition::URL_CONTAINS, str);
323 }
324
325 URLMatcherCondition URLMatcherConditionFactory::CreateURLEqualsCondition(
326 const std::string& str) {
327 return CreateCondition(URLMatcherCondition::QUERY_EQUALS,
328 kBeginningOfURL + CanonicalizeHostname(str) + kEndOfURL);
329 }
330
331 void URLMatcherConditionFactory::ForgetUnusedPatterns(
332 const std::set<SubstringPattern::ID>& used_patterns) {
333 PatternSingletons::iterator i = pattern_singletons_.begin();
334 while (i != pattern_singletons_.end()) {
335 if (used_patterns.find((*i)->id()) != used_patterns.end())
336 ++i;
337 else
338 pattern_singletons_.erase(i++);
339 }
340 }
341
342 URLMatcherCondition URLMatcherConditionFactory::CreateCondition(
343 URLMatcherCondition::Criterion criterion,
344 const std::string& pattern) {
345 SubstringPattern search_pattern(pattern, 0);
346 PatternSingletons::const_iterator iter =
347 pattern_singletons_.find(&search_pattern);
348 if (iter != pattern_singletons_.end()) {
349 return URLMatcherCondition(criterion, *iter);
350 } else {
351 SubstringPattern* new_pattern =
352 new SubstringPattern(pattern, id_counter_++);
353 pattern_singletons_.insert(new_pattern);
354 return URLMatcherCondition(criterion, new_pattern);
355 }
356 }
357
358 std::string URLMatcherConditionFactory::CanonicalizeHostname(
359 const std::string& hostname) const {
360 if (!hostname.empty() && hostname[0] == '.')
361 return hostname;
362 else
363 return "." + hostname;
364 }
365
366 size_t URLMatcherConditionFactory::HashFunction::operator()(
367 SubstringPattern* substring_pattern) const {
368 if (substring_pattern == NULL) return 0u;
369 return BASE_HASH_NAMESPACE::hash<std::string>()(substring_pattern->pattern());
370 }
371
372 bool URLMatcherConditionFactory::EqualsFunction::operator()(
373 SubstringPattern* lhs,
374 SubstringPattern* rhs) const {
375 if (lhs == NULL && rhs == NULL) return true;
376 if (lhs != NULL && rhs != NULL)
377 return lhs->pattern() == rhs->pattern();
378 return false;
379 }
380
381 //
382 // URLMatcherConditionSet
383 //
384
385 URLMatcherConditionSet::URLMatcherConditionSet() : id_(-1) {}
386
387 URLMatcherConditionSet::URLMatcherConditionSet(
388 ID id,
389 const Conditions& conditions)
390 : id_(id),
391 conditions_(conditions) {}
392
393 URLMatcherConditionSet::URLMatcherConditionSet(
394 const URLMatcherConditionSet& rhs)
395 : id_(rhs.id_), conditions_(rhs.conditions_) {}
396
397 URLMatcherConditionSet& URLMatcherConditionSet::operator=(
398 const URLMatcherConditionSet& rhs) {
399 id_ = rhs.id_;
400 conditions_ = rhs.conditions_;
401 return *this;
402 }
403
404 bool URLMatcherConditionSet::IsMatch(
405 const std::set<SubstringPattern::ID>& matching_substring_patterns,
406 const GURL& url) const {
407 for (Conditions::const_iterator i = conditions_.begin();
408 i != conditions_.end(); ++i) {
409 if (!i->IsMatch(matching_substring_patterns, url))
410 return false;
411 }
412 return true;
413 }
414
415
416 //
417 // URLMatcher
418 //
419
420 URLMatcher::URLMatcher() {}
421
422 void URLMatcher::AddConditionSets(
423 const std::vector<URLMatcherConditionSet>& condition_sets) {
424 for (std::vector<URLMatcherConditionSet>::const_iterator i =
425 condition_sets.begin(); i != condition_sets.end(); ++i) {
426 DCHECK(url_matcher_condition_sets_.find(i->id()) ==
427 url_matcher_condition_sets_.end());
428 url_matcher_condition_sets_[i->id()] = *i;
429 }
430 UpdateInternalDatastructures();
431 }
432
433 void URLMatcher::RemoveConditionSets(
434 const std::vector<URLMatcherConditionSet::ID>& condition_set_ids) {
435 for (std::vector<URLMatcherConditionSet::ID>::const_iterator i =
436 condition_set_ids.begin(); i != condition_set_ids.end(); ++i) {
437 DCHECK(url_matcher_condition_sets_.find(*i) !=
438 url_matcher_condition_sets_.end());
439 url_matcher_condition_sets_.erase(*i);
440 }
441 UpdateInternalDatastructures();
442 }
443
444 std::set<URLMatcherConditionSet::ID> URLMatcher::MatchURL(const GURL& url) {
445 // See URLMatcherConditionFactory for the canonicalization of URLs and the
446 // distinction between full url searches and url component searches.
447
448 // Perform all full url searches.
449 std::string full_url =
450 condition_factory_.CanonlicalizeURLForFullSearches(url);
451 std::set<SubstringPattern::ID> full_url_matches;
452 full_url_matcher_.Match(full_url, &full_url_matches);
453
454 // Perform all url component searches.
455 std::string component_url =
456 condition_factory_.CanonlicalizeURLForComponentSearches(url);
457 std::set<SubstringPattern::ID> component_url_matches;
458 url_component_matcher_.Match(component_url, &component_url_matches);
459
460 // Build the union of both result sets.
Matt Perry 2012/02/15 22:45:18 Rather than doing this as a separate step, just pa
battre 2012/02/16 14:45:55 Done.
461 std::set<SubstringPattern::ID> matches;
462 if (full_url_matches.size() > component_url_matches.size()) {
463 matches.swap(full_url_matches);
464 matches.insert(component_url_matches.begin(), component_url_matches.end());
465 } else {
466 matches.swap(component_url_matches);
467 matches.insert(full_url_matches.begin(), full_url_matches.end());
468 }
469
470 // Calculate all URLMatcherConditionSet for which all URLMatcherConditions
471 // were fulfilled.
472 std::set<URLMatcherConditionSet::ID> result;
473 for (std::set<SubstringPattern::ID>::const_iterator i = matches.begin();
474 i != matches.end(); ++i) {
475 // For each URLMatcherConditionSet there is exactly one condition
476 // registered in substring_match_triggers_. This means that the following
477 // logic tests each URLMatcherConditionSet exactly once if it can be
478 // completely fulfilled.
479 std::set<URLMatcherConditionSet::ID>& condition_sets =
480 substring_match_triggers_[*i];
481 for (std::set<URLMatcherConditionSet::ID>::const_iterator j =
482 condition_sets.begin(); j != condition_sets.end(); ++j) {
483 if (url_matcher_condition_sets_[*j].IsMatch(matches, url))
484 result.insert(url_matcher_condition_sets_[*j].id());
Matt Perry 2012/02/15 22:45:18 Isn't *j the ID?
battre 2012/02/16 14:45:55 Done.
485 }
486 }
487
488 return result;
489 }
490
491 void URLMatcher::UpdateSubstringSetMatcher(bool full_url_conditions) {
492 // The purpose of |full_url_conditions| is just that we need to execute
493 // the same logic once for Full URL searches and once for URL Component
494 // searches (see URLMatcherConditionFactory).
495
496 // Determine which patterns need to be registered when this function
497 // terminates.
498 std::set<const SubstringPattern*> new_patterns;
499 for (URLMatcherConditionSets::const_iterator condition_set_iter =
500 url_matcher_condition_sets_.begin();
501 condition_set_iter != url_matcher_condition_sets_.end();
502 ++condition_set_iter) {
503 const URLMatcherConditionSet::Conditions& conditions =
504 condition_set_iter->second.conditions();
505 for (URLMatcherConditionSet::Conditions::const_iterator condition_iter =
506 conditions.begin(); condition_iter != conditions.end();
507 ++condition_iter) {
508 // If we are called to process Full URL searches, ignore all others,
509 // and vice versa.
510 if (full_url_conditions == condition_iter->IsFullURLCondition())
511 new_patterns.insert(condition_iter->substring_pattern());
512 }
513 }
514
515 // This is the set of patterns that were registered before this function
516 // is called.
517 std::set<const SubstringPattern*>& registered_patterns =
518 full_url_conditions ? registered_full_url_patterns_
519 : registered_url_component_patterns_;
520
521 // Add all patterns that are in new_patterns but not in registered_patterns.
522 std::vector<const SubstringPattern*> patterns_to_register;
523 std::set_difference(
524 new_patterns.begin(), new_patterns.end(),
525 registered_patterns.begin(), registered_patterns.end(),
526 std::back_inserter(patterns_to_register));
527
528 // Remove all patterns that are in registered_patterns but not in
529 // new_patterns.
530 std::vector<const SubstringPattern*> patterns_to_unregister;
531 std::set_difference(
532 registered_patterns.begin(), registered_patterns.end(),
533 new_patterns.begin(), new_patterns.end(),
534 std::back_inserter(patterns_to_unregister));
535
536 // Update the SubstringSetMatcher.
537 SubstringSetMatcher& url_matcher =
538 full_url_conditions ? full_url_matcher_ : url_component_matcher_;
539 url_matcher.RegisterAndUnregisterPatterns(patterns_to_register,
540 patterns_to_unregister);
541
542 // Update the set of registered_patterns for the next time this function
543 // is being called.
544 registered_patterns.swap(new_patterns);
545 }
546
547 void URLMatcher::UpdateTriggers() {
548 // Count substring pattern frequencies.
549 std::map<SubstringPattern::ID, size_t> substring_pattern_frequencies;
550 for (URLMatcherConditionSets::const_iterator condition_set_iter =
551 url_matcher_condition_sets_.begin();
552 condition_set_iter != url_matcher_condition_sets_.end();
553 ++condition_set_iter) {
554 const URLMatcherConditionSet::Conditions& conditions =
555 condition_set_iter->second.conditions();
556 for (URLMatcherConditionSet::Conditions::const_iterator condition_iter =
557 conditions.begin(); condition_iter != conditions.end();
558 ++condition_iter) {
559 const SubstringPattern* pattern = condition_iter->substring_pattern();
560 substring_pattern_frequencies[pattern->id()]++;
561 }
562 }
563
564 // Update trigger conditions: Determine for each URLMatcherConditionSet which
565 // URLMatcherCondition occurs least frequently in this URLMatcher. We assume
Matt Perry 2012/02/15 22:45:18 s/URLMatcherCondition/SubstringPattern, right?
battre 2012/02/16 14:45:55 Done.
566 // that this condition is very specific and occurs rarely in URLs. If a match
567 // occurs for this URLMatcherCondition, we want to test all other
568 // URLMatcherCondition in the respective URLMatcherConditionSet as well to
569 // see whether the entire URLMatcherConditionSet is considered matching.
570 substring_match_triggers_.clear();
571 for (URLMatcherConditionSets::const_iterator condition_set_iter =
572 url_matcher_condition_sets_.begin();
573 condition_set_iter != url_matcher_condition_sets_.end();
574 ++condition_set_iter) {
575 const URLMatcherConditionSet::Conditions& conditions =
576 condition_set_iter->second.conditions();
577 if (conditions.empty())
578 continue;
579 URLMatcherConditionSet::Conditions::const_iterator condition_iter =
580 conditions.begin();
581 SubstringPattern::ID trigger = condition_iter->substring_pattern()->id();
582 // We skip the first element in the following loop.
583 ++condition_iter;
584 for (; condition_iter != conditions.end(); ++condition_iter) {
585 SubstringPattern::ID current_id =
586 condition_iter->substring_pattern()->id();
587 if (substring_pattern_frequencies[trigger] >
588 substring_pattern_frequencies[current_id]) {
589 trigger = current_id;
590 }
591 }
592 substring_match_triggers_[trigger].insert(condition_set_iter->second.id());
593 }
594 }
595
596 void URLMatcher::UpdateConditionFactory() {
597 std::set<SubstringPattern::ID> used_patterns;
598 for (URLMatcherConditionSets::const_iterator condition_set_iter =
599 url_matcher_condition_sets_.begin();
600 condition_set_iter != url_matcher_condition_sets_.end();
601 ++condition_set_iter) {
602 const URLMatcherConditionSet::Conditions& conditions =
603 condition_set_iter->second.conditions();
604 for (URLMatcherConditionSet::Conditions::const_iterator condition_iter =
605 conditions.begin(); condition_iter != conditions.end();
606 ++condition_iter) {
607 used_patterns.insert(condition_iter->substring_pattern()->id());
608 }
609 }
610 condition_factory_.ForgetUnusedPatterns(used_patterns);
611 }
612
613 void URLMatcher::UpdateInternalDatastructures() {
614 UpdateSubstringSetMatcher(false);
615 UpdateSubstringSetMatcher(true);
616 UpdateTriggers();
617 UpdateConditionFactory();
618 }
619
620 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698