Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: lib/elemHide.js

Issue 29342830: Issue 4057 - Further speedup ElemHide.getSelectorsforDomain (Closed)
Left Patch Set: Rebased, unconditionalSelectors Created May 24, 2016, 2:39 p.m.
Right Patch Set: Addressed nits Created May 25, 2016, 10:50 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | test/elemHide.js » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2016 Eyeo GmbH 3 * Copyright (C) 2006-2016 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 */ 54 */
55 var filtersByDomain = Object.create(null); 55 var filtersByDomain = Object.create(null);
56 56
57 /** 57 /**
58 * Lookup table, filters by selector. (Only contains filters that have a 58 * Lookup table, filters by selector. (Only contains filters that have a
59 * selector that is unconditionally matched for all domains.) 59 * selector that is unconditionally matched for all domains.)
60 */ 60 */
61 var filtersBySelector = Object.create(null); 61 var filtersBySelector = Object.create(null);
62 62
63 /** 63 /**
64 * Array of selectors which unconditionally apply to all domains. 64 * This array caches the keys of filtersBySelector table (selectors which
65 */ 65 * unconditionally apply on all domains). It will be null if the cache needs to
66 var unconditionalSelectors = []; 66 * be rebuilt.
67 */
68 var unconditionalSelectors = null;
67 69
68 /** 70 /**
69 * Object to be used instead when a filter has a blank domains property. 71 * Object to be used instead when a filter has a blank domains property.
70 */ 72 */
71 var defaultDomains = Object.create(null); 73 var defaultDomains = Object.create(null);
72 defaultDomains[""] = true; 74 defaultDomains[""] = true;
73 75
74 /** 76 /**
75 * Lookup table, keys are known element hiding exceptions 77 * Lookup table, keys are known element hiding exceptions
76 * @type Object 78 * @type Object
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 128
127 /** 129 /**
128 * Removes all known filters 130 * Removes all known filters
129 */ 131 */
130 clear: function() 132 clear: function()
131 { 133 {
132 filterByKey = []; 134 filterByKey = [];
133 keyByFilter = Object.create(null); 135 keyByFilter = Object.create(null);
134 filtersByDomain = Object.create(null); 136 filtersByDomain = Object.create(null);
135 filtersBySelector = Object.create(null); 137 filtersBySelector = Object.create(null);
136 unconditionalSelectors = []; 138 unconditionalSelectors = null;
137 knownExceptions = Object.create(null); 139 knownExceptions = Object.create(null);
138 exceptions = Object.create(null); 140 exceptions = Object.create(null);
139 ElemHide.isDirty = false; 141 ElemHide.isDirty = false;
140 ElemHide.unapply(); 142 ElemHide.unapply();
141 }, 143 },
142 144
143 _addToFiltersByDomain: function(filter) 145 _addToFiltersByDomain: function(filter)
144 { 146 {
145 let key = keyByFilter[filter.text]; 147 let key = keyByFilter[filter.text];
146 let domains = filter.domains || defaultDomains; 148 let domains = filter.domains || defaultDomains;
(...skipping 30 matching lines...) Expand all
177 { 179 {
178 // If this is the first exception for a previously unconditionally 180 // If this is the first exception for a previously unconditionally
179 // applied element hiding selector we need to take care to update the 181 // applied element hiding selector we need to take care to update the
180 // lookups. 182 // lookups.
181 let unconditionalFilters = filtersBySelector[selector]; 183 let unconditionalFilters = filtersBySelector[selector];
182 if (unconditionalFilters) 184 if (unconditionalFilters)
183 { 185 {
184 for (let f of unconditionalFilters) 186 for (let f of unconditionalFilters)
185 this._addToFiltersByDomain(f); 187 this._addToFiltersByDomain(f);
186 delete filtersBySelector[selector]; 188 delete filtersBySelector[selector];
187 let index = unconditionalSelectors.indexOf(selector); 189 unconditionalSelectors = null;
188 unconditionalSelectors.splice(index, 1);
189 } 190 }
190 } 191 }
191 192
192 knownExceptions[filter.text] = true; 193 knownExceptions[filter.text] = true;
193 } 194 }
194 else 195 else
195 { 196 {
196 if (filter.text in keyByFilter) 197 if (filter.text in keyByFilter)
197 return; 198 return;
198 199
199 let key = filterByKey.push(filter) - 1; 200 let key = filterByKey.push(filter) - 1;
200 keyByFilter[filter.text] = key; 201 keyByFilter[filter.text] = key;
201 202
202 if (usingGetSelectorsForDomain) 203 if (usingGetSelectorsForDomain)
203 { 204 {
204 // The new filter's selector is unconditionally applied to all domains 205 if (!(filter.domains || filter.selector in exceptions))
Wladimir Palant 2016/05/24 15:16:18 This comment belongs inside the if block since it
kzar 2016/05/25 05:12:24 Done.
205 if (!filter.domains && !exceptions[filter.selector]) 206 {
Wladimir Palant 2016/05/24 15:16:19 We don't really care about the value of exceptions
kzar 2016/05/25 05:12:24 Done.
206 { 207 // The new filter's selector is unconditionally applied to all domains
207 let filters = filtersBySelector[filter.selector]; 208 let filters = filtersBySelector[filter.selector];
208 if (filters) 209 if (filters)
209 { 210 {
210 filters.push(filter); 211 filters.push(filter);
211 } 212 }
212 else 213 else
213 { 214 {
214 filtersBySelector[filter.selector] = [filter]; 215 filtersBySelector[filter.selector] = [filter];
215 unconditionalSelectors.push(filter.selector); 216 unconditionalSelectors = null;
216 } 217 }
217 } 218 }
218 // The new filter's selector only applies to some domains
Wladimir Palant 2016/05/24 15:16:18 Same here, comment inside the block please.
kzar 2016/05/25 05:12:24 Done.
219 else 219 else
220 { 220 {
221 // The new filter's selector only applies to some domains
221 this._addToFiltersByDomain(filter); 222 this._addToFiltersByDomain(filter);
222 } 223 }
223 } 224 }
224 225
225 ElemHide.isDirty = true; 226 ElemHide.isDirty = true;
226 } 227 }
227 }, 228 },
228 229
229 /** 230 /**
230 * Removes an element hiding filter 231 * Removes an element hiding filter
(...skipping 15 matching lines...) Expand all
246 else 247 else
247 { 248 {
248 if (!(filter.text in keyByFilter)) 249 if (!(filter.text in keyByFilter))
249 return; 250 return;
250 251
251 let key = keyByFilter[filter.text]; 252 let key = keyByFilter[filter.text];
252 delete filterByKey[key]; 253 delete filterByKey[key];
253 delete keyByFilter[filter.text]; 254 delete keyByFilter[filter.text];
254 ElemHide.isDirty = true; 255 ElemHide.isDirty = true;
255 256
256 if (usingGetSelectorsForDomain) 257 if (usingGetSelectorsForDomain)
kzar 2016/05/24 14:45:22 I'm worried about the performance of ElemHide.remo
Wladimir Palant 2016/05/24 15:16:19 A remove isn't a very common operation. Did you me
kzar 2016/05/24 17:47:09 Yea, it's pretty bad - something like 2325ms spent
kzar 2016/05/24 17:52:12 Another idea, maybe crazy... removing is expensive
kzar 2016/05/25 04:57:16 With Patch Set 5 ElemHide.remove is now down to ab
257 { 258 {
258 let filters = filtersBySelector[filter.selector]; 259 let filters = filtersBySelector[filter.selector];
259 if (filters) 260 if (filters)
260 { 261 {
261 if (filters.length > 1) 262 if (filters.length > 1)
262 { 263 {
263 let index = filters.indexOf(filter); 264 let index = filters.indexOf(filter);
264 filters.splice(index, 1); 265 filters.splice(index, 1);
265 } 266 }
266 else 267 else
267 { 268 {
268 delete filtersBySelector[filter.selector]; 269 delete filtersBySelector[filter.selector];
269 let index = unconditionalSelectors.indexOf(filter.selector); 270 unconditionalSelectors = null;
270 unconditionalSelectors.splice(index, 1);
271 } 271 }
272 } 272 }
273 else 273 else
274 { 274 {
275 let domains = filter.domains || defaultDomains; 275 let domains = filter.domains || defaultDomains;
276 for (let domain in domains) 276 for (let domain in domains)
277 { 277 {
278 let filters = filtersByDomain[domain]; 278 let filters = filtersByDomain[domain];
279 if (filters) 279 if (filters)
280 delete filters[key]; 280 delete filters[key];
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 490
491 /** 491 /**
492 * Returns a list of all selectors active on a particular domain, must not be 492 * Returns a list of all selectors active on a particular domain, must not be
493 * used in Firefox (when usingGetSelectorsForDomain is false). 493 * used in Firefox (when usingGetSelectorsForDomain is false).
494 */ 494 */
495 getSelectorsForDomain: function(/**String*/ domain, /**Boolean*/ specificOnly) 495 getSelectorsForDomain: function(/**String*/ domain, /**Boolean*/ specificOnly)
496 { 496 {
497 if (!usingGetSelectorsForDomain) 497 if (!usingGetSelectorsForDomain)
498 throw new Error("getSelectorsForDomain can not be used in Firefox!"); 498 throw new Error("getSelectorsForDomain can not be used in Firefox!");
499 499
500 let selectors = []; 500 if (!unconditionalSelectors)
501 unconditionalSelectors = Object.keys(filtersBySelector);
502 let selectors = specificOnly ? [] : unconditionalSelectors.slice();
501 503
502 let seenFilters = Object.create(null); 504 let seenFilters = Object.create(null);
503 let currentDomain = domain ? domain.toUpperCase() : ""; 505 let currentDomain = domain ? domain.toUpperCase() : "";
504 while (true) 506 while (true)
505 { 507 {
506 if (specificOnly && currentDomain == "") 508 if (specificOnly && currentDomain == "")
507 break; 509 break;
508 510
509 let filters = filtersByDomain[currentDomain]; 511 let filters = filtersByDomain[currentDomain];
510 if (filters) 512 if (filters)
(...skipping 10 matching lines...) Expand all
521 } 523 }
522 } 524 }
523 525
524 if (currentDomain == "") 526 if (currentDomain == "")
525 break; 527 break;
526 528
527 let nextDot = currentDomain.indexOf("."); 529 let nextDot = currentDomain.indexOf(".");
528 currentDomain = nextDot == -1 ? "" : currentDomain.substr(nextDot + 1); 530 currentDomain = nextDot == -1 ? "" : currentDomain.substr(nextDot + 1);
529 } 531 }
530 532
531 if (specificOnly) 533 return selectors;
Sebastian Noack 2016/05/24 15:20:07 Why do you still account for specificOnly inside t
Wladimir Palant 2016/05/24 15:26:06 Not all generic filters are in unconditionalSelect
532 return selectors;
533 else
Sebastian Noack 2016/05/24 15:20:07 Nit: extraneous else
kzar 2016/05/25 05:12:24 Done.
534 return unconditionalSelectors.concat(selectors);
Wladimir Palant 2016/05/24 15:16:19 I think we should avoid concatenating two arrays h
kzar 2016/05/25 05:12:24 Done.
535 } 534 }
536 }; 535 };
LEFTRIGHT
« no previous file | test/elemHide.js » ('j') | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

Powered by Google App Engine
This is Rietveld