-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Use nullIterable instead of new Set in RuleSets.ruleCache #12577
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,6 +26,20 @@ const trivial_rule_from_c = new RegExp("^http:"); | |
| const trivial_cookie_name_c = new RegExp(".*"); | ||
| const trivial_cookie_host_c = new RegExp(".*"); | ||
|
|
||
|
|
||
| // Empty iterable singleton to reduce memory usage | ||
| const nullIterable = Object.create(null, { | ||
| [Symbol.iterator]: { | ||
| value: function* () { | ||
| // do nothing | ||
| } | ||
| }, | ||
|
|
||
| size: { | ||
| value: 0 | ||
| }, | ||
| }); | ||
|
|
||
| /** | ||
| * A single rule | ||
| * @param from | ||
|
|
@@ -416,63 +430,70 @@ RuleSets.prototype = { | |
| */ | ||
| potentiallyApplicableRulesets: function(host) { | ||
| // Have we cached this result? If so, return it! | ||
| var cached_item = this.ruleCache.get(host); | ||
| if (cached_item !== undefined) { | ||
| util.log(util.DBUG, "Ruleset cache hit for " + host + " items:" + cached_item.length); | ||
| if (this.ruleCache.has(host)) { | ||
| let cached_item = this.ruleCache.get(host); | ||
| util.log(DBUG, "Ruleset cache hit for " + host + " items:" + cached_item.size); | ||
| return cached_item; | ||
| } else { | ||
| util.log(DBUG, "Ruleset cache miss for " + host); | ||
| } | ||
| util.log(util.DBUG, "Ruleset cache miss for " + host); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are some issues with how this was merged, this line should have been kept (it should be |
||
|
|
||
| var results = []; | ||
| if (this.targets.has(host)) { | ||
| // Copy the host targets so we don't modify them. | ||
| results = results.concat(this.targets.get(host)); | ||
| } | ||
| // Let's begin search | ||
| // Copy the host targsts so we don't modify them. | ||
| let results = (this.targets.has(host) ? | ||
| new Set([...this.targets.get(host)]) : | ||
| new Set()); | ||
|
|
||
| // Ensure host is well-formed (RFC 1035) | ||
| if (host.indexOf("..") != -1 || host.length > 255) { | ||
| util.log(util.WARN,"Malformed host passed to potentiallyApplicableRulesets: " + host); | ||
| return null; | ||
| if (host.length > 255 || host.indexOf("..") != -1) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This makes sense 👍 |
||
| util.log(WARN,"Malformed host passed to potentiallyApplicableRulesets: " + host); | ||
| return nullIterable; | ||
| } | ||
|
|
||
| // Replace each portion of the domain with a * in turn | ||
| var segmented = host.split("."); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please avoid renaming and changing this code unless its necessary to the PR. This algorithm is important, but isn't well tested unfortunately. |
||
| for (let i=0; i < segmented.length; i++) { | ||
| let segmented = host.split("."); | ||
| for (let i = 0; i < segmented.length; i++) { | ||
| let tmp = segmented[i]; | ||
| segmented[i] = "*"; | ||
| results = results.concat(this.targets.get(segmented.join("."))); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could be something like my above comment, (https://github.com/EFForg/https-everywhere/pull/12577/files#r139258106) or maybe a ternary expression like results = (this.targets.has(segmented.join('.')) ?
(new Set([...results, ...this.targets.get(segmented.join('.')]) :
results); |
||
|
|
||
| results = (this.targets.has(segmented.join(".")) ? | ||
| new Set([...results, ...this.targets.get(segmented.join("."))]) : | ||
| results); | ||
|
|
||
| segmented[i] = tmp; | ||
| } | ||
|
|
||
| // now eat away from the left, with *, so that for x.y.z.google.com we | ||
| // check *.z.google.com and *.google.com (we did *.y.z.google.com above) | ||
| for (var i = 2; i <= segmented.length - 2; ++i) { | ||
| var t = "*." + segmented.slice(i,segmented.length).join("."); | ||
| results = results.concat(this.targets.get(t)); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please revert this rename. Then just use one of the methods I suggested above to update the |
||
| for (let i = 2; i <= segmented.length - 2; i++) { | ||
| let t = "*." + segmented.slice(i, segmented.length).join("."); | ||
|
|
||
| results = (this.targets.has(t) ? | ||
| new Set([...results, ...this.targets.get(t)]) : | ||
| results); | ||
| } | ||
|
|
||
| // Clean the results list, which may contain duplicates or undefined entries | ||
| var resultSet = new Set(results); | ||
| resultSet.delete(undefined); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Keep a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what |
||
| results.delete(undefined); | ||
|
|
||
| util.log(util.DBUG,"Applicable rules for " + host + ":"); | ||
| if (resultSet.size == 0) { | ||
| util.log(util.DBUG, " None"); | ||
| log(DBUG,"Applicable rules for " + host + ":"); | ||
| if (results.size == 0) { | ||
| util.log(DBUG, " None"); | ||
| results = nullIterable; | ||
| } else { | ||
| for (let target of resultSet.values()) { | ||
| util.log(util.DBUG, " " + target.name); | ||
| } | ||
| results.forEach(result => util.log(DBUG, " " + result.name)); | ||
| } | ||
|
|
||
| // Insert results into the ruleset cache | ||
| this.ruleCache.set(host, resultSet); | ||
| this.ruleCache.set(host, results); | ||
|
|
||
| // Cap the size of the cache. (Limit chosen somewhat arbitrarily) | ||
| if (this.ruleCache.size > 1000) { | ||
| // Map.prototype.keys() returns keys in insertion order, so this is a FIFO. | ||
| this.ruleCache.delete(this.ruleCache.keys().next().value); | ||
| } | ||
|
|
||
| return resultSet; | ||
| return results; | ||
| }, | ||
|
|
||
| /** | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be done in a simpler way.
Will also save memory since it will not create a new iterator each time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having just one name is nice. How about just:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cowlicks
const nullIterable = (function* () {})()would be better.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cowlicks why use
Object.create(null, { ...?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cowlicks This will create a new instance of
{ next() { return { done: true } } }each time.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently I have this code:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@koops76 see #12577 (comment)
re: new instance of ... thing - that is fine, it should get GC'd immediately anyway