| Index: lib/matcher.js |
| =================================================================== |
| --- a/lib/matcher.js |
| +++ b/lib/matcher.js |
| @@ -146,16 +146,23 @@ |
| /** |
| * Blacklist/whitelist filter matching |
| */ |
| class Matcher |
| { |
| constructor() |
| { |
| /** |
| + * Lookup table for keywords by their associated filter |
| + * @type {Map.<RegExpFilter,string>} |
| + * @private |
| + */ |
| + this._keywordsByFilter = new Map(); |
| + |
| + /** |
| * Lookup table for simple filters by their associated keyword |
| * @type {Map.<string,(RegExpFilter|Set.<RegExpFilter>)>} |
| * @private |
| */ |
| this._simpleFiltersByKeyword = new Map(); |
| /** |
| * Lookup table for complex filters by their associated keyword |
| @@ -173,35 +180,41 @@ |
| this._filterMapsByType = new Map(); |
| } |
| /** |
| * Removes all known filters |
| */ |
| clear() |
| { |
| + this._keywordsByFilter.clear(); |
| this._simpleFiltersByKeyword.clear(); |
| this._complexFiltersByKeyword.clear(); |
| this._filterMapsByType.clear(); |
| } |
| /** |
| * Adds a filter to the matcher |
| * @param {RegExpFilter} filter |
| */ |
| add(filter) |
| { |
| + if (this._keywordsByFilter.has(filter)) |
| + return; |
| + |
| // Look for a suitable keyword |
| let keyword = this.findKeyword(filter); |
| let locationOnly = filter.isLocationOnly(); |
| addFilterByKeyword(filter, keyword, |
| locationOnly ? this._simpleFiltersByKeyword : |
| this._complexFiltersByKeyword); |
| + this._keywordsByFilter.set(filter, keyword); |
| + |
| if (locationOnly) |
| return; |
| for (let type of nonDefaultTypes(filter.contentType)) |
| { |
| let map = this._filterMapsByType.get(type); |
| if (!map) |
| this._filterMapsByType.set(type, map = new Map()); |
| @@ -211,23 +224,28 @@ |
| } |
| /** |
| * Removes a filter from the matcher |
| * @param {RegExpFilter} filter |
| */ |
| remove(filter) |
| { |
| - let keyword = this.findKeyword(filter); |
| + let keyword = this._keywordsByFilter.get(filter); |
| + if (typeof keyword == "undefined") |
| + return; |
| + |
| let locationOnly = filter.isLocationOnly(); |
| removeFilterByKeyword(filter, keyword, |
| locationOnly ? this._simpleFiltersByKeyword : |
| this._complexFiltersByKeyword); |
| + this._keywordsByFilter.delete(filter); |
| + |
| if (locationOnly) |
| return; |
| for (let type of nonDefaultTypes(filter.contentType)) |
| { |
| let map = this._filterMapsByType.get(type); |
| if (map) |
| removeFilterByKeyword(filter, keyword, map); |