1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-09-15 07:22:28 +02:00

Fix throttling of optimization cycles

This should help lower time-to-readiness when uBO
is launched on less powerful devices.
This commit is contained in:
Raymond Hill 2021-12-05 09:07:02 -05:00
parent 71d2466eff
commit 634ffc9d14
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2

View File

@ -359,15 +359,28 @@ const isSeparatorChar = c => (charClassMap[c] & CHAR_CLASS_SEPARATOR) !== 0;
const FILTER_DATA_PAGE_SIZE = 65536; const FILTER_DATA_PAGE_SIZE = 65536;
const roundToFilterDataPageSize =
len => (len + FILTER_DATA_PAGE_SIZE-1) & ~(FILTER_DATA_PAGE_SIZE-1);
let filterData = new Int32Array(FILTER_DATA_PAGE_SIZE * 5); let filterData = new Int32Array(FILTER_DATA_PAGE_SIZE * 5);
let filterDataWritePtr = 2; let filterDataWritePtr = 2;
function filterDataGrow(len) { function filterDataGrow(len) {
if ( len <= filterData.length ) { return; } if ( len <= filterData.length ) { return; }
const newLen = (len + FILTER_DATA_PAGE_SIZE-1) & ~(FILTER_DATA_PAGE_SIZE-1); const newLen = roundToFilterDataPageSize(len);
const newBuf = new Int32Array(newLen); const newBuf = new Int32Array(newLen);
newBuf.set(filterData); newBuf.set(filterData);
filterData = newBuf; filterData = newBuf;
} }
function filterDataShrink() {
const newLen = Math.max(
roundToFilterDataPageSize(filterDataWritePtr),
FILTER_DATA_PAGE_SIZE
);
if ( newLen >= filterData.length ) { return; }
const newBuf = new Int32Array(newLen);
newBuf.set(filterData.subarray(0, filterDataWritePtr));
filterData = newBuf;
}
function filterDataAlloc(...args) { function filterDataAlloc(...args) {
const len = args.length; const len = args.length;
const idata = filterDataAllocLen(len); const idata = filterDataAllocLen(len);
@ -404,6 +417,7 @@ function filterDataFromSelfie(selfie) {
filterDataGrow(data.length); filterDataGrow(data.length);
filterDataWritePtr = data.length; filterDataWritePtr = data.length;
filterData.set(data); filterData.set(data);
filterDataShrink();
return true; return true;
} }
@ -1706,9 +1720,9 @@ const FilterOriginHitSetTest = class extends FilterOriginHitSet {
static create(domainOpt) { static create(domainOpt) {
const idata = filterDataAllocLen(4); const idata = filterDataAllocLen(4);
filterData[idata+0] = FilterOriginHitSetTest.fid; filterData[idata+0] = FilterOriginHitSetTest.fid;
filterData[idata+1] = super.create(domainOpt); // ihitset filterData[idata+1] = FilterOriginHitSet.create(domainOpt); // ihitset
filterData[idata+2] = domainOpt.includes('.*') ? 1 : 0; // hasEntity filterData[idata+2] = domainOpt.includes('.*') ? 1 : 0; // hasEntity
filterData[idata+3] = 0; // $lastResult filterData[idata+3] = 0; // $lastResult
return idata; return idata;
} }
}; };
@ -3538,6 +3552,9 @@ const FilterContainer = function() {
// becomes too large, we can just go back to using a Map. // becomes too large, we can just go back to using a Map.
this.bitsToBucketIndices = JSON.parse(`[${'0,'.repeat(CategoryCount-1)}0]`); this.bitsToBucketIndices = JSON.parse(`[${'0,'.repeat(CategoryCount-1)}0]`);
this.buckets = [ new Map() ]; this.buckets = [ new Map() ];
this.goodFilters = new Set();
this.badFilters = new Set();
this.unitsToOptimize = [];
this.reset(); this.reset();
}; };
@ -3567,11 +3584,11 @@ FilterContainer.prototype.reset = function() {
this.allowFilterCount = 0; this.allowFilterCount = 0;
this.blockFilterCount = 0; this.blockFilterCount = 0;
this.discardedCount = 0; this.discardedCount = 0;
this.goodFilters = new Set(); this.goodFilters.clear();
this.badFilters = new Set(); this.badFilters.clear();
this.unitsToOptimize.length = 0;
this.bitsToBucketIndices.fill(0); this.bitsToBucketIndices.fill(0);
this.buckets.length = 1; this.buckets.length = 1;
this.optimized = false;
urlTokenizer.resetKnownTokens(); urlTokenizer.resetKnownTokens();
@ -3625,6 +3642,7 @@ FilterContainer.prototype.freeze = function() {
if ( iunit === 0 ) { if ( iunit === 0 ) {
iunit = FilterHostnameDict.create(); iunit = FilterHostnameDict.create();
bucket.set(DOT_TOKEN_HASH, iunit); bucket.set(DOT_TOKEN_HASH, iunit);
this.unitsToOptimize.push({ bits, tokenHash });
} }
FilterHostnameDict.add(iunit, fdata); FilterHostnameDict.add(iunit, fdata);
continue; continue;
@ -3673,6 +3691,7 @@ FilterContainer.prototype.freeze = function() {
FilterBucket.unshift(ibucketunit, iunit); FilterBucket.unshift(ibucketunit, iunit);
FilterBucket.unshift(ibucketunit, inewunit); FilterBucket.unshift(ibucketunit, inewunit);
bucket.set(tokenHash, ibucketunit); bucket.set(tokenHash, ibucketunit);
this.unitsToOptimize.push({ bits, tokenHash });
} }
this.badFilters.clear(); this.badFilters.clear();
@ -3682,12 +3701,12 @@ FilterContainer.prototype.freeze = function() {
// Optimizing is not critical for the static network filtering engine to // Optimizing is not critical for the static network filtering engine to
// work properly, so defer this until later to allow for reduced delay to // work properly, so defer this until later to allow for reduced delay to
// readiness when no valid selfie is available. // readiness when no valid selfie is available.
if ( this.optimized !== true && this.optimizeTaskId === undefined ) { if ( this.optimizeTaskId !== undefined ) { return; }
this.optimizeTaskId = queueTask(( ) => {
this.optimizeTaskId = undefined; this.optimizeTaskId = queueTask(( ) => {
this.optimize(); this.optimizeTaskId = undefined;
}, 2000); this.optimize(10);
} }, 2000);
}; };
/******************************************************************************/ /******************************************************************************/
@ -3698,43 +3717,41 @@ FilterContainer.prototype.optimize = function(throttle = 0) {
this.optimizeTaskId = undefined; this.optimizeTaskId = undefined;
} }
// This will prevent pointless optimize cycles when incrementally adding
// filters.
this.optimized = true;
//this.filterClassHistogram(); //this.filterClassHistogram();
const later = throttle => { const later = throttle => {
this.optimizeTaskId = queueTask(( ) => { this.optimizeTaskId = queueTask(( ) => {
this.optimizeTaskId = undefined; this.optimizeTaskId = undefined;
this.optimize(throttle - 1); this.optimize(throttle);
}, 1000); }, 1000);
}; };
const t0 = Date.now(); const t0 = Date.now();
for ( let bits = 0; bits < this.bitsToBucketIndices.length; bits++ ) { while ( this.unitsToOptimize.length !== 0 ) {
const ibucket = this.bitsToBucketIndices[bits]; const { bits, tokenHash } = this.unitsToOptimize.pop();
if ( ibucket === 0 ) { continue; } const bucket = this.buckets[this.bitsToBucketIndices[bits]];
const bucket = this.buckets[ibucket]; const iunit = bucket.get(tokenHash);
for ( const [ th, iunit ] of bucket ) { const fc = filterGetClass(iunit);
if ( throttle > 0 && (Date.now() - t0) > 48 ) { switch ( fc ) {
return later(throttle); case FilterHostnameDict:
} FilterHostnameDict.optimize(iunit);
const fc = filterGetClass(iunit); break;
if ( fc === FilterHostnameDict ) { case FilterBucket: {
FilterHostnameDict.optimize(iunit); const optimizeBits =
continue; (tokenHash === NO_TOKEN_HASH) || (bits & ModifyAction) !== 0
} ? 0b10
if ( fc === FilterBucket ) { : 0b01;
const optimizeBits = const inewunit = FilterBucket.optimize(iunit, optimizeBits);
(th === NO_TOKEN_HASH) || (bits & ModifyAction) !== 0 if ( inewunit !== 0 ) {
? 0b10 bucket.set(tokenHash, inewunit);
: 0b01;
const inewunit = FilterBucket.optimize(iunit, optimizeBits);
if ( inewunit === 0 ) { continue; }
bucket.set(th, inewunit);
continue;
} }
break;
}
default:
break;
}
if ( throttle > 0 && (Date.now() - t0) > 48 ) {
return later(throttle - 1);
} }
} }
@ -3745,6 +3762,7 @@ FilterContainer.prototype.optimize = function(throttle = 0) {
destHNTrieContainer.optimize() destHNTrieContainer.optimize()
); );
bidiTrieOptimize(); bidiTrieOptimize();
filterDataShrink();
//this.filterClassHistogram(); //this.filterClassHistogram();
}; };