Optimize cache verification
| @@ -43,7 +43,7 @@ class DiskCache { | |||
| 43 | static DIRECTORY = 'characters'; | 43 | static DIRECTORY = 'characters'; |
| 44 | 44 | ||
| 45 | /** @type {number} */ | 45 | /** @type {number} */ |
| 46 | static REMOVAL_INTERVAL = 60000; | 46 | static REMOVAL_INTERVAL = 60 * 1000; |
| 47 | 47 | ||
| 48 | /** @type {import('node-persist').LocalStorage} */ | 48 | /** @type {import('node-persist').LocalStorage} */ |
| 49 | #instance; | 49 | #instance; |
| @@ -58,6 +58,22 @@ class DiskCache { | |||
| 58 | removalQueue = []; | 58 | removalQueue = []; |
| 59 | 59 | ||
| 60 | /** | 60 | /** |
| 61 | * Path to the cache directory. | ||
| 62 | * @returns {string} | ||
| 63 | */ | ||
| 64 | get cachePath() { | ||
| 65 | return path.join(globalThis.DATA_ROOT, '_cache', DiskCache.DIRECTORY); | ||
| 66 | } | ||
| 67 | |||
| 68 | /** | ||
| 69 | * Returns the list of hashed keys in the cache. | ||
| 70 | * @returns {string[]} | ||
| 71 | */ | ||
| 72 | get hashedKeys() { | ||
| 73 | return fs.readdirSync(this.cachePath); | ||
| 74 | } | ||
| 75 | |||
| 76 | /** | ||
| 61 | * Processes the removal queue. | 77 | * Processes the removal queue. |
| 62 | * @returns {Promise<void>} | 78 | * @returns {Promise<void>} |
| 63 | */ | 79 | */ |
| @@ -110,8 +126,7 @@ class DiskCache { | |||
| 110 | return this.#instance; | 126 | return this.#instance; |
| 111 | } | 127 | } |
| 112 | 128 | ||
| 113 | const cacheDir = path.join(globalThis.DATA_ROOT, '_cache', DiskCache.DIRECTORY); | 129 | this.#instance = storage.create({ dir: this.cachePath, ttl: false }); |
| 114 | this.#instance = storage.create({ dir: cacheDir, ttl: false }); | ||
| 115 | await this.#instance.init(); | 130 | await this.#instance.init(); |
| 116 | this.#removalInterval = setInterval(this.#removeCacheEntries.bind(this), DiskCache.REMOVAL_INTERVAL); | 131 | this.#removalInterval = setInterval(this.#removeCacheEntries.bind(this), DiskCache.REMOVAL_INTERVAL); |
| 117 | return this.#instance; | 132 | return this.#instance; |
| @@ -128,18 +143,17 @@ class DiskCache { | |||
| 128 | } | 143 | } |
| 129 | 144 | ||
| 130 | const cache = await this.instance(); | 145 | const cache = await this.instance(); |
| 131 | const validKeys = []; | 146 | const validKeys = new Set(); |
| 132 | for (const dir of directoriesList) { | 147 | for (const dir of directoriesList) { |
| 133 | const files = fs.readdirSync(dir.characters); | 148 | const files = fs.readdirSync(dir.characters, { withFileTypes: true }); |
| 134 | for (const file of files) { | 149 | for (const file of files.filter(f => f.isFile() && path.extname(f.name) === '.png')) { |
| 135 | const filePath = path.join(dir.characters, file); | 150 | const filePath = path.join(dir.characters, file.name); |
| 136 | const stat = fs.statSync(filePath); | 151 | const stat = fs.statSync(filePath); |
| 137 | validKeys.push(`${filePath}-${stat.mtimeMs}`); | 152 | validKeys.add(path.parse(cache.getDatumPath(`${filePath}-${stat.mtimeMs}`)).base); |
| 138 | } | 153 | } |
| 139 | } | 154 | } |
| 140 | const cacheKeys = await cache.keys(); | 155 | for (const key of this.hashedKeys) { |
| 141 | for (const key of cacheKeys) { | 156 | if (!validKeys.has(key)) { |
| 142 | if (!validKeys.includes(key)) { | ||
| 143 | await cache.removeItem(key); | 157 | await cache.removeItem(key); |
| 144 | } | 158 | } |
| 145 | } | 159 | } |