Raymond Hill 2018-12-05 19:18:20 -05:00
parent 0d6a18207a
commit e7d4aff2a2
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
4 changed files with 110 additions and 36 deletions

View File

@ -40,19 +40,28 @@
µBlock.cacheStorage = (function() {
// Firefox-specific: we use indexedDB because chrome.storage.local() has
// poor performance in Firefox. See:
const STORAGE_NAME = 'uBlock0CacheStorage';
// https://bugzilla.mozilla.org/show_bug.cgi?id=1371255
if ( vAPI.webextFlavor.soup.has('firefox') === false ) {
// Firefox-specific: we use indexedDB because chrome.storage.local() has
// poor performance in Firefox.
// https://github.com/uBlockOrigin/uBlock-issues/issues/328
// Use IndexedDB for Chromium as well, to take advantage of LZ4
// compression.
if (
vAPI.webextFlavor.soup.has('firefox') === false &&
vAPI.webextFlavor.soup.has('chromium') === false
) {
// In case IndexedDB was used as cache storage, remove it.
indexedDB.deleteDatabase(STORAGE_NAME);
return vAPI.cacheStorage;
}
const STORAGE_NAME = 'uBlock0CacheStorage';
let db;
let pendingInitialization;
let dbByteLength;
let get = function get(input, callback) {
const get = function get(input, callback) {
if ( typeof callback !== 'function' ) { return; }
if ( input === null ) {
return getAllFromDb(callback);
@ -69,23 +78,23 @@
return getFromDb(toRead, output, callback);
};
let set = function set(input, callback) {
const set = function set(input, callback) {
putToDb(input, callback);
};
let remove = function remove(key, callback) {
const remove = function remove(key, callback) {
deleteFromDb(key, callback);
};
let clear = function clear(callback) {
const clear = function clear(callback) {
clearDb(callback);
};
let getBytesInUse = function getBytesInUse(keys, callback) {
const getBytesInUse = function getBytesInUse(keys, callback) {
getDbSize(callback);
};
let api = {
const api = {
get,
set,
remove,
@ -94,7 +103,7 @@
error: undefined
};
let genericErrorHandler = function(ev) {
const genericErrorHandler = function(ev) {
let error = ev.target && ev.target.error;
if ( error && error.name === 'QuotaExceededError' ) {
api.error = error.name;
@ -102,10 +111,10 @@
console.error('[%s]', STORAGE_NAME, error && error.name);
};
function noopfn() {
}
const noopfn = function () {
};
let getDb = function getDb() {
const getDb = function getDb() {
if ( db instanceof IDBDatabase ) {
return Promise.resolve(db);
}
@ -165,7 +174,7 @@
return pendingInitialization;
};
let getFromDb = function(keys, keyvalStore, callback) {
const getFromDb = function(keys, keyvalStore, callback) {
if ( typeof callback !== 'function' ) { return; }
if ( keys.length === 0 ) { return callback(keyvalStore); }
let promises = [];
@ -202,7 +211,7 @@
});
};
let visitAllFromDb = function(visitFn) {
const visitAllFromDb = function(visitFn) {
getDb().then(( ) => {
if ( !db ) { return visitFn(); }
let transaction = db.transaction(STORAGE_NAME);
@ -221,7 +230,7 @@
});
};
let getAllFromDb = function(callback) {
const getAllFromDb = function(callback) {
if ( typeof callback !== 'function' ) { return; }
let promises = [];
let keyvalStore = {};
@ -245,7 +254,7 @@
});
};
let getDbSize = function(callback) {
const getDbSize = function(callback) {
if ( typeof callback !== 'function' ) { return; }
if ( typeof dbByteLength === 'number' ) {
return Promise.resolve().then(( ) => {
@ -280,7 +289,7 @@
// https://developer.mozilla.org/en-US/docs/Web/API/IDBDatabase/transaction
// https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/put
let putToDb = function(keyvalStore, callback) {
const putToDb = function(keyvalStore, callback) {
if ( typeof callback !== 'function' ) {
callback = noopfn;
}
@ -326,7 +335,7 @@
});
};
let deleteFromDb = function(input, callback) {
const deleteFromDb = function(input, callback) {
if ( typeof callback !== 'function' ) {
callback = noopfn;
}
@ -356,7 +365,7 @@
});
};
let clearDb = function(callback) {
const clearDb = function(callback) {
if ( typeof callback !== 'function' ) {
callback = noopfn;
}
@ -383,6 +392,57 @@
// prime the db so that it's ready asap for next access.
getDb(noopfn);
// https://github.com/uBlockOrigin/uBlock-issues/issues/328
// Detect whether browser.storage.local was used as cache storage,
// and if so, move cache-related entries to the new storage.
{
const srcStorage = vAPI.cacheStorage;
const desStorage = api;
srcStorage.get(
[ 'assetCacheRegistry', 'assetSourceRegistry' ],
bin => {
if (
bin instanceof Object === false ||
bin.assetSourceRegistry instanceof Object === false
) {
return;
}
desStorage.set(bin);
const toRemove = [
'assetCacheRegistry',
'assetSourceRegistry',
'resourcesSelfie',
'selfie'
];
let toMigrate = 0;
const setEntry = function(assetKey, bin) {
if (
bin instanceof Object &&
bin[assetKey] !== undefined
) {
desStorage.set(bin);
}
toMigrate -= 1;
if ( toMigrate === 0 ) {
srcStorage.remove(toRemove);
}
};
for ( const key in bin.assetCacheRegistry ) {
if ( bin.assetCacheRegistry.hasOwnProperty(key) === false ) {
continue;
}
const assetKey = 'cache/' + key;
srcStorage.get(assetKey, setEntry.bind(null, assetKey));
toMigrate += 1;
toRemove.push(assetKey);
}
if ( toMigrate === 0 ) {
srcStorage.remove(toRemove);
}
}
);
}
return api;
}());

View File

@ -198,7 +198,11 @@ return {
data: decodeValue(result.key, result.data) || result.data
};
});
}
},
relinquish: function() {
ttlDelay = 1;
ttlManage(0);
},
};
/******************************************************************************/

View File

@ -53,6 +53,13 @@ vAPI.app.onShutdown = function() {
// - Schedule next update operation.
var onAllReady = function() {
// Ensure that the resources allocated for decompression purpose (likely
// large buffers) are garbage-collectable immediately after launch.
// Otherwise I have observed that it may take quite a while before the
// garbage collection of these resources kicks in. Relinquishing as soon
// as possible ensure minimal memory usage baseline.
µb.lz4Codec.relinquish();
µb.webRequest.start();
initializeTabs();

View File

@ -608,15 +608,15 @@
if ( this.loadingFilterLists ) { return; }
this.loadingFilterLists = true;
var µb = this,
filterlistsCount = 0,
loadedListKeys = [];
const µb = µBlock;
const loadedListKeys = [];
let filterlistsCount = 0;
if ( typeof callback !== 'function' ) {
callback = this.noopFunc;
}
var onDone = function() {
const onDone = function() {
µb.staticNetFilteringEngine.freeze();
µb.staticExtFilteringEngine.freeze();
µb.redirectEngine.freeze();
@ -632,17 +632,19 @@
callback();
µb.selfieManager.destroy();
µb.lz4Codec.relinquish();
µb.loadingFilterLists = false;
};
var applyCompiledFilters = function(assetKey, compiled) {
var snfe = µb.staticNetFilteringEngine,
sxfe = µb.staticExtFilteringEngine,
acceptedCount = snfe.acceptedCount + sxfe.acceptedCount,
const applyCompiledFilters = function(assetKey, compiled) {
const snfe = µb.staticNetFilteringEngine;
const sxfe = µb.staticExtFilteringEngine;
let acceptedCount = snfe.acceptedCount + sxfe.acceptedCount,
discardedCount = snfe.discardedCount + sxfe.discardedCount;
µb.applyCompiledFilters(compiled, assetKey === µb.userFiltersPath);
if ( µb.availableFilterLists.hasOwnProperty(assetKey) ) {
var entry = µb.availableFilterLists[assetKey];
const entry = µb.availableFilterLists[assetKey];
entry.entryCount = snfe.acceptedCount + sxfe.acceptedCount -
acceptedCount;
entry.entryUsedCount = entry.entryCount -
@ -651,7 +653,7 @@
loadedListKeys.push(assetKey);
};
var onCompiledListLoaded = function(details) {
const onCompiledListLoaded = function(details) {
applyCompiledFilters(details.assetKey, details.content);
filterlistsCount -= 1;
if ( filterlistsCount === 0 ) {
@ -659,7 +661,7 @@
}
};
var onFilterListsReady = function(lists) {
const onFilterListsReady = function(lists) {
µb.availableFilterLists = lists;
µb.redirectEngine.reset();
@ -672,8 +674,8 @@
// because it *may* happens that some load operations are synchronous:
// This happens for assets which do not exist, ot assets with no
// content.
var toLoad = [];
for ( var assetKey in lists ) {
const toLoad = [];
for ( const assetKey in lists ) {
if ( lists.hasOwnProperty(assetKey) === false ) { continue; }
if ( lists[assetKey].off ) { continue; }
toLoad.push(assetKey);
@ -683,7 +685,7 @@
return onDone();
}
var i = toLoad.length;
let i = toLoad.length;
while ( i-- ) {
µb.getCompiledFilterList(toLoad[i], onCompiledListLoaded);
}
@ -1021,6 +1023,7 @@
staticExtFilteringEngine: µb.staticExtFilteringEngine.toSelfie()
});
µb.cacheStorage.set({ selfie: selfie });
µb.lz4Codec.relinquish();
};
let load = function(callback) {