Files
orca/src/shared/secure-path-hardening-cache.ts
T
NeilandOrca 879aad7dd6 oom(foundation): bound shared readers/limits + add BoundedMap primitive (#10299)
* oom(01): A1-shared-readers — reintroduce #10179 subset

Files: 18 applied, 0 deleted (from 6eb70d8370)

Co-authored-by: Orca <help@stably.ai>

* oom(02): A2-shared-image-media — reintroduce #10179 subset

Files: 7 applied, 0 deleted (from 6eb70d8370)

Co-authored-by: Orca <help@stably.ai>

* oom(03): A3-shared-fs-listing — reintroduce #10179 subset

Files: 21 applied, 0 deleted (from 6eb70d8370)

Co-authored-by: Orca <help@stably.ai>

* oom(04): A4-shared-remote-relay — reintroduce #10179 subset

Files: 8 applied, 0 deleted (from 6eb70d8370)

Co-authored-by: Orca <help@stably.ai>

* oom(05): A5-shared-misc — reintroduce #10179 subset

Files: 28 applied, 0 deleted (from 6eb70d8370)

Co-authored-by: Orca <help@stably.ai>

* oom(06): B-shared-wiring — reintroduce #10179 subset

Files: 81 applied, 0 deleted (from 6eb70d8370)

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-24 21:36:57 -07:00

75 lines
1.8 KiB
TypeScript

export type SecurePathHardeningCacheBounds = {
maxEntries: number
maxKeyBytes: number
maxTotalKeyBytes: number
}
type RetainedSecurePath<T> = {
value: T
keyBytes: number
}
export class SecurePathHardeningCache<T> {
private readonly entries = new Map<string, RetainedSecurePath<T>>()
private retainedKeyBytes = 0
constructor(private readonly bounds: SecurePathHardeningCacheBounds) {}
get(path: string): T | undefined {
const retained = this.entries.get(path)
if (!retained) {
return undefined
}
this.entries.delete(path)
this.entries.set(path, retained)
return retained.value
}
set(path: string, value: T): boolean {
const keyBytes = Buffer.byteLength(path, 'utf8')
this.delete(path)
if (
keyBytes > this.bounds.maxKeyBytes ||
keyBytes > this.bounds.maxTotalKeyBytes ||
this.bounds.maxEntries <= 0
) {
return false
}
while (
this.entries.size >= this.bounds.maxEntries ||
this.retainedKeyBytes + keyBytes > this.bounds.maxTotalKeyBytes
) {
const oldest = this.entries.keys().next().value
if (oldest === undefined) {
return false
}
this.delete(oldest)
}
this.entries.set(path, { value, keyBytes })
this.retainedKeyBytes += keyBytes
return true
}
delete(path: string): void {
const retained = this.entries.get(path)
if (!retained) {
return
}
this.entries.delete(path)
this.retainedKeyBytes -= retained.keyBytes
}
clear(): void {
this.entries.clear()
this.retainedKeyBytes = 0
}
state(): { entries: number; keyBytes: number; paths: string[] } {
return {
entries: this.entries.size,
keyBytes: this.retainedKeyBytes,
paths: [...this.entries.keys()]
}
}
}