gpt4 book ai didi

google-chrome - IndexedDB 删除的对象从未从 Chrome 上的磁盘中删除

转载 作者:搜寻专家 更新时间:2023-10-30 20:59:14 25 4
gpt4 key购买 nike

我正在尝试创建一个每秒接收产品的应用程序,并使用 LRU 策略更新固定大小(~ 300 MB)的数据库。虽然我在添加新产品和从数据库中删除它们方面没有异常(exception),但 Chrome 似乎永远不会删除 .ldb 和 .bak 文件。因此,我花费了几千兆字节的硬盘,而且我总是达到配额限制。相同的代码在 Firefox 上运行完美。有人可以解释我做错了什么吗?您可以在下面找到代码。

startExperiment(300 * 1024 * 1024);

function startExperiment(lrusize:number) {

var j = 0;

var productsToInsert = new HashMap<number, Product>();

window.indexedDB.deleteDatabase("ExampleDatabase");
var versionNumber = 1;
var stats = new Stats();
var sizeOfDatabase = 0;
var db = new ProductDatabase('ExampleDatabase', versionNumber, () => {
db.getSizeOfDatabase((result) => {
if(result == null) {
sizeOfDatabase = 0;
} else {
sizeOfDatabase = result;
}
});
});





function randomizeArray() {
var numOfMBS = Math.floor((Math.random() * (10 - 2) + 2) * 1024 * 1024);
var bytearray = new Uint8Array(numOfMBS.valueOf());
for (var i = 0; i < bytearray.length; i++) {
bytearray[i] = Math.random() * (100 - 1) + 1;
}
return bytearray;
}


setInterval(function () {
var readAverage = stats.getReadTimesAverage();
var writeAverage = stats.getWriteTimesAverage();
var deleteAverage = stats.getDeleteTimesAverage();

console.log("Num of insertions : " + j + " | Read average : " + readAverage + " | Write average : " + writeAverage + " | Delete average : " + deleteAverage);
}, 5000);

setInterval(function () {
var bytearray = randomizeArray();
var identifier = j++;
var timestamp = Date.now();
db.getProduct(identifier, (product) => {
if (product == null) {
var newProduct = new Product(identifier, timestamp, 0, bytearray);
var size = memorySizeOf(newProduct);
newProduct.sizeInBytes = size;
productsToInsert.set(identifier, newProduct);
}
});
}, 1000);


function updateLRU() {
var tmpList:Product[] = [];
var keys = productsToInsert.keys();
var currentBytesToBeInserted = 0;
for (var i = 0; i < keys.length; i++) {
var product = productsToInsert.get(keys[i]);
tmpList.push(product);
currentBytesToBeInserted += product.sizeInBytes;
}

var currentSize = sizeOfDatabase + currentBytesToBeInserted;
if (currentSize > lrusize) {
var bytesToRemove = currentSize - lrusize;
db.deleteProducts(bytesToRemove, stats, () => {
sizeOfDatabase -= bytesToRemove;
addFragments(tmpList);
});
} else {
addProducts(tmpList);
}
}


function addProducts(tmpList:Product[]) {

var product = tmpList[0];
var startAddProductTs = Date.now();
db.addProduct(product, () => {
var stopAddProductTs = Date.now();
stats.addWriteTimes(stopAddProductTs - startAddProductTs);
sizeOfDatabase += product.sizeInBytes;
tmpList.shift();
productsToInsert.delete(product.productId);
if(tmpList.length > 0) {
addProducts(tmpList);
} else {
db.addDBSize(sizeOfDatabase, () => {

});
}
});
}

setInterval(function () {

updateLRU();

}, 20000);


}





