Skip to content

Commit de28b04

Browse files
committed
cache: more efficient pruning
Reduce transaction lock times. Refs: #4124
1 parent a180465 commit de28b04

1 file changed

Lines changed: 26 additions & 49 deletions

File tree

lib/cache/sqlite-cache-store.js

Lines changed: 26 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,13 @@ module.exports = class SqliteCacheStore {
6262
*/
6363
#deleteByUrlQuery
6464

65-
/**
66-
* @type {import('node:sqlite').StatementSync}
67-
*/
68-
#countEntriesQuery
69-
7065
/**
7166
* @type {import('node:sqlite').StatementSync | null}
7267
*/
7368
#deleteOldValuesQuery
7469

70+
#pruneInterval
71+
7572
/**
7673
* @param {import('../../types/cache-interceptor.d.ts').default.SqliteCacheStoreOpts | undefined} opts
7774
*/
@@ -196,10 +193,6 @@ module.exports = class SqliteCacheStore {
196193
`DELETE FROM cacheInterceptorV${VERSION} WHERE url = ?`
197194
)
198195

199-
this.#countEntriesQuery = this.#db.prepare(
200-
`SELECT COUNT(*) AS total FROM cacheInterceptorV${VERSION}`
201-
)
202-
203196
this.#deleteExpiredValuesQuery = this.#db.prepare(
204197
`DELETE FROM cacheInterceptorV${VERSION} WHERE deleteAt <= ?`
205198
)
@@ -212,13 +205,18 @@ module.exports = class SqliteCacheStore {
212205
SELECT
213206
id
214207
FROM cacheInterceptorV${VERSION}
215-
ORDER BY cachedAt DESC
216-
LIMIT ?
208+
ORDER BY deleteAt DESC
209+
OFFSET ${this.#maxCount}
217210
)
218211
`)
212+
213+
this.#pruneInterval = setInterval(() => {
214+
this.#prune()
215+
}, 10e3)
219216
}
220217

221218
close () {
219+
clearInterval(this.#pruneInterval)
222220
this.#db.close()
223221
}
224222

@@ -232,7 +230,7 @@ module.exports = class SqliteCacheStore {
232230
const value = this.#findValue(key)
233231
return value
234232
? {
235-
body: value.body ? Buffer.from(value.body.buffer, value.body.byteOffset, value.body.byteLength) : undefined,
233+
body: value.body ? Buffer.from(value.body.buffer) : undefined,
236234
statusCode: value.statusCode,
237235
statusMessage: value.statusMessage,
238236
headers: value.headers ? JSON.parse(value.headers) : undefined,
@@ -243,7 +241,7 @@ module.exports = class SqliteCacheStore {
243241
: undefined,
244242
cachedAt: value.cachedAt,
245243
staleAt: value.staleAt,
246-
deleteAt: value.deleteAt
244+
deleteAt: value.deleteAt || value.staleAt || value.cachedAt
247245
}
248246
: undefined
249247
}
@@ -279,7 +277,6 @@ module.exports = class SqliteCacheStore {
279277
existingValue.id
280278
)
281279
} else {
282-
this.#prune()
283280
// New response, let's insert it
284281
this.#insertValueQuery.run(
285282
url,
@@ -346,36 +343,15 @@ module.exports = class SqliteCacheStore {
346343
}
347344

348345
#prune () {
349-
if (this.size <= this.#maxCount) {
350-
return 0
351-
}
352-
353-
{
354-
const removed = this.#deleteExpiredValuesQuery.run(Date.now()).changes
355-
if (removed) {
356-
return removed
357-
}
358-
}
359-
360-
{
361-
const removed = this.#deleteOldValuesQuery?.run(Math.max(Math.floor(this.#maxCount * 0.1), 1)).changes
362-
if (removed) {
363-
return removed
364-
}
346+
if (this.#deleteOldValuesQuery) {
347+
this.#deleteOldValuesQuery?.run()
348+
} else {
349+
this.#deleteExpiredValuesQuery.run(Date.now())
365350
}
366351

367352
return 0
368353
}
369354

370-
/**
371-
* Counts the number of rows in the cache
372-
* @returns {Number}
373-
*/
374-
get size () {
375-
const { total } = this.#countEntriesQuery.get()
376-
return total
377-
}
378-
379355
/**
380356
* @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} key
381357
* @returns {string}
@@ -411,6 +387,10 @@ module.exports = class SqliteCacheStore {
411387
let matches = true
412388

413389
if (value.vary) {
390+
if (!headers) {
391+
return undefined
392+
}
393+
414394
const vary = JSON.parse(value.vary)
415395

416396
for (const header in vary) {
@@ -436,21 +416,18 @@ module.exports = class SqliteCacheStore {
436416
* @returns {boolean}
437417
*/
438418
function headerValueEquals (lhs, rhs) {
439-
if (lhs == null && rhs == null) {
440-
return true
441-
}
442-
443-
if ((lhs == null && rhs != null) ||
444-
(lhs != null && rhs == null)) {
445-
return false
446-
}
447-
448419
if (Array.isArray(lhs) && Array.isArray(rhs)) {
449420
if (lhs.length !== rhs.length) {
450421
return false
451422
}
452423

453-
return lhs.every((x, i) => x === rhs[i])
424+
for (let i = 0; i < lhs.length; i++) {
425+
if (rhs.includes(lhs[i])) {
426+
return false
427+
}
428+
}
429+
430+
return true
454431
}
455432

456433
return lhs === rhs

0 commit comments

Comments
 (0)