mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-07 03:12:33 +01: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:
parent
71d2466eff
commit
634ffc9d14
@ -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,7 +1720,7 @@ 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 = queueTask(( ) => {
|
||||||
this.optimizeTaskId = undefined;
|
this.optimizeTaskId = undefined;
|
||||||
this.optimize();
|
this.optimize(10);
|
||||||
}, 2000);
|
}, 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 ) {
|
|
||||||
if ( throttle > 0 && (Date.now() - t0) > 48 ) {
|
|
||||||
return later(throttle);
|
|
||||||
}
|
|
||||||
const fc = filterGetClass(iunit);
|
const fc = filterGetClass(iunit);
|
||||||
if ( fc === FilterHostnameDict ) {
|
switch ( fc ) {
|
||||||
|
case FilterHostnameDict:
|
||||||
FilterHostnameDict.optimize(iunit);
|
FilterHostnameDict.optimize(iunit);
|
||||||
continue;
|
break;
|
||||||
}
|
case FilterBucket: {
|
||||||
if ( fc === FilterBucket ) {
|
|
||||||
const optimizeBits =
|
const optimizeBits =
|
||||||
(th === NO_TOKEN_HASH) || (bits & ModifyAction) !== 0
|
(tokenHash === NO_TOKEN_HASH) || (bits & ModifyAction) !== 0
|
||||||
? 0b10
|
? 0b10
|
||||||
: 0b01;
|
: 0b01;
|
||||||
const inewunit = FilterBucket.optimize(iunit, optimizeBits);
|
const inewunit = FilterBucket.optimize(iunit, optimizeBits);
|
||||||
if ( inewunit === 0 ) { continue; }
|
if ( inewunit !== 0 ) {
|
||||||
bucket.set(th, inewunit);
|
bucket.set(tokenHash, 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();
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user