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