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

Side by Side Diff: lib/elemHide.js

Issue 4529242486341632: Issue 235 - Improved performance of ElemHide.getSelectorsForDomain() (Closed)
Patch Set: Optimized performance of data structure removal Created Jan. 22, 2015, 2:43 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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-2015 Eyeo GmbH 3 * Copyright (C) 2006-2015 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 */ 52 */
53 let exceptions = Object.create(null); 53 let exceptions = Object.create(null);
54 54
55 /** 55 /**
56 * Currently applied stylesheet URL 56 * Currently applied stylesheet URL
57 * @type nsIURI 57 * @type nsIURI
58 */ 58 */
59 let styleURL = null; 59 let styleURL = null;
60 60
61 /** 61 /**
62 * Lookup table, blocking filters by domain which they are applied to
63 * @type Object
64 */
65 let filtersByDomain = Object.create(null);
66
67 /**
62 * Element hiding component 68 * Element hiding component
63 * @class 69 * @class
64 */ 70 */
65 let ElemHide = exports.ElemHide = 71 let ElemHide = exports.ElemHide =
66 { 72 {
67 /** 73 /**
68 * Indicates whether filters have been added or removed since the last apply() call. 74 * Indicates whether filters have been added or removed since the last apply() call.
69 * @type Boolean 75 * @type Boolean
70 */ 76 */
71 isDirty: false, 77 isDirty: false,
(...skipping 26 matching lines...) Expand all
98 104
99 /** 105 /**
100 * Removes all known filters 106 * Removes all known filters
101 */ 107 */
102 clear: function() 108 clear: function()
103 { 109 {
104 filterByKey = Object.create(null); 110 filterByKey = Object.create(null);
105 keyByFilter = Object.create(null); 111 keyByFilter = Object.create(null);
106 knownExceptions = Object.create(null); 112 knownExceptions = Object.create(null);
107 exceptions = Object.create(null); 113 exceptions = Object.create(null);
114 filtersByDomain = Object.create(null);
108 ElemHide.isDirty = false; 115 ElemHide.isDirty = false;
109 ElemHide.unapply(); 116 ElemHide.unapply();
110 }, 117 },
111 118
112 /** 119 /**
113 * Add a new element hiding filter 120 * Add a new element hiding filter
114 * @param {ElemHideFilter} filter 121 * @param {ElemHideFilter} filter
115 */ 122 */
116 add: function(filter) 123 add: function(filter)
117 { 124 {
118 if (filter instanceof ElemHideException) 125 if (filter instanceof ElemHideException)
119 { 126 {
120 if (filter.text in knownExceptions) 127 if (filter.text in knownExceptions)
121 return; 128 return;
122 129
123 let selector = filter.selector; 130 let selector = filter.selector;
124 if (!(selector in exceptions)) 131 if (!(selector in exceptions))
125 exceptions[selector] = []; 132 exceptions[selector] = [];
126 exceptions[selector].push(filter); 133 exceptions[selector].push(filter);
127 knownExceptions[filter.text] = true; 134 knownExceptions[filter.text] = true;
128 } 135 }
129 else 136 else
130 { 137 {
131 if (filter.text in keyByFilter) 138 if (filter.text in keyByFilter)
132 return; 139 return;
133 140
141 if (!("nsIStyleSheetService" in Ci))
Wladimir Palant 2015/02/23 19:20:16 Looking up things in Components.interfaces isn't s
Thomas Greiner 2015/03/12 16:00:06 Done.
142 {
143 let domains = filter.domains;
144 if (domains === null)
145 {
146 domains = Object.create(null);
147 domains[""] = undefined;
Wladimir Palant 2015/02/23 19:20:16 This should be true, not undefined.
Thomas Greiner 2015/03/12 16:00:06 Done.
148 }
149
150 for (let domain in domains)
151 {
152 if (!(domain in filtersByDomain))
153 {
154 filtersByDomain[domain] = Object.create(null);
155 filtersByDomain[domain]._length = 0;
156 }
157
158 filtersByDomain[domain][filter.text] = filter.isActiveOnDomain(domain) ;
Wladimir Palant 2015/02/23 19:20:16 The very point of this functionality is to avoid c
Thomas Greiner 2015/03/12 16:00:06 Done, you're right that it appears to be redundant
159 filtersByDomain[domain]._length++;
Wladimir Palant 2015/02/23 19:20:16 Strictly speaking, _length isn't an invalid domain
Thomas Greiner 2015/03/12 16:00:06 That's true but that might make it difficult to sp
160 }
161 }
162
134 let key; 163 let key;
135 do { 164 do {
136 key = Math.random().toFixed(15).substr(5); 165 key = Math.random().toFixed(15).substr(5);
137 } while (key in filterByKey); 166 } while (key in filterByKey);
138 167
139 filterByKey[key] = filter; 168 filterByKey[key] = filter;
140 keyByFilter[filter.text] = key; 169 keyByFilter[filter.text] = key;
141 ElemHide.isDirty = true; 170 ElemHide.isDirty = true;
142 } 171 }
143 }, 172 },
(...skipping 13 matching lines...) Expand all
157 let index = list.indexOf(filter); 186 let index = list.indexOf(filter);
158 if (index >= 0) 187 if (index >= 0)
159 list.splice(index, 1); 188 list.splice(index, 1);
160 delete knownExceptions[filter.text]; 189 delete knownExceptions[filter.text];
161 } 190 }
162 else 191 else
163 { 192 {
164 if (!(filter.text in keyByFilter)) 193 if (!(filter.text in keyByFilter))
165 return; 194 return;
166 195
196 if (!("nsIStyleSheetService" in Ci))
197 {
198 let domains = filter.domains;
199 if (!domains)
200 {
201 domains = Object.create(null);
202 domains[""] = undefined;
Wladimir Palant 2015/02/23 19:20:16 This should be true, not undefined.
Thomas Greiner 2015/03/12 16:00:06 Done.
203 }
204
205 for (let domain in domains)
206 {
207 if (domain in filtersByDomain && filter.text in filtersByDomain[domain ])
208 {
209 delete filtersByDomain[domain][filter.text];
210 if (!--filtersByDomain[domain]._length)
211 delete filtersByDomain[domain];
212 }
213 }
214 }
215
167 let key = keyByFilter[filter.text]; 216 let key = keyByFilter[filter.text];
168 delete filterByKey[key]; 217 delete filterByKey[key];
169 delete keyByFilter[filter.text]; 218 delete keyByFilter[filter.text];
170 ElemHide.isDirty = true; 219 ElemHide.isDirty = true;
171 } 220 }
172 }, 221 },
173 222
174 /** 223 /**
175 * Checks whether an exception rule is registered for a filter on a particular 224 * Checks whether an exception rule is registered for a filter on a particular
176 * domain. 225 * domain.
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 /** 415 /**
367 * Retrieves an element hiding filter by the corresponding protocol key 416 * Retrieves an element hiding filter by the corresponding protocol key
368 */ 417 */
369 getFilterByKey: function(/**String*/ key) /**Filter*/ 418 getFilterByKey: function(/**String*/ key) /**Filter*/
370 { 419 {
371 return (key in filterByKey ? filterByKey[key] : null); 420 return (key in filterByKey ? filterByKey[key] : null);
372 }, 421 },
373 422
374 /** 423 /**
375 * Returns a list of all selectors active on a particular domain (currently 424 * Returns a list of all selectors active on a particular domain (currently
376 * used only in Chrome, Opera and Safari). 425 * used only in Chrome, Opera and Safari).
Wladimir Palant 2015/02/23 19:20:16 This comment is no longer correct. Either way, it
Thomas Greiner 2015/03/12 16:00:06 Done.
377 */ 426 */
378 getSelectorsForDomain: function(/**String*/ domain, /**Boolean*/ specificOnly) 427 getSelectorsForDomain: function(/**String*/ domain, /**Boolean*/ specificOnly)
379 { 428 {
Wladimir Palant 2015/02/23 19:20:16 How about an exception here on Firefox, to explain
Thomas Greiner 2015/03/12 16:00:06 Done.
380 let result = []; 429 let selectors = [];
381 for (let key in filterByKey) 430 domain = domain.toUpperCase();
431
432 if (!specificOnly)
382 { 433 {
383 let filter = filterByKey[key]; 434 let filterTexts = filtersByDomain[""];
384 if (specificOnly && (!filter.domains || filter.domains[""])) 435 if (filterTexts)
385 continue; 436 {
437 for (let filterText in filterTexts)
438 {
439 if (filterTexts[filterText])
440 {
441 let filter = filterByKey[keyByFilter[filterText]];
442 if (!filter)
443 continue;
444
445 let selector = filter.selector;
446 if (filter.isActiveOnDomain(docDomain) && !this.getException(selecto r, docDomain))
Thomas Greiner 2015/03/12 16:00:06 Done.
447 selectors[selectors.length] = selector;
448 }
449 }
450 }
451 }
386 452
387 if (filter.isActiveOnDomain(domain) && !this.getException(filter, domain)) 453 while (true)
388 result.push(filter.selector); 454 {
455 if (domain && domain in filtersByDomain)
456 {
457 let filterTexts = filtersByDomain[domain];
458 if (filterTexts)
Wladimir Palant 2015/02/23 19:20:16 This check seems pointless - if a property exists
Thomas Greiner 2015/03/12 16:00:06 Done.
459 {
460 for (let filterText in filterTexts)
461 {
462 if (filterTexts[filterText])
463 {
464 let filter = filterByKey[keyByFilter[filterText]];
Wladimir Palant 2015/02/23 19:20:16 let filter = Filter.fromText(filterText);
Thomas Greiner 2015/03/12 16:00:06 Done.
465 if (!filter)
466 continue;
467
468 let selector = filter.selector;
469 if (!this.getException(selector, docDomain))
470 selectors[selectors.length] = selector;
Wladimir Palant 2015/02/23 19:20:16 You meant using selectors.push(), right?
Thomas Greiner 2015/03/12 16:00:06 This turned out to be about ~3ms faster for each c
471 }
472 }
473 }
474 }
475
476 let nextDot = domain.indexOf(".");
477 if (nextDot < 0)
478 break;
479 domain = domain.substr(nextDot + 1);
389 } 480 }
Wladimir Palant 2015/02/23 19:20:16 This logic is wrong, we can have a filter ~subdoma
Thomas Greiner 2015/03/12 16:00:06 Indeed, that's true. I added the `ignorableFilters
390 return result; 481
482 return selectors;
391 } 483 }
392 }; 484 };
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld