UNPKG

@httpx/lru

Version:

LruCache implementations with O(1) complexity

1 lines 26.4 kB
{"version":3,"sources":["../src/doubly-linked-node.ts","../src/lru-cache.ts","../src/null-lru-cache.ts","../src/null-time-lru-cache.ts","../src/time-lru-cache.ts"],"names":["DoublyLinkedNode","key","LruCache","#maxSize","#touchOnHas","#onEviction","#cache","#head","#tail","params","maxSize","touchOnHas","onEviction","size","options","hasEntry","#moveToHead","value","data","newNode","#removeTail","valueOrFn","node","#removeNode","current","tailKey","NullLruCache","_params","_key","_options","_value","NullTimeLruCache","_ttl","TimeLruCache","#ttl","defaultTTL","ttl","val"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { BaseCacheKeyTypes } from './types';\n\nexport class DoublyLinkedNode<TValue, TKey extends BaseCacheKeyTypes = string> {\n readonly key: TKey;\n prev: DoublyLinkedNode<TValue, TKey> | null = null;\n next: DoublyLinkedNode<TValue, TKey> | null = null;\n constructor(key: TKey) {\n this.key = key;\n }\n}\n","import { DoublyLinkedNode } from './doubly-linked-node';\nimport type { ILruCache } from './lru-cache.interface';\nimport type {\n BaseCacheKeyTypes,\n LruCacheHasOptions,\n SupportedCacheValues,\n} from './types';\n\ntype LruCacheEntry<TValue, TKey extends BaseCacheKeyTypes = string> = {\n value: TValue;\n node: DoublyLinkedNode<TValue, TKey>;\n};\n\nexport type LruCacheParams<\n TValue = unknown,\n TKey extends BaseCacheKeyTypes = string,\n> = {\n /**\n * The maximum number of items that the cache can hold.\n */\n maxSize: number;\n /**\n * If true, the item will be marked as recently used when calling has.\n * @default false\n */\n touchOnHas?: boolean;\n /**\n * Callback that will be called before an item is evicted from the cache.\n * Useful for side effects or for items like object URLs that need explicit cleanup (revokeObjectURL).\n */\n onEviction?: (key: TKey, value: TValue) => void;\n};\n\n/**\n * Double linked list based lru cache that supports get in O(1)\n */\nexport class LruCache<\n TValue extends SupportedCacheValues = SupportedCacheValues,\n TKey extends BaseCacheKeyTypes = string,\n> implements ILruCache<TValue, TKey>\n{\n #maxSize: number;\n #touchOnHas: boolean;\n #onEviction?: ((key: TKey, value: TValue) => void) | undefined;\n\n #cache: Map<TKey, LruCacheEntry<TValue, TKey>>;\n #head: DoublyLinkedNode<TValue, TKey> | null = null;\n #tail: DoublyLinkedNode<TValue, TKey> | null = null;\n\n /**\n * Create a new LruCache instance\n *\n * @example\n * ```typescript\n * import { LruCache } from '@httpx/lru';\n *\n * const lru = new LruCache({ maxSize: 1000 });\n * lru.set('🦄', ['cool', 'stuff']);\n * if (lru.has('🦄')) {;\n * console.log(lru.get('🦄'));\n * // ['cool', 'stuff']\n * }\n * console.log(lru.size); // 1\n * lru.delete('🦄');\n * console.log(lru.size); // 0\n * lru.clear();\n * ```\n */\n constructor(params: LruCacheParams<TValue, TKey>) {\n const { maxSize, touchOnHas = false, onEviction } = params;\n if (!Number.isSafeInteger(maxSize) || maxSize < 1) {\n throw new TypeError('Invalid maxSize');\n }\n this.#touchOnHas = touchOnHas;\n this.#onEviction = onEviction;\n this.#maxSize = maxSize;\n this.#cache = new Map();\n }\n\n get params(): ILruCache['params'] {\n return {\n maxSize: this.#maxSize,\n };\n }\n\n /**\n * Return the current number of items in the cache\n */\n get size(): number {\n return this.#cache.size;\n }\n\n clear(): number {\n const size = this.#cache.size;\n this.#cache.clear();\n this.#head = this.#tail = null;\n return size;\n }\n\n has(key: TKey, options?: LruCacheHasOptions): boolean {\n const hasEntry = this.#cache.has(key);\n if (hasEntry && (options?.touch ?? this.#touchOnHas)) {\n this.#moveToHead(this.#cache.get(key)!.node);\n }\n return hasEntry;\n }\n\n set(key: TKey, value: TValue): boolean {\n if (this.#cache.has(key)) {\n const data = this.#cache.get(key)!;\n data.value = value;\n this.#moveToHead(data.node);\n return false;\n }\n\n const newNode = new DoublyLinkedNode(key);\n const data: LruCacheEntry<TValue, TKey> = { value, node: newNode };\n\n this.#cache.set(key, data);\n this.#moveToHead(newNode);\n\n if (this.#cache.size > this.#maxSize) {\n this.#removeTail();\n }\n return true;\n }\n\n get(key: TKey): TValue | undefined {\n const data = this.#cache.get(key);\n if (data === undefined) {\n return;\n }\n this.#moveToHead(data.node);\n return data.value;\n }\n\n getOrSet(key: TKey, valueOrFn: TValue | (() => TValue)): TValue {\n if (this.#cache.has(key)) {\n return this.get(key)!;\n }\n const value = typeof valueOrFn === 'function' ? valueOrFn() : valueOrFn;\n this.set(key, value);\n return value;\n }\n\n peek(key: TKey): TValue | undefined {\n return this.#cache.get(key)?.value;\n }\n\n delete(key: TKey): boolean {\n const node = this.#cache.get(key)?.node;\n if (node === undefined) {\n return false;\n }\n this.#removeNode(node);\n return this.#cache.delete(key);\n }\n\n *[Symbol.iterator](): IterableIterator<[TKey, TValue]> {\n let current = this.#tail;\n\n while (current) {\n const data = this.#cache.get(current.key)!;\n yield [current.key, data.value];\n current = current.prev;\n }\n }\n\n #moveToHead(node: DoublyLinkedNode<TValue, TKey>): void {\n if (node === this.#head) {\n return;\n }\n this.#removeNode(node);\n node.next = this.#head;\n node.prev = null;\n if (this.#head) {\n this.#head.prev = node;\n }\n this.#head = node;\n this.#tail ??= node;\n }\n\n #removeNode(node: DoublyLinkedNode<TValue, TKey>): void {\n if (node.prev) {\n node.prev.next = node.next;\n }\n if (node.next) {\n node.next.prev = node.prev;\n }\n if (node === this.#head) {\n this.#head = node.next;\n }\n if (node === this.#tail) {\n this.#tail = node.prev;\n }\n }\n\n #removeTail(): void {\n if (this.#tail === null) {\n return;\n }\n const tailKey = this.#tail.key;\n this.#removeNode(this.#tail);\n if (this.#onEviction) {\n this.#onEviction(tailKey, this.#cache.get(tailKey)!.value);\n }\n this.#cache.delete(tailKey);\n }\n}\n","import type { LruCacheParams } from './lru-cache';\nimport type { ILruCache } from './lru-cache.interface';\nimport type {\n BaseCacheKeyTypes,\n LruCacheHasOptions,\n SupportedCacheValues,\n} from './types';\n\nexport class NullLruCache<\n TValue extends SupportedCacheValues = SupportedCacheValues,\n TKey extends BaseCacheKeyTypes = string,\n> implements ILruCache<TValue, TKey>\n{\n /**\n * Create a new NullLruCache (does cache nothing)\n *\n * @example\n * ```typescript\n * import { NullLruCache } from '@httpx/lru';\n *\n * const lru = new NullLruCache({ maxSize: 1000 });\n * ```\n */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n constructor(_params: LruCacheParams<TValue, TKey>) {}\n\n readonly size = 0;\n readonly params = {\n maxSize: 0,\n };\n\n clear(): number {\n return 0;\n }\n\n has(_key: TKey, _options?: LruCacheHasOptions): boolean {\n return false;\n }\n\n set(_key: TKey, _value: TValue): boolean {\n return false;\n }\n\n get(_key: TKey): undefined {\n return undefined;\n }\n\n getOrSet(_key: TKey, valueOrFn: TValue | (() => TValue)): TValue {\n return typeof valueOrFn === 'function' ? valueOrFn() : valueOrFn;\n }\n\n peek(_key: TKey): undefined {\n return undefined;\n }\n\n delete(_key: TKey): boolean {\n return false;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n *[Symbol.iterator](): IterableIterator<[TKey, TValue]> {}\n}\n","import type { TimeLruCacheParams } from './time-lru-cache';\nimport type { ITimeLruCache } from './time-lru-cache.interface';\nimport type {\n BaseCacheKeyTypes,\n LruCacheHasOptions,\n Milliseconds,\n SupportedCacheValues,\n} from './types';\n\nexport class NullTimeLruCache<\n TValue extends SupportedCacheValues = SupportedCacheValues,\n TKey extends BaseCacheKeyTypes = string,\n> implements ITimeLruCache<TValue, TKey>\n{\n /**\n * Create a new NullTimeLruCache (does cache nothing)\n *\n * @example\n * ```typescript\n * import { NullTimeLruCache } from '@httpx/lru';\n *\n * const lru = new NullTimeLruCache({ maxSize: 1000 });\n * ```\n */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n constructor(_params: TimeLruCacheParams<TValue, TKey>) {}\n\n readonly size = 0;\n readonly params = {\n maxSize: 0,\n defaultTTL: 0,\n };\n\n clear(): number {\n return 0;\n }\n\n has(_key: TKey, _options?: LruCacheHasOptions): boolean {\n return false;\n }\n\n set(_key: TKey, _value: TValue, _ttl?: Milliseconds): boolean {\n return false;\n }\n\n get(_key: TKey): undefined {\n return undefined;\n }\n\n getOrSet(\n _key: TKey,\n valueOrFn: TValue | (() => TValue),\n _ttl?: Milliseconds\n ): TValue {\n return typeof valueOrFn === 'function' ? valueOrFn() : valueOrFn;\n }\n\n peek(_key: TKey): undefined {\n return undefined;\n }\n\n delete(_key: TKey): boolean {\n return false;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n *[Symbol.iterator](): IterableIterator<[TKey, TValue]> {}\n}\n","import { DoublyLinkedNode } from './doubly-linked-node';\nimport type { LruCacheParams } from './lru-cache';\nimport type { ITimeLruCache } from './time-lru-cache.interface';\nimport type {\n BaseCacheKeyTypes,\n EpochTimeInMilliseconds,\n LruCacheHasOptions,\n Milliseconds,\n SupportedCacheValues,\n} from './types';\n\ntype TimeLruCacheEntry<TValue, TKey extends BaseCacheKeyTypes = string> = {\n value: TValue;\n expiry: EpochTimeInMilliseconds;\n node: DoublyLinkedNode<TValue, TKey>;\n};\n\nexport type TimeLruCacheParams<\n TValue = unknown,\n TKey extends BaseCacheKeyTypes = string,\n> = LruCacheParams<TValue, TKey> & {\n /**\n * Default time to live for each entry in milliseconds\n */\n defaultTTL: Milliseconds;\n};\n\n/**\n * Double linked list based lru cache that supports get in O(1) and time to live for each entry\n */\nexport class TimeLruCache<\n TValue extends SupportedCacheValues = SupportedCacheValues,\n TKey extends BaseCacheKeyTypes = string,\n> implements ITimeLruCache<TValue, TKey>\n{\n #maxSize: number;\n #touchOnHas: boolean;\n\n #ttl: Milliseconds;\n\n #onEviction?: ((key: TKey, value: TValue) => void) | undefined;\n\n #cache: Map<TKey, TimeLruCacheEntry<TValue, TKey>>;\n #head: DoublyLinkedNode<TValue, TKey> | null = null;\n #tail: DoublyLinkedNode<TValue, TKey> | null = null;\n\n /**\n * Create a new LruCache instance\n *\n * @example\n * ```typescript\n * import { TimeLruCache } from '@httpx/lru';\n *\n * const THIRTY_SECONDS_IN_MILLIS = 30_000\n *\n * const lru = new TimeLruCache({ maxSize: 1000, defaultTTL: THIRTY_SECONDS_IN_MILLIS});\n * lru.set('🦄', ['cool', 'stuff'], THIRTY_SECONDS_IN_MILLIS);\n * if (lru.has('🦄')) {;\n * console.log(lru.get('🦄'));\n * // ['cool', 'stuff']\n * }\n * console.log(lru.size); // 1\n * lru.delete('🦄');\n * console.log(lru.size); // 0\n * lru.clear();\n * ```\n */\n constructor(params: TimeLruCacheParams<TValue, TKey>) {\n const { maxSize, touchOnHas = false, onEviction, defaultTTL } = params;\n if (!Number.isSafeInteger(maxSize) || maxSize < 1) {\n throw new TypeError('Invalid maxSize');\n }\n if (!Number.isSafeInteger(defaultTTL) || defaultTTL < 1) {\n throw new TypeError('Invalid ttl');\n }\n\n this.#touchOnHas = touchOnHas;\n this.#onEviction = onEviction;\n this.#maxSize = maxSize;\n this.#ttl = defaultTTL;\n this.#cache = new Map();\n }\n\n /**\n * Return the current size of the cache\n */\n get params(): ITimeLruCache['params'] {\n return {\n maxSize: this.#maxSize,\n defaultTTL: this.#ttl,\n };\n }\n\n /**\n * Return the current number of entries in the cache\n */\n get size(): number {\n return this.#cache.size;\n }\n\n clear(): number {\n const size = this.#cache.size;\n this.#cache.clear();\n this.#head = this.#tail = null;\n return size;\n }\n\n has(key: TKey, options?: LruCacheHasOptions): boolean {\n const value = this.#cache.get(key);\n const hasEntry = value !== undefined;\n const hasExpired = hasEntry && value.expiry < Date.now();\n\n if (hasExpired) {\n if (this.#onEviction) {\n this.#onEviction(key, this.#cache.get(key)!.value);\n }\n this.#removeNode(value.node);\n return false;\n }\n\n if (hasEntry && (options?.touch ?? this.#touchOnHas)) {\n this.#moveToHead(this.#cache.get(key)!.node);\n }\n return hasEntry;\n }\n\n set(key: TKey, value: TValue, ttl?: Milliseconds): boolean {\n if (this.#cache.has(key)) {\n const data = this.#cache.get(key)!;\n data.value = value;\n data.expiry = Date.now() + (ttl ?? this.#ttl);\n this.#moveToHead(data.node);\n return false;\n }\n\n const newNode = new DoublyLinkedNode(key);\n const data: TimeLruCacheEntry<TValue, TKey> = {\n value,\n expiry: Date.now() + (ttl ?? this.#ttl),\n node: newNode,\n };\n\n this.#cache.set(key, data);\n this.#moveToHead(newNode);\n\n if (this.#cache.size > this.#maxSize) {\n this.#removeTail();\n }\n return true;\n }\n\n get(key: TKey): TValue | undefined {\n const data = this.#cache.get(key);\n if (data === undefined) {\n return;\n }\n if (data.expiry < Date.now()) {\n if (this.#onEviction) {\n this.#onEviction(key, data.value);\n }\n this.#removeNode(data.node);\n return;\n }\n\n this.#moveToHead(data.node);\n\n return data.value;\n }\n\n getOrSet(\n key: TKey,\n valueOrFn: TValue | (() => TValue),\n ttl?: Milliseconds\n ): TValue {\n const val = this.get(key);\n if (val === undefined) {\n const value = typeof valueOrFn === 'function' ? valueOrFn() : valueOrFn;\n this.set(key, value, ttl);\n return value;\n }\n return val;\n }\n\n peek(key: TKey): TValue | undefined {\n const val = this.#cache.get(key);\n if (val === undefined) {\n return;\n }\n return val.expiry < Date.now() ? undefined : val.value;\n }\n\n delete(key: TKey): boolean {\n const node = this.#cache.get(key)?.node;\n if (node === undefined) {\n return false;\n }\n this.#removeNode(node);\n return this.#cache.delete(key);\n }\n\n /**\n * Iterate over the cache from the least recently used to the most recently used.\n *\n * ```typescript\n * const lru = new LruCache({ maxSize: 2 });\n * lru.set('key1', 'value1');\n * lru.set('key2', 'value2');\n * lru.set('key3', 'value3');\n * // trigger a get to move key2 to the head\n * lru.get('key2');\n * const results = [];\n * // iterate over the cache entries\n * for (const [key, value] of lru) {\n * results.push([key, value]);\n * }\n * expect(results).toStrictEqual([\n * ['key3', 'value3'], // Least recently used\n * ['key2', 'value2'], // Most recently used\n * ]);\n * ```\n */\n *[Symbol.iterator](): IterableIterator<[TKey, TValue]> {\n let current = this.#tail;\n\n while (current) {\n const data = this.#cache.get(current.key)!;\n yield [current.key, data.value];\n current = current.prev;\n }\n }\n\n #moveToHead(node: DoublyLinkedNode<TValue, TKey>): void {\n if (node === this.#head) {\n return;\n }\n this.#removeNode(node);\n node.next = this.#head;\n node.prev = null;\n if (this.#head) {\n this.#head.prev = node;\n }\n this.#head = node;\n this.#tail ??= node;\n }\n\n #removeNode(node: DoublyLinkedNode<TValue, TKey>): void {\n if (node.prev) {\n node.prev.next = node.next;\n }\n if (node.next) {\n node.next.prev = node.prev;\n }\n if (node === this.#head) {\n this.#head = node.next;\n }\n if (node === this.#tail) {\n this.#tail = node.prev;\n }\n }\n\n #removeTail(): void {\n if (this.#tail === null) {\n return;\n }\n const tailKey = this.#tail.key;\n this.#removeNode(this.#tail);\n if (this.#onEviction) {\n this.#onEviction(tailKey, this.#cache.get(tailKey)!.value);\n }\n this.#cache.delete(tailKey);\n }\n}\n"]}