Browse Source

cache testBlacklist results

tophf 6 years ago
parent
commit
fcbd53ad7d
1 changed files with 38 additions and 3 deletions
  1. 38 3
      src/background/utils/tester.js

+ 38 - 3
src/background/utils/tester.js

@@ -11,6 +11,21 @@ hookOptions((changes) => {
 });
 const RE_HTTP_OR_HTTPS = /^https?$/i;
 
+/*
+ Simple FIFO queue for the results of testBlacklist, cached separately from the main |cache|
+ because the blacklist is updated only once in a while so its entries would be crowding
+ the main cache and reducing its performance (objects with lots of keys are slow to access).
+
+ We also don't need to auto-expire the entries after a timeout.
+ The only limit we're concerned with is the overall memory used.
+ The limit is specified in the amount of unicode characters (string length) for simplicity.
+ Disregarding deduplication due to interning, the actual memory used is approximately twice as big:
+ 2 * keyLength + objectStructureOverhead * objectCount
+*/
+const MAX_BL_CACHE_LENGTH = 100e3;
+let blCache = {};
+let blCacheSize = 0;
+
 /**
  * Test glob rules like `@include` and `@exclude`.
  */
@@ -186,11 +201,15 @@ function checkPrefix(prefix, rule) {
 }
 
 export function testBlacklist(url) {
-  for (let i = 0; i < blacklistRules.length; i += 1) {
-    const { test, reject } = blacklistRules[i];
-    if (test(url)) return reject;
+  let res = blCache[url];
+  if (res === undefined) {
+    const rule = blacklistRules.find(({ test }) => test(url));
+    if (rule) res = rule.reject;
+    updateBlacklistCache(url, res || false);
   }
+  return res;
 }
+
 export function resetBlacklist(list) {
   const rules = list == null ? getOption('blacklist') : list;
   if (process.env.DEBUG) {
@@ -244,4 +263,20 @@ export function resetBlacklist(list) {
     };
   })
   .filter(Boolean);
+  blCache = {};
+  blCacheSize = 0;
+}
+
+function updateBlacklistCache(key, value) {
+  blCache[key] = value;
+  blCacheSize += key.length;
+  if (blCacheSize > MAX_BL_CACHE_LENGTH) {
+    Object.keys(blCache)
+    .some((k) => {
+      blCacheSize -= blCache[k].length;
+      delete blCache[k];
+      // reduce the cache to 75% so that this function doesn't run too often.
+      return blCacheSize < MAX_BL_CACHE_LENGTH * 3 / 4;
+    });
+  }
 }