Files
SnowLuma/.pnpm-store/v11/files/b8/e508073e0e468f9db3d9eb25e05b7f606f5c7835831e76b5c33fa2321fa9ac59c454673a3c031909bd616bdf208d662288121ccd87cf98f140304b6af554b4
TanTan 2a69b23b47
Dev Build / cleanup (push) Canceled after 0s
Dev Build / typecheck (push) Canceled after 0s
Dev Build / build (linux-arm64, ubuntu-24.04-arm, linux-arm64) (push) Canceled after 0s
Dev Build / build (linux-x64, ubuntu-latest, linux-x64) (push) Canceled after 0s
Dev Build / build (win-x64, windows-latest, win32-x64) (push) Canceled after 0s
Dev Build / dispatch-dev-docker (push) Skipped
docs: 仓库链接指向本镜像仓库
2026-11-13 09:27:07 +08:00

75 lines
1.7 KiB
Plaintext

export type LRUCache<TKey, TValue> = {
get: (key: TKey) => TValue | undefined
set: (key: TKey, value: TValue) => void
clear: () => void
}
export function createLRUCache<TKey, TValue>(
max: number,
): LRUCache<TKey, TValue> {
type Node = { prev?: Node; next?: Node; key: TKey; value: TValue }
const cache = new Map<TKey, Node>()
let oldest: Node | undefined
let newest: Node | undefined
const touch = (entry: Node) => {
if (!entry.next) return
if (!entry.prev) {
entry.next.prev = undefined
oldest = entry.next
entry.next = undefined
if (newest) {
entry.prev = newest
newest.next = entry
}
} else {
entry.prev.next = entry.next
entry.next.prev = entry.prev
entry.next = undefined
if (newest) {
newest.next = entry
entry.prev = newest
}
}
newest = entry
}
return {
get(key) {
const entry = cache.get(key)
if (!entry) return undefined
touch(entry)
return entry.value
},
set(key, value) {
if (cache.size >= max && oldest) {
const toDelete = oldest
cache.delete(toDelete.key)
if (toDelete.next) {
oldest = toDelete.next
toDelete.next.prev = undefined
}
if (toDelete === newest) {
newest = undefined
}
}
const existing = cache.get(key)
if (existing) {
existing.value = value
touch(existing)
} else {
const entry: Node = { key, value, prev: newest }
if (newest) newest.next = entry
newest = entry
if (!oldest) oldest = entry
cache.set(key, entry)
}
},
clear() {
cache.clear()
oldest = undefined
newest = undefined
},
}
}