Leverage compile-time token information in new fitler classes

Related commit:
- 99390390fc

The token information available at compile time can be stored
in the filter to be used at match() time. This allows the use of
startsWith() rather than a more costly indexOf() call as a first
quick test to detect mismatches.
This commit is contained in:
Raymond Hill 2019-04-26 11:16:47 -04:00
parent 1f8f616faf
commit 19ece97b0c
No known key found for this signature in database
GPG key ID: 25E1490B761470C2
2 changed files with 76 additions and 27 deletions

View file

@ -137,7 +137,7 @@ const µBlock = (function() { // jshint ignore:line
// Read-only // Read-only
systemSettings: { systemSettings: {
compiledMagic: 11, // Increase when compiled format changes compiledMagic: 12, // Increase when compiled format changes
selfieMagic: 11 // Increase when selfie format changes selfieMagic: 11 // Increase when selfie format changes
}, },

View file

@ -553,14 +553,23 @@ registerFilterClass(FilterPlainHnAnchored);
*/ */
const FilterWildcard1 = class { const FilterWildcard1 = class {
constructor(s0, s1) { constructor(s0, s1, tokenBeg) {
this.s0 = s0; this.s0 = s0;
this.s1 = s1; this.s1 = s1;
this.tokenBeg = tokenBeg;
} }
match(url) { match(url, tokenBeg) {
const pos = url.indexOf(this.s0); if ( this.tokenBeg >= 0 ) {
return pos !== -1 && url.indexOf(this.s1, pos + this.s0.length) !== -1; const s0Beg = tokenBeg - this.tokenBeg;
return s0Beg >= 0 &&
url.startsWith(this.s0, s0Beg) &&
url.indexOf(this.s1, s0Beg + this.s0.length) !== -1;
}
const s1Beg = tokenBeg + this.tokenBeg;
return s1Beg > 0 &&
url.startsWith(this.s1, s1Beg) &&
url.lastIndexOf(this.s0, s1Beg) !== -1;
} }
logData() { logData() {
@ -572,21 +581,29 @@ const FilterWildcard1 = class {
} }
compile() { compile() {
return [ this.fid, this.s0, this.s1 ]; return [ this.fid, this.s0, this.s1, this.tokenBeg ];
} }
static compile(details) { static compile(details) {
if ( this.token === '*' ) { return; }
if ( details.anchor !== 0 ) { return; } if ( details.anchor !== 0 ) { return; }
const s = details.f; const s = details.f;
let pos = s.indexOf('*'); let pos = s.indexOf('*');
if ( pos === -1 ) { return; } if ( pos === -1 ) { return; }
if ( reIsWildcarded.test(s.slice(pos + 1)) ) { return; } if ( reIsWildcarded.test(s.slice(pos + 1)) ) { return; }
if ( reIsWildcarded.test(s.slice(0, pos)) ) { return; } if ( reIsWildcarded.test(s.slice(0, pos)) ) { return; }
return [ FilterWildcard1.fid, s.slice(0, pos), s.slice(pos + 1) ]; return [
FilterWildcard1.fid,
s.slice(0, pos),
s.slice(pos + 1),
details.tokenBeg < pos
? details.tokenBeg
: pos + 1 - details.tokenBeg,
];
} }
static load(args) { static load(args) {
return new FilterWildcard1(args[1], args[2]); return new FilterWildcard1(args[1], args[2], args[3]);
} }
}; };
@ -648,16 +665,26 @@ registerFilterClass(FilterGeneric);
*/ */
const FilterWildcard1HnAnchored = class { const FilterWildcard1HnAnchored = class {
constructor(s0, s1) { constructor(s0, s1, tokenBeg) {
this.s0 = s0; this.s0 = s0;
this.s1 = s1; this.s1 = s1;
this.tokenBeg = tokenBeg;
} }
match(url) { match(url, tokenBeg) {
const pos = url.indexOf(this.s0); if ( this.tokenBeg >= 0 ) {
return pos !== -1 && const s0Beg = tokenBeg - this.tokenBeg;
isHnAnchored(url, pos) && return s0Beg >= 0 &&
url.indexOf(this.s1, pos + this.s0.length) !== -1; url.startsWith(this.s0, s0Beg) &&
isHnAnchored(url, s0Beg) &&
url.indexOf(this.s1, s0Beg + this.s0.length) !== -1;
}
const s1Beg = tokenBeg + this.tokenBeg;
if ( s1Beg < 0 || url.startsWith(this.s1, s1Beg) === false ) {
return false;
}
const s0Beg = url.lastIndexOf(this.s0, s1Beg);
return s0Beg !== -1 && isHnAnchored(url, s0Beg);
} }
logData() { logData() {
@ -669,10 +696,11 @@ const FilterWildcard1HnAnchored = class {
} }
compile() { compile() {
return [ this.fid, this.s0, this.s1 ]; return [ this.fid, this.s0, this.s1, this.tokenBeg ];
} }
static compile(details) { static compile(details) {
if ( this.token === '*' ) { return; }
if ( (details.anchor & 0x0b001) !== 0 ) { return; } if ( (details.anchor & 0x0b001) !== 0 ) { return; }
const s = details.f; const s = details.f;
let pos = s.indexOf('*'); let pos = s.indexOf('*');
@ -689,11 +717,14 @@ const FilterWildcard1HnAnchored = class {
FilterWildcard1HnAnchored.fid, FilterWildcard1HnAnchored.fid,
s.slice(0, pos), s.slice(0, pos),
s.slice(pos + 1), s.slice(pos + 1),
details.tokenBeg < pos
? details.tokenBeg
: pos + 1 - details.tokenBeg,
]; ];
} }
static load(args) { static load(args) {
return new FilterWildcard1HnAnchored(args[1], args[2]); return new FilterWildcard1HnAnchored(args[1], args[2], args[3]);
} }
}; };
@ -707,20 +738,35 @@ registerFilterClass(FilterWildcard1HnAnchored);
*/ */
const FilterWildcard2HnAnchored = class { const FilterWildcard2HnAnchored = class {
constructor(s0, s1) { constructor(s0, s1, tokenBeg) {
this.s0 = s0; this.s0 = s0;
this.s1 = s1; this.s1 = s1;
this.tokenBeg = tokenBeg;
} }
match(url) { match(url, tokenBeg) {
const pos0 = url.indexOf(this.s0); let s0End, s1Beg;
if ( pos0 === -1 || isHnAnchored(url, pos0) === false ) { if ( this.tokenBeg >= 0 ) {
return false; const s0Beg = tokenBeg - this.tokenBeg;
if ( s0Beg < 0 || url.startsWith(this.s0, s0Beg) === false ) {
return false;
}
if ( isHnAnchored(url, s0Beg) === false ) { return false; }
s0End = s0Beg + this.s0.length;
s1Beg = url.indexOf(this.s1, s0End);
if ( s1Beg === -1 ) { return false; }
} else {
s1Beg = tokenBeg + this.tokenBeg;
if ( s1Beg < 0 || url.startsWith(this.s1, s1Beg) === false ) {
return false;
}
const s0Beg = url.lastIndexOf(this.s0, s1Beg);
if ( s0Beg === -1 || isHnAnchored(url, s0Beg) === false ) {
return false;
}
s0End = s0Beg + this.s0.length;
} }
const pos1 = pos0 + this.s0.length; return this.reSeparators.test(url.slice(s0End, s1Beg));
const pos2 = url.indexOf(this.s1, pos1);
return pos2 !== -1 &&
this.reSeparators.test(url.slice(pos1, pos2));
} }
logData() { logData() {
@ -732,7 +778,7 @@ const FilterWildcard2HnAnchored = class {
} }
compile() { compile() {
return [ this.fid, this.s0, this.s1 ]; return [ this.fid, this.s0, this.s1, this.tokenBeg ];
} }
static compile(details, pos) { static compile(details, pos) {
@ -740,11 +786,14 @@ const FilterWildcard2HnAnchored = class {
FilterWildcard2HnAnchored.fid, FilterWildcard2HnAnchored.fid,
details.f.slice(0, pos), details.f.slice(0, pos),
details.f.slice(pos + 2), details.f.slice(pos + 2),
details.tokenBeg < pos
? details.tokenBeg
: pos + 2 - details.tokenBeg,
]; ];
} }
static load(args) { static load(args) {
return new FilterWildcard2HnAnchored(args[1], args[2]); return new FilterWildcard2HnAnchored(args[1], args[2], args[3]);
} }
}; };