mirror of
https://github.com/EmulatorJS/EmulatorJS.git
synced 2026-02-06 11:17:36 +00:00
Refactor EJS_Cache to store all cache data in a single database, but seperate tables for metadata and blobs
This commit is contained in:
parent
cdbb6a2f8d
commit
56bb0035f5
@ -6,15 +6,13 @@ class EJS_Cache {
|
||||
/**
|
||||
* Creates an instance of EJS_Cache.
|
||||
* @param {boolean} enabled - Whether caching is enabled.
|
||||
* @param {EJS_STORAGE} storage - Instance of EJS_STORAGE for IndexedDB operations.
|
||||
* @param {EJS_STORAGE} blobStorage - Instance of EJS_STORAGE for storing blob data.
|
||||
* @param {string} databaseName - Name of the IndexedDB database to use for caching.
|
||||
* @param {number} maxSizeMB - Maximum size of the cache in megabytes.
|
||||
* @param {number} maxAgeMins - Maximum age of items (in minutes) before they are cleaned up.
|
||||
*/
|
||||
constructor(enabled = true, storage, blobStorage, maxSizeMB = 4096, maxAgeMins = 7200, debug = false) {
|
||||
constructor(enabled = true, databaseName, maxSizeMB = 4096, maxAgeMins = 7200, debug = false) {
|
||||
this.enabled = enabled;
|
||||
this.storage = storage;
|
||||
this.blobStorage = blobStorage;
|
||||
this.databaseName = databaseName;
|
||||
this.maxSizeMB = maxSizeMB;
|
||||
this.maxAgeMins = maxAgeMins;
|
||||
this.minAgeMins = Math.max(60, maxAgeMins * 0.1); // Minimum 1 hour, or 10% of max age
|
||||
@ -25,9 +23,7 @@ class EJS_Cache {
|
||||
if (this.debug) {
|
||||
console.log("Initialized EJS_Cache with settings:", {
|
||||
enabled: this.enabled,
|
||||
storage: this.storage,
|
||||
blobStorage: this.blobStorage,
|
||||
enabledValue: this.enabled,
|
||||
databaseName: this.databaseName,
|
||||
maxSizeMB: this.maxSizeMB,
|
||||
maxAgeMins: this.maxAgeMins,
|
||||
minAgeMins: this.minAgeMins
|
||||
@ -35,6 +31,38 @@ class EJS_Cache {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the IndexedDB database and object stores.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async #createCacheDatabase() {
|
||||
if (!this.enabled) return;
|
||||
|
||||
if (this.storage && this.blobStorage) return;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = window.indexedDB.open(this.databaseName, 1);
|
||||
|
||||
request.onupgradeneeded = (event) => {
|
||||
const db = event.target.result;
|
||||
// Create object stores
|
||||
db.createObjectStore("cache");
|
||||
db.createObjectStore("blobs");
|
||||
};
|
||||
|
||||
request.onsuccess = (event) => {
|
||||
this.storage = new EJS_STORAGE(this.databaseName, "cache");
|
||||
this.blobStorage = new EJS_STORAGE(this.databaseName, "blobs");
|
||||
resolve();
|
||||
};
|
||||
|
||||
request.onerror = (event) => {
|
||||
console.error("Error creating cache database:", event);
|
||||
reject(event);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the startup cleanup has been completed.
|
||||
*/
|
||||
@ -60,6 +88,9 @@ class EJS_Cache {
|
||||
async get(key, metadataOnly = false) {
|
||||
if (!this.enabled) return null;
|
||||
|
||||
// ensure database is created
|
||||
await this.#createCacheDatabase();
|
||||
|
||||
// clean up cache on first get if not already done
|
||||
if (!this.#startupCleanupCompleted) {
|
||||
await this.cleanup();
|
||||
@ -88,6 +119,9 @@ class EJS_Cache {
|
||||
async put(item) {
|
||||
if (!this.enabled) return;
|
||||
|
||||
// ensure database is created
|
||||
await this.#createCacheDatabase();
|
||||
|
||||
// before putting, ensure item is of type EJS_CacheItem
|
||||
if (!(item instanceof EJS_CacheItem)) {
|
||||
throw new Error("Item must be an instance of EJS_CacheItem");
|
||||
@ -146,6 +180,9 @@ class EJS_Cache {
|
||||
* @param {string} key - The unique key identifying the cached item to delete.
|
||||
*/
|
||||
async delete(key) {
|
||||
// ensure database is created
|
||||
await this.#createCacheDatabase();
|
||||
|
||||
// fail silently if the key does not exist
|
||||
try {
|
||||
await this.storage.remove(key);
|
||||
@ -159,6 +196,9 @@ class EJS_Cache {
|
||||
* Clears all items from the cache.
|
||||
*/
|
||||
async clear() {
|
||||
// ensure database is created
|
||||
await this.#createCacheDatabase();
|
||||
|
||||
const allItems = await this.storage.getAll();
|
||||
for (let i = 0; i < allItems.length; i++) {
|
||||
await this.delete(allItems[i].key);
|
||||
@ -171,6 +211,9 @@ class EJS_Cache {
|
||||
async cleanup() {
|
||||
if (!this.enabled) return;
|
||||
|
||||
// ensure database is created
|
||||
await this.#createCacheDatabase();
|
||||
|
||||
if (this.debug) console.log("[EJS Cache] Starting cache cleanup...");
|
||||
const cleanupStartTime = performance.now();
|
||||
|
||||
|
||||
@ -353,8 +353,7 @@ class EmulatorJS {
|
||||
|
||||
this.storageCache = new window.EJS_Cache(
|
||||
this.config.cacheConfig.enabled,
|
||||
new window.EJS_STORAGE("EmulatorJS-cache", "cache"),
|
||||
new window.EJS_STORAGE("EmulatorJS-cacheBlobs", "cacheblobs"),
|
||||
"EmulatorJS-Cache",
|
||||
this.config.cacheConfig.cacheMaxSizeMB,
|
||||
this.config.cacheConfig.cacheMaxAgeMins || 7200,
|
||||
this.debug
|
||||
|
||||
@ -24,7 +24,7 @@ class EJS_STORAGE {
|
||||
openRequest.onerror = () => resolve();
|
||||
openRequest.onsuccess = () => {
|
||||
let db = openRequest.result;
|
||||
let transaction = db.transaction([this.storeName], mode);
|
||||
let transaction = db.transaction(this.storeName, mode);
|
||||
let objectStore = transaction.objectStore(this.storeName);
|
||||
resolve(objectStore);
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user