class ProductDatabase {

private db;

constructor(private name:string, private version:number, callback:() => void) {
this.openDatabase(callback);

}


openDatabase(callback:() => void) {
var openDatabaseRequest = window.indexedDB.open(this.name, this.version);
openDatabaseRequest.onupgradeneeded = this.upgrade;
openDatabaseRequest.onsuccess = () => {
this.db = openDatabaseRequest.result;
callback();
}

}

upgrade(event:any) {
var store = event.target.result.createObjectStore("products", {keyPath: 'productId'});
store.createIndex('by_timestamp', "timestamp", {unique: true});
event.target.result.createObjectStore("dbsize", {keyPath: 'sizeId'});
}


getProduct(productId:number, callback:(result:Product) => void) {


var productStore = this.db.transaction(["products"], "readonly").objectStore('products');

var query = productStore.get(productId);

query.onsuccess = () => {
var product = query.result;
callback(product);
}

query.onerror = () => {
console.error("Read product error : " + query.error);
}


}


addDBSize(dbSize:number, callback:() => void) {


var transaction = this.db.transaction('dbsize', 'readwrite');
var productStore = transaction.objectStore('dbsize');
var newSize = {'sizeId': 1, 'bytelength': dbSize};
var request = productStore.put(newSize);


request.onerror = () => {
console.log("Unsuccessful request with error : " + request.error);

}


transaction.oncomplete = () => {
callback();
}

transaction.onerror = () => {
console.error("fucking error : " + transaction.error);

}


transaction.onabort = () => {
console.error("Shit. transaction is aborted with error : " + transaction.error);

}


}

addCachedProducts(productList:Array<Product>, callback:() => void) {


var transaction = this.db.transaction('products', 'readwrite');
var productStore = transaction.objectStore('products');
for (var i = 0; i < productList.length; i++) {
productStore.add(productList[i]);
}

transaction.oncomplete = () => {
callback();
}

transaction.onabort = () => {
console.error("Shit. transaction is aborted with error : " + transaction.error);
}

}

getNumberOfProducts(callback:(result:number) => void) {

var productStore = this.db.transaction('products', 'readonly').objectStore('products');
var query = productStore.count();
query.onsuccess = () => {
var result = query.result;
callback(result);
}

query.onerror = () => {
console.error("Read number of products error : " + query.error);
}

}

getSizeOfDatabase(callback:(result:number) => void) {

var productStore = this.db.transaction('dbsize', "readonly").objectStore('dbsize');

var query = productStore.get(1);

query.onsuccess = () => {
var product = query.result;
callback(product);
}

query.onerror = () => {
console.error("Read databasesize error : " + query.error);
}

}

deleteProducts(numOfBytes:number, stats:Stats, callback:() => void) {


var transaction = this.db.transaction('products', 'readwrite');
var productStore = transaction.objectStore('products');
var index = productStore.index('by_timestamp');

var request = index.openCursor();
request.onsuccess = function () {
var cursor = request.result;
if (cursor) {
var cursorBytes = cursor.value.sizeInBytes;
var startDeleteTs = Date.now();
var deleteRequest = cursor.delete();
deleteRequest.onsuccess = () => {
var stopDeleteTs = Date.now();
stats.addDeleteTimes(stopDeleteTs - startDeleteTs);
numOfBytes -= cursorBytes;
if (numOfBytes > 0) {
cursor.continue();
}
}

deleteRequest.onerror = () => {
console.error("Delete product error : " + deleteRequest.error);
}
}

}


transaction.oncomplete = () => {
callback();
}

transaction.onabort = () => {
console.log("Delete transaction aborted with error : " + transaction.error);
}

}


addProduct(product:Product, callback:() => void) {


var transaction = this.db.transaction('products', 'readwrite');
var productStore = transaction.objectStore('products');
var request = productStore.put(product);


request.onerror = () => {
console.log("Unsuccessful request with error : " + request.error);
}


transaction.oncomplete = () => {
callback();
}

transaction.onerror = () => {
console.error("fucking error : " + transaction.error);
}


transaction.onabort = () => {
console.error("Shit. transaction is aborted with error : " + transaction.error);
}



}

}

最佳答案

在 Chrome 中,通过 IndexedDB API 删除数据和从磁盘中删除数据之间存在延迟。通常这很好。但根据我的经验,sometimes it never gets deleted from disk, which is really bad when the user has exceeded their quota because then you can never store any more data even if you delete everything .

关于google-chrome - IndexedDB 删除的对象从未从 Chrome 上的磁盘中删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36411740/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com