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

Unified Diff: lib/matcher.js

Issue 29907586: Issue 6994 - Use shortcut matching for location only filters (Closed)
Patch Set: Address PS4, and rebase Created Oct. 24, 2018, 8:40 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: lib/matcher.js
===================================================================
--- a/lib/matcher.js
+++ b/lib/matcher.js
@@ -66,72 +66,87 @@
constructor()
{
/**
* Lookup table for filters by their associated keyword
* @type {Map.<string,(Filter|Set.<Filter>)>}
* @private
*/
this._filterByKeyword = new Map();
+
+ /**
+ * Lookup table for location only filters by their associated keyword
Manish Jethani 2018/10/24 21:35:28 Nit: I don't know if this is right, but I would ha
Jon Sonesen 2018/10/24 21:46:51 Acknowledged.
+ * for shortcut matching.
+ * @private
Manish Jethani 2018/10/24 21:35:28 Let's put @private last.
Jon Sonesen 2018/10/24 21:46:52 Acknowledged.
+ * @type {Map.<string,(Filter|Set.<Filter>)>}
+ */
+ this._fastFilterByKeyword = new Map();
Manish Jethani 2018/10/24 21:35:28 I'm thinking about the nomenclature here, about ho
Jon Sonesen 2018/10/24 21:46:52 I like this, it makes more sense from a reader's p
}
/**
* Removes all known filters
*/
clear()
{
this._filterByKeyword.clear();
+ this._fastFilterByKeyword.clear();
}
/**
* Adds a filter to the matcher
* @param {RegExpFilter} filter
*/
add(filter)
{
// Look for a suitable keyword
let keyword = this.findKeyword(filter);
- let set = this._filterByKeyword.get(keyword);
+ let filterMap = filter.isLocationOnly() ? this._fastFilterByKeyword :
+ this._filterByKeyword;
+ let set = filterMap.get(keyword);
+
if (typeof set == "undefined")
{
- this._filterByKeyword.set(keyword, filter);
+ filterMap.set(keyword, filter);
}
else if (set.size == 1)
{
if (filter != set)
- this._filterByKeyword.set(keyword, new Set([set, filter]));
+ filterMap.set(keyword, new Set([set, filter]));
}
else
{
set.add(filter);
}
}
/**
* Removes a filter from the matcher
* @param {RegExpFilter} filter
*/
remove(filter)
{
let keyword = this.findKeyword(filter);
- let set = this._filterByKeyword.get(keyword);
+ let filterMap = filter.isLocationOnly() ? this._fastFilterByKeyword :
+ this._filterByKeyword;
+ let set = filterMap.get(keyword);
+
if (typeof set == "undefined")
return;
if (set.size == 1)
{
if (filter == set)
- this._filterByKeyword.delete(keyword);
+ filterMap.delete(keyword);
}
else
{
set.delete(filter);
if (set.size == 1)
- this._filterByKeyword.set(keyword, [...set][0]);
+ filterMap.set(keyword, [...set][0]);
}
}
/**
* Chooses a keyword to be associated with the filter
* @param {Filter} filter
* @returns {string} keyword or an empty string if no keyword could be found
* @protected
@@ -142,17 +157,19 @@
let {pattern} = filter;
if (pattern == null)
return result;
let candidates = pattern.toLowerCase().match(allKeywordsRegExp);
if (!candidates)
return result;
- let hash = this._filterByKeyword;
+ let hash = filter.isLocationOnly() ? this._fastFilterByKeyword :
+ this._filterByKeyword;
+
let resultCount = 0xFFFFFF;
let resultLength = 0;
for (let i = 0, l = candidates.length; i < l; i++)
{
let candidate = candidates[i].substr(1);
let filters = hash.get(candidate);
let count = typeof filters != "undefined" ? filters.size : 0;
Manish Jethani 2018/10/25 00:49:42 We need `count` to be the sum of `this._simpleFilt
if (count < resultCount ||
@@ -178,17 +195,32 @@
* @returns {?Filter}
* @protected
*/
checkEntryMatch(keyword, location, typeMask, docDomain, thirdParty, sitekey,
specificOnly)
{
let set = this._filterByKeyword.get(keyword);
if (typeof set == "undefined")
Manish Jethani 2018/10/25 00:49:41 This is clearly wrong. We want to check all filter
+ {
+ let fastSet = this._fastFilterByKeyword.get(keyword);
+ if (typeof fastSet == "undefined")
+ return null;
+
+ for (let filter of fastSet)
+ {
+ if (specificOnly && filter.isGeneric() &&
+ !(filter instanceof WhitelistFilter))
+ continue;
+
+ if (filter.matchesLocation(location))
+ return filter;
+ }
return null;
+ }
for (let filter of set)
{
if (specificOnly && filter.isGeneric() &&
!(filter instanceof WhitelistFilter))
continue;
if (filter.matches(location, typeMask, docDomain, thirdParty, sitekey))
« lib/filterClasses.js ('K') | « lib/filterClasses.js ('k') | test/filterListener.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld