1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-11-05 18:32:30 +01:00

Reorganize filter instances deduplication code

Related commit:
- https://github.com/gorhill/uBlock/commit/ab629b9e1093
This commit is contained in:
Raymond Hill 2020-03-19 13:42:06 -04:00
parent a36566b348
commit 381498daa2
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2

View File

@ -345,6 +345,7 @@ const bidiTrieOptimize = function(shrink = false) {
*/
const filterClasses = [];
const filterArgsToUnit = new Map();
let filterClassIdGenerator = 0;
const registerFilterClass = function(ctor) {
@ -365,7 +366,21 @@ const filterFromCtor = function(ctor, ...args) {
const filterUnitFromCompiled = function(args) {
const ctor = filterClasses[args[0]];
return ctor.unitFromCompiled(args);
const keygen = ctor.keyFromArgs;
if ( keygen === undefined ) {
return filterUnits.push(ctor.fromCompiled(args)) - 1;
}
let key = `${ctor.fid}`;
const keyargs = keygen(args);
if ( keyargs !== undefined ) {
key += `\t${keyargs}`;
}
let iunit = filterArgsToUnit.get(key);
if ( iunit === undefined ) {
iunit = filterUnits.push(ctor.fromCompiled(args)) - 1;
filterArgsToUnit.set(key, iunit);
}
return iunit;
};
const filterFromSelfie = function(args) {
@ -374,29 +389,6 @@ const filterFromSelfie = function(args) {
/******************************************************************************/
// Optional manager to be used to reuse filters instances. This is useful
// when deduplicating instances is worth it. For examples, filter instances
// which have a high likelihood of larger than average memory usage per
// instance.
const filterInstanceManager = {
unitFromArgs: function(args, createFn) {
const key = JSON.stringify(args);
let iunit = this.argsToUnit.get(key);
if ( iunit === undefined ) {
iunit = createFn(args);
this.argsToUnit.set(key, iunit);
}
return iunit;
},
reset: function() {
this.argsToUnit.clear();
},
argsToUnit: new Map(),
};
/******************************************************************************/
const filterPattern = {
compile: function(parsed, units) {
if ( parsed.isRegex ) {
@ -501,18 +493,18 @@ const FilterTrue = class {
return [ FilterTrue.fid ];
}
static unitFromCompiled() {
return FilterTrue.filterUnit;
static fromCompiled() {
return new FilterTrue();
}
static fromSelfie() {
return FilterTrue.instance;
return new FilterTrue();
}
static keyFromArgs() {
}
};
FilterTrue.instance = new FilterTrue();
FilterTrue.filterUnit = filterUnits.push(FilterTrue.instance) - 1;
registerFilterClass(FilterTrue);
/******************************************************************************/
@ -562,18 +554,16 @@ const FilterPatternPlain = class {
return [ FilterPatternPlain.fid, details.f, details.tokenBeg ];
}
static unitFromCompiled(args) {
static fromCompiled(args) {
const i = bidiTrie.storeString(args[1]);
const n = args[1].length;
let f;
if ( args[2] === 0 ) {
f = new FilterPatternPlain(i, n);
} else if ( args[2] === 1 ) {
f = new FilterPatternPlain1(i, n);
} else {
f = new FilterPatternPlainX(i, n, args[2]);
return new FilterPatternPlain(i, n);
}
return filterUnits.push(f) - 1;
if ( args[2] === 1 ) {
return new FilterPatternPlain1(i, n);
}
return new FilterPatternPlainX(i, n, args[2]);
}
static fromSelfie(args) {
@ -678,10 +668,9 @@ const FilterPatternLeft = class {
];
}
static unitFromCompiled(args) {
static fromCompiled(args) {
const i = bidiTrie.storeString(args[1]);
const f = new FilterPatternLeft(i, args[1].length);
return filterUnits.push(f) - 1;
return new FilterPatternLeft(i, args[1].length);
}
static fromSelfie(args) {
@ -716,10 +705,9 @@ const FilterPatternLeftEx = class extends FilterPatternLeft {
details.regex.unshift(restrFromPlainPattern(s), restrSeparator, '.*');
}
static unitFromCompiled(args) {
static fromCompiled(args) {
const i = bidiTrie.storeString(args[1]);
const f = new FilterPatternLeftEx(i, args[1].length);
return filterUnits.push(f) - 1;
return new FilterPatternLeftEx(i, args[1].length);
}
static fromSelfie(args) {
@ -764,10 +752,9 @@ const FilterPatternRight = class {
];
}
static unitFromCompiled(args) {
static fromCompiled(args) {
const i = bidiTrie.storeString(args[1]);
const f = new FilterPatternRight(i, args[1].length);
return filterUnits.push(f) - 1;
return new FilterPatternRight(i, args[1].length);
}
static fromSelfie(args) {
@ -799,10 +786,9 @@ const FilterPatternRightEx = class extends FilterPatternRight {
details.regex.push(restrSeparator, '.*', restrFromPlainPattern(s));
}
static unitFromCompiled(args) {
static fromCompiled(args) {
const i = bidiTrie.storeString(args[1]);
const f = new FilterPatternRightEx(i, args[1].length);
return filterUnits.push(f) - 1;
return new FilterPatternRightEx(i, args[1].length);
}
static fromSelfie(args) {
@ -856,16 +842,17 @@ const FilterPatternGeneric = class {
return [ FilterPatternGeneric.fid, details.f, anchor ];
}
static unitFromCompiled(args) {
return filterInstanceManager.unitFromArgs(args, args => {
const f = new FilterPatternGeneric(args[1], args[2]);
return filterUnits.push(f) - 1;
});
static fromCompiled(args) {
return new FilterPatternGeneric(args[1], args[2]);
}
static fromSelfie(args) {
return new FilterPatternGeneric(args[1], args[2]);
}
static keyFromArgs(args) {
return `${args[1]}\t${args[2]}`;
}
};
FilterPatternGeneric.prototype.re = null;
@ -902,9 +889,8 @@ const FilterPlainHostname = class {
return [ FilterPlainHostname.fid, details.f ];
}
static unitFromCompiled(args) {
const f = new FilterPlainHostname(args[1]);
return filterUnits.push(f) - 1;
static fromCompiled(args) {
return new FilterPlainHostname(args[1]);
}
static fromSelfie(args) {
@ -970,19 +956,18 @@ const FilterAnchorHn = class {
return [ FilterAnchorHn.fid ];
}
static unitFromCompiled() {
return FilterAnchorHn.filterUnit;
static fromCompiled() {
return new FilterAnchorHn();
}
static fromSelfie() {
return FilterAnchorHn.instance;
return new FilterAnchorHn();
}
static keyFromArgs() {
}
};
FilterAnchorHn.instance = new FilterAnchorHn();
FilterAnchorHn.filterUnit = filterUnits.length;
filterUnits.push(FilterAnchorHn.instance);
registerFilterClass(FilterAnchorHn);
/******************************************************************************/
@ -1005,19 +990,18 @@ const FilterAnchorLeft = class {
return [ FilterAnchorLeft.fid ];
}
static unitFromCompiled() {
return FilterAnchorLeft.filterUnit;
static fromCompiled() {
return new FilterAnchorLeft();
}
static fromSelfie() {
return FilterAnchorLeft.instance;
return new FilterAnchorLeft();
}
static keyFromArgs() {
}
};
FilterAnchorLeft.instance = new FilterAnchorLeft();
FilterAnchorLeft.filterUnit = filterUnits.length;
filterUnits.push(FilterAnchorLeft.instance);
registerFilterClass(FilterAnchorLeft);
/******************************************************************************/
@ -1040,19 +1024,18 @@ const FilterAnchorRight = class {
return [ FilterAnchorRight.fid ];
}
static unitFromCompiled() {
return FilterAnchorRight.filterUnit;
static fromCompiled() {
return new FilterAnchorRight();
}
static fromSelfie() {
return FilterAnchorRight.instance;
return new FilterAnchorRight();
}
static keyFromArgs() {
}
};
FilterAnchorRight.instance = new FilterAnchorRight();
FilterAnchorRight.filterUnit = filterUnits.length;
filterUnits.push(FilterAnchorRight.instance);
registerFilterClass(FilterAnchorRight);
/******************************************************************************/
@ -1076,19 +1059,18 @@ const FilterTrailingSeparator = class {
return [ FilterTrailingSeparator.fid ];
}
static unitFromCompiled() {
return FilterTrailingSeparator.filterUnit;
static fromCompiled() {
return new FilterTrailingSeparator();
}
static fromSelfie() {
return FilterTrailingSeparator.instance;
return new FilterTrailingSeparator();
}
static keyFromArgs() {
}
};
FilterTrailingSeparator.instance = new FilterTrailingSeparator();
FilterTrailingSeparator.filterUnit = filterUnits.length;
filterUnits.push(FilterTrailingSeparator.instance);
registerFilterClass(FilterTrailingSeparator);
/******************************************************************************/
@ -1113,9 +1095,8 @@ const FilterType = class {
return [ FilterType.fid, details.typeBits & allNetworkTypesBits ];
}
static unitFromCompiled(args) {
const f = new FilterType(args[1]);
return filterUnits.push(f) - 1;
static fromCompiled(args) {
return new FilterType(args[1]);
}
static fromSelfie(args) {
@ -1159,16 +1140,17 @@ const FilterRegex = class {
return [ FilterRegex.fid, details.f ];
}
static unitFromCompiled(args) {
return filterInstanceManager.unitFromArgs(args, args => {
const f = new FilterRegex(args[1]);
return filterUnits.push(f) - 1;
});
static fromCompiled(args) {
return new FilterRegex(args[1]);
}
static fromSelfie(args) {
return new FilterRegex(args[1]);
}
static keyFromArgs(args) {
return args[1];
}
};
FilterRegex.prototype.re = null;
@ -1295,9 +1277,8 @@ const FilterOriginHit = class {
return [ FilterOriginHit.fid, domainOpt ];
}
static unitFromCompiled(args) {
const f = new FilterOriginHit(args[1]);
return filterUnits.push(f) - 1;
static fromCompiled(args) {
return new FilterOriginHit(args[1]);
}
static fromSelfie(args) {
@ -1340,9 +1321,8 @@ const FilterOriginMiss = class {
return [ FilterOriginMiss.fid, domainOpt ];
}
static unitFromCompiled(args) {
const f = new FilterOriginMiss(args[1]);
return filterUnits.push(f) - 1;
static fromCompiled(args) {
return new FilterOriginMiss(args[1]);
}
static fromSelfie(args) {
@ -1389,16 +1369,17 @@ const FilterOriginHitSet = class {
return [ FilterOriginHitSet.fid, domainOpt ];
}
static unitFromCompiled(args) {
return filterInstanceManager.unitFromArgs(args, args => {
const f = new FilterOriginHitSet(args[1]);
return filterUnits.push(f) - 1;
});
static fromCompiled(args) {
return new FilterOriginHitSet(args[1]);
}
static fromSelfie(args) {
return new FilterOriginHitSet(args[1], args[2]);
}
static keyFromArgs(args) {
return args[1];
}
};
registerFilterClass(FilterOriginHitSet);
@ -1440,16 +1421,17 @@ const FilterOriginMissSet = class {
return [ FilterOriginMissSet.fid, domainOpt ];
}
static unitFromCompiled(args) {
return filterInstanceManager.unitFromArgs(args, args => {
const f = new FilterOriginMissSet(args[1]);
return filterUnits.push(f) - 1;
});
static fromCompiled(args) {
return new FilterOriginMissSet(args[1]);
}
static fromSelfie(args) {
return new FilterOriginMissSet(args[1], args[2]);
}
static keyFromArgs(args) {
return args[1];
}
};
registerFilterClass(FilterOriginMissSet);
@ -1493,16 +1475,17 @@ const FilterDataHolder = class {
return [ FilterDataHolder.fid, details.dataType, details.data ];
}
static unitFromCompiled(args) {
return filterInstanceManager.unitFromArgs(args, args => {
const f = new FilterDataHolder(args[1], args[2]);
return filterUnits.push(f) - 1;
});
static fromCompiled(args) {
return new FilterDataHolder(args[1], args[2]);
}
static fromSelfie(args) {
return new FilterDataHolder(args[1], args[2]);
}
static keyFromArgs(args) {
return `${args[1]}\t${args[2]}`;
}
};
registerFilterClass(FilterDataHolder);
@ -1577,7 +1560,7 @@ const FilterCollection = class {
return [ ctor.fid, fdata ];
}
static unitFromCompiled(ctor, args) {
static fromCompiled(ctor, args) {
let iprev = 0, i0 = 0;
const n = args[1].length;
for ( let i = 0; i < n; i++ ) {
@ -1590,7 +1573,7 @@ const FilterCollection = class {
}
iprev = inext;
}
return filterUnits.push(new ctor(i0, args[1].length)) - 1;
return new ctor(i0, args[1].length);
}
static fromSelfie(ctor, args) {
@ -1652,8 +1635,8 @@ const FilterComposite = class extends FilterCollection {
return FilterCollection.compile(FilterComposite, fdata);
}
static unitFromCompiled(args) {
return FilterCollection.unitFromCompiled(FilterComposite, args);
static fromCompiled(args) {
return FilterCollection.fromCompiled(FilterComposite, args);
}
static fromSelfie(args) {
@ -1754,20 +1737,22 @@ const FilterDenyAllow = class {
return [ FilterDenyAllow.fid, details.denyallow ];
}
static unitFromCompiled(args) {
return filterInstanceManager.unitFromArgs(args, args => {
const f = new FilterDenyAllow(args[1]);
for ( const hn of args[1].split('|') ) {
if ( hn === '' ) { continue; }
f.hndict.add(hn);
}
return filterUnits.push(f) - 1;
});
static fromCompiled(args) {
const f = new FilterDenyAllow(args[1]);
for ( const hn of args[1].split('|') ) {
if ( hn === '' ) { continue; }
f.hndict.add(hn);
}
return f;
}
static fromSelfie(args) {
return new FilterDenyAllow(...args.slice(1));
}
static keyFromArgs(args) {
return args[1];
}
};
registerFilterClass(FilterDenyAllow);
@ -1808,9 +1793,8 @@ const FilterJustOrigin = class {
return [ this.fid, filterOrigin.trieContainer.compileOne(this.dict) ];
}
static unitFromCompiled(args) {
const f = new FilterJustOrigin(args[1]);
return filterUnits.push(f) - 1;
static fromCompiled(args) {
return new FilterJustOrigin(args[1]);
}
static fromSelfie(args) {
@ -1833,9 +1817,8 @@ const FilterHTTPSJustOrigin = class extends FilterJustOrigin {
details.domains.push(this.$h);
}
static unitFromCompiled(args) {
const f = new FilterHTTPSJustOrigin(args[1]);
return filterUnits.push(f) - 1;
static fromCompiled(args) {
return new FilterHTTPSJustOrigin(args[1]);
}
static fromSelfie(args) {
@ -1858,9 +1841,8 @@ const FilterHTTPJustOrigin = class extends FilterJustOrigin {
details.domains.push(this.$h);
}
static unitFromCompiled(args) {
const f = new FilterHTTPJustOrigin(args[1]);
return filterUnits.push(f) - 1;
static fromCompiled(args) {
return new FilterHTTPJustOrigin(args[1]);
}
static fromSelfie(args) {
@ -2740,7 +2722,7 @@ FilterContainer.prototype.reset = function() {
FilterHostnameDict.reset();
filterOrigin.reset();
bidiTrie.reset();
filterInstanceManager.reset();
filterArgsToUnit.clear();
filterUnits = filterUnits.slice(0, FILTER_UNITS_MIN);
filterSequenceWritePtr = FILTER_SEQUENCES_MIN;
@ -2863,7 +2845,7 @@ FilterContainer.prototype.freeze = function() {
FilterHostnameDict.optimize();
bidiTrieOptimize();
filterInstanceManager.reset();
filterArgsToUnit.clear();
log.info(`staticNetFilteringEngine.freeze() took ${Date.now()-t0} ms`);
};