diff --git a/lib/cache/memory-cache-store.js b/lib/cache/memory-cache-store.js index af5f14a9fbc..ab8d470eae7 100644 --- a/lib/cache/memory-cache-store.js +++ b/lib/cache/memory-cache-store.js @@ -18,7 +18,8 @@ class MemoryCacheStore { #maxEntrySize = Infinity #size = 0 - #entries = [] + #count = 0 + #entries = new Map() /** * @param {import('../../types/cache-interceptor.d.ts').default.MemoryCacheStoreOpts | undefined} [opts] @@ -73,12 +74,12 @@ class MemoryCacheStore { throw new TypeError(`expected key to be object, got ${typeof key}`) } + const topLevelKey = `${key.origin}:${key.path}` + const now = Date.now() - return this.#entries.find((entry) => ( + return this.#entries.get(topLevelKey)?.find((entry) => ( entry.deleteAt > now && entry.method === key.method && - entry.origin === key.origin && - entry.path === key.path && (entry.vary == null || Object.keys(entry.vary).every(headerName => entry.vary[headerName] === key.headers?.[headerName])) )) } @@ -96,6 +97,8 @@ class MemoryCacheStore { throw new TypeError(`expected value to be object, got ${typeof val}`) } + const topLevelKey = `${key.origin}:${key.path}` + const store = this const entry = { ...key, ...val, body: [], size: 0 } @@ -116,13 +119,25 @@ class MemoryCacheStore { callback(null) }, final (callback) { - store.#entries.push(entry) - store.#size += entry.size + let entries = store.#entries.get(topLevelKey) + if (!entries) { + entries = [] + store.#entries.set(topLevelKey, entries) + } + entries.push(entry) - while (store.#entries.length >= store.#maxCount || store.#size >= store.#maxSize) { - const count = Math.max(0, store.#entries.length - store.#maxCount / 2) - for (const entry of store.#entries.splice(0, count)) { - store.#size -= entry.size + store.#size += entry.size + store.#count += 1 + + if (store.#size > store.#maxSize || store.#count > store.#maxCount) { + for (const [key, entries] of store.#entries) { + for (const entry of entries.splice(0, entries.length / 2)) { + store.#size -= entry.size + store.#count -= 1 + } + if (entries.length === 0) { + store.#entries.delete(key) + } } } @@ -139,15 +154,13 @@ class MemoryCacheStore { throw new TypeError(`expected key to be object, got ${typeof key}`) } - const arr = [] - for (const entry of this.#entries) { - if (entry.path === key.path && entry.origin === key.origin) { - this.#size -= entry.size - } else { - arr.push(entry) - } + const topLevelKey = `${key.origin}:${key.path}` + + for (const entry of this.#entries.get(topLevelKey) ?? []) { + this.#size -= entry.size + this.#count -= 1 } - this.#entries = arr + this.#entries.delete(topLevelKey) } }