| | import { deleteMapEntry } from './cache-map' |
| | import type { UnknownMapEntry } from './cache-map' |
| |
|
| | |
| | |
| |
|
| | let head: UnknownMapEntry | null = null |
| | let didScheduleCleanup: boolean = false |
| | let lruSize: number = 0 |
| |
|
| | |
| | |
| | |
| | const maxLruSize = 50 * 1024 * 1024 |
| |
|
| | export function lruPut(node: UnknownMapEntry) { |
| | if (head === node) { |
| | |
| | return |
| | } |
| | const prev = node.prev |
| | const next = node.next |
| | if (next === null || prev === null) { |
| | |
| | lruSize += node.size |
| | |
| | |
| | |
| | ensureCleanupIsScheduled() |
| | } else { |
| | |
| | prev.next = next |
| | next.prev = prev |
| | } |
| |
|
| | |
| | if (head === null) { |
| | |
| | node.prev = node |
| | node.next = node |
| | } else { |
| | |
| | const tail = head.prev |
| | node.prev = tail |
| | |
| | if (tail !== null) { |
| | tail.next = node |
| | } |
| | node.next = head |
| | head.prev = node |
| | } |
| | head = node |
| | } |
| |
|
| | export function updateLruSize(node: UnknownMapEntry, newNodeSize: number) { |
| | |
| | |
| | const prevNodeSize = node.size |
| | node.size = newNodeSize |
| | if (node.next === null) { |
| | |
| | return |
| | } |
| | |
| | lruSize = lruSize - prevNodeSize + newNodeSize |
| | ensureCleanupIsScheduled() |
| | } |
| |
|
| | export function deleteFromLru(deleted: UnknownMapEntry) { |
| | const next = deleted.next |
| | const prev = deleted.prev |
| | if (next !== null && prev !== null) { |
| | lruSize -= deleted.size |
| |
|
| | deleted.next = null |
| | deleted.prev = null |
| |
|
| | |
| | if (head === deleted) { |
| | |
| | if (next === head) { |
| | |
| | head = null |
| | } else { |
| | head = next |
| | } |
| | } else { |
| | prev.next = next |
| | next.prev = prev |
| | } |
| | } else { |
| | |
| | } |
| | } |
| |
|
| | function ensureCleanupIsScheduled() { |
| | if (didScheduleCleanup || lruSize <= maxLruSize) { |
| | return |
| | } |
| | didScheduleCleanup = true |
| | requestCleanupCallback(cleanup) |
| | } |
| |
|
| | function cleanup() { |
| | didScheduleCleanup = false |
| |
|
| | |
| | |
| | |
| | const ninetyPercentMax = maxLruSize * 0.9 |
| | while (lruSize > ninetyPercentMax && head !== null) { |
| | const tail = head.prev |
| | |
| | if (tail !== null) { |
| | |
| | |
| | deleteMapEntry(tail) |
| | } |
| | } |
| | } |
| |
|
| | const requestCleanupCallback = |
| | typeof requestIdleCallback === 'function' |
| | ? requestIdleCallback |
| | : (cb: () => void) => setTimeout(cb, 0) |
| |
|