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

Side by Side Diff: lib/matcher.js

Issue 29719569: Issue 6467 - Use Map object for caching filter matches (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: Created March 10, 2018, 3:30 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-present eyeo GmbH 3 * Copyright (C) 2006-present 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 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 /** 241 /**
242 * Combines a matcher for blocking and exception rules, automatically sorts 242 * Combines a matcher for blocking and exception rules, automatically sorts
243 * rules into two Matcher instances. 243 * rules into two Matcher instances.
244 * @constructor 244 * @constructor
245 * @augments Matcher 245 * @augments Matcher
246 */ 246 */
247 function CombinedMatcher() 247 function CombinedMatcher()
248 { 248 {
249 this.blacklist = new Matcher(); 249 this.blacklist = new Matcher();
250 this.whitelist = new Matcher(); 250 this.whitelist = new Matcher();
251 this.resultCache = Object.create(null); 251 this.resultCache = new Map();
252 } 252 }
253 exports.CombinedMatcher = CombinedMatcher; 253 exports.CombinedMatcher = CombinedMatcher;
254 254
255 /** 255 /**
256 * Maximal number of matching cache entries to be kept 256 * Maximal number of matching cache entries to be kept
257 * @type {number} 257 * @type {number}
258 */ 258 */
259 CombinedMatcher.maxCacheEntries = 1000; 259 CombinedMatcher.maxCacheEntries = 1000;
260 260
261 CombinedMatcher.prototype = 261 CombinedMatcher.prototype =
262 { 262 {
263 /** 263 /**
264 * Matcher for blocking rules. 264 * Matcher for blocking rules.
265 * @type {Matcher} 265 * @type {Matcher}
266 */ 266 */
267 blacklist: null, 267 blacklist: null,
268 268
269 /** 269 /**
270 * Matcher for exception rules. 270 * Matcher for exception rules.
271 * @type {Matcher} 271 * @type {Matcher}
272 */ 272 */
273 whitelist: null, 273 whitelist: null,
274 274
275 /** 275 /**
276 * Lookup table of previous matchesAny results 276 * Lookup table of previous matchesAny results
277 * @type {Object} 277 * @type {Map.<string,Filter>}
278 */ 278 */
279 resultCache: null, 279 resultCache: null,
280 280
281 /** 281 /**
282 * Number of entries in resultCache
Manish Jethani 2018/03/10 15:54:37 There's no need for cacheEntries anymore.
283 * @type {number}
284 */
285 cacheEntries: 0,
286
287 /**
288 * @see Matcher#clear 282 * @see Matcher#clear
289 */ 283 */
290 clear() 284 clear()
291 { 285 {
292 this.blacklist.clear(); 286 this.blacklist.clear();
293 this.whitelist.clear(); 287 this.whitelist.clear();
294 this.resultCache = Object.create(null); 288 this.resultCache.clear();
295 this.cacheEntries = 0;
296 }, 289 },
297 290
298 /** 291 /**
299 * @see Matcher#add 292 * @see Matcher#add
300 * @param {Filter} filter 293 * @param {Filter} filter
301 */ 294 */
302 add(filter) 295 add(filter)
303 { 296 {
304 if (filter instanceof WhitelistFilter) 297 if (filter instanceof WhitelistFilter)
305 this.whitelist.add(filter); 298 this.whitelist.add(filter);
306 else 299 else
307 this.blacklist.add(filter); 300 this.blacklist.add(filter);
308 301
309 if (this.cacheEntries > 0) 302 this.resultCache.clear();
Manish Jethani 2018/03/10 15:54:37 We don't have to check the size here because we're
sergei 2018/03/12 12:03:00 I'm pretty sure that now it's even faster, tough i
310 {
311 this.resultCache = Object.create(null);
312 this.cacheEntries = 0;
313 }
314 }, 303 },
315 304
316 /** 305 /**
317 * @see Matcher#remove 306 * @see Matcher#remove
318 * @param {Filter} filter 307 * @param {Filter} filter
319 */ 308 */
320 remove(filter) 309 remove(filter)
321 { 310 {
322 if (filter instanceof WhitelistFilter) 311 if (filter instanceof WhitelistFilter)
323 this.whitelist.remove(filter); 312 this.whitelist.remove(filter);
324 else 313 else
325 this.blacklist.remove(filter); 314 this.blacklist.remove(filter);
326 315
327 if (this.cacheEntries > 0) 316 this.resultCache.clear();
328 {
329 this.resultCache = Object.create(null);
330 this.cacheEntries = 0;
331 }
332 }, 317 },
333 318
334 /** 319 /**
335 * @see Matcher#findKeyword 320 * @see Matcher#findKeyword
336 * @param {Filter} filter 321 * @param {Filter} filter
337 * @return {string} keyword 322 * @return {string} keyword
338 */ 323 */
339 findKeyword(filter) 324 findKeyword(filter)
340 { 325 {
341 if (filter instanceof WhitelistFilter) 326 if (filter instanceof WhitelistFilter)
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 }, 402 },
418 403
419 /** 404 /**
420 * @see Matcher#matchesAny 405 * @see Matcher#matchesAny
421 * @inheritdoc 406 * @inheritdoc
422 */ 407 */
423 matchesAny(location, typeMask, docDomain, thirdParty, sitekey, specificOnly) 408 matchesAny(location, typeMask, docDomain, thirdParty, sitekey, specificOnly)
424 { 409 {
425 let key = location + " " + typeMask + " " + docDomain + " " + thirdParty + 410 let key = location + " " + typeMask + " " + docDomain + " " + thirdParty +
426 " " + sitekey + " " + specificOnly; 411 " " + sitekey + " " + specificOnly;
427 if (key in this.resultCache)
428 return this.resultCache[key];
429 412
430 let result = this.matchesAnyInternal(location, typeMask, docDomain, 413 let result = this.resultCache.get(key);
431 thirdParty, sitekey, specificOnly); 414 if (result !== undefined)
Manish Jethani 2018/03/10 15:54:37 Assumption: an entry will never have a value of un
sergei 2018/03/12 12:03:01 AFAIK our coding style says to rather use `typeof
Manish Jethani 2018/03/12 13:42:42 This is really not about coding style. The cache c
sergei 2018/03/12 17:48:31 Please take a look around in this file, whenever o
Manish Jethani 2018/03/12 18:59:21 Done.
sergei 2018/03/13 13:56:41 I still think we should discuss whether we use typ
Manish Jethani 2018/03/13 14:32:49 Yes, let's have that discussion.
415 return result;
432 416
433 if (this.cacheEntries >= CombinedMatcher.maxCacheEntries) 417 result = this.matchesAnyInternal(location, typeMask, docDomain,
434 { 418 thirdParty, sitekey, specificOnly);
435 this.resultCache = Object.create(null);
436 this.cacheEntries = 0;
437 }
438 419
439 this.resultCache[key] = result; 420 if (this.resultCache.size >= CombinedMatcher.maxCacheEntries)
Manish Jethani 2018/03/10 15:54:37 Again, we don't have to create a new object every
440 this.cacheEntries++; 421 this.resultCache.clear();
422
423 this.resultCache.set(key, result);
441 424
442 return result; 425 return result;
443 } 426 }
444 }; 427 };
445 428
446 /** 429 /**
447 * Shared CombinedMatcher instance that should usually be used. 430 * Shared CombinedMatcher instance that should usually be used.
448 * @type {CombinedMatcher} 431 * @type {CombinedMatcher}
449 */ 432 */
450 exports.defaultMatcher = new CombinedMatcher(); 433 exports.defaultMatcher = new CombinedMatcher();
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