Skip to content

Commit 0d3a416

Browse files
committed
add cache.info()
Fix: #325
1 parent e8feab5 commit 0d3a416

File tree

4 files changed

+91
-2
lines changed

4 files changed

+91
-2
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# cringe lorg
22

3+
## 10.1.0
4+
5+
- add `cache.info(key)` to get value as well as ttl and size
6+
information.
7+
38
## 10.0.0
49

510
- `cache.fetch()` return type is now `Promise<V | undefined>`

README.md

+15
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,21 @@ If the key is not found, `get()` will return `undefined`.
607607
For the usage of the `status` option, see **Status Tracking**
608608
below.
609609

610+
### `info(key) => Entry | undefined`
611+
612+
Return an `Entry` object containing the currently cached value,
613+
as well as ttl and size information if available. Returns
614+
undefined if the key is not found in the cache.
615+
616+
Unlike `dump()` (which is designed to be portable and survive
617+
serialization), the `start` value is always the current
618+
timestamp, and the `ttl` is a calculated remaining time to live
619+
(negative if expired).
620+
621+
Note that stale values are always returned, rather than being
622+
pruned and treated as if they were not in the cache. If you wish
623+
to exclude stale entries, guard against a negative `ttl` value.
624+
610625
### `async fetch(key, options = {}) => Promise`
611626

612627
The following options are supported:

src/index.ts

+33-2
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ class ZeroArray extends Array<number> {
130130
}
131131
}
132132
export type { ZeroArray }
133+
export type { Stack }
133134

134135
export type StackLike = Stack | Index[]
135136
class Stack {
@@ -164,7 +165,6 @@ class Stack {
164165
return this.heap[--this.length] as Index
165166
}
166167
}
167-
export type { Stack }
168168

169169
/**
170170
* Promise representing an in-progress {@link LRUCache#fetch} call
@@ -792,7 +792,8 @@ export namespace LRUCache {
792792
| OptionsTTLLimit<K, V, FC>
793793

794794
/**
795-
* Entry objects used by {@link LRUCache#load} and {@link LRUCache#dump}
795+
* Entry objects used by {@link LRUCache#load} and {@link LRUCache#dump},
796+
* and returned by {@link LRUCache#info}.
796797
*/
797798
export interface Entry<V> {
798799
value: V
@@ -1563,6 +1564,36 @@ export class LRUCache<K extends {}, V extends {}, FC = unknown> {
15631564
return deleted
15641565
}
15651566

1567+
/**
1568+
* Get the extended info about a given entry, to get its value, size, and
1569+
* TTL info simultaneously. Like {@link LRUCache#dump}, but just for a
1570+
* single key. Always returns stale values, if their info is found in the
1571+
* cache, so be sure to check for expired TTLs if relevant.
1572+
*/
1573+
info(key: K): LRUCache.Entry<V> | undefined {
1574+
const i = this.#keyMap.get(key)
1575+
if (i === undefined) return undefined
1576+
const v = this.#valList[i]
1577+
const value: V | undefined = this.#isBackgroundFetch(v)
1578+
? v.__staleWhileFetching
1579+
: v
1580+
if (value === undefined) return undefined
1581+
const entry: LRUCache.Entry<V> = { value }
1582+
if (this.#ttls && this.#starts) {
1583+
const ttl = this.#ttls[i]
1584+
const start = this.#starts[i]
1585+
if (ttl && start) {
1586+
const remain = ttl - (perf.now() - start)
1587+
entry.ttl = remain
1588+
entry.start = Date.now()
1589+
}
1590+
}
1591+
if (this.#sizes) {
1592+
entry.size = this.#sizes[i]
1593+
}
1594+
return entry
1595+
}
1596+
15661597
/**
15671598
* Return an array of [key, {@link LRUCache.Entry}] tuples which can be
15681599
* passed to cache.load()

test/info.ts

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import t from 'tap'
2+
import { LRUCache } from '../dist/esm/index.js'
3+
4+
t.test('just kv', t => {
5+
const c = new LRUCache<number, number>({ max: 2 })
6+
c.set(1, 10)
7+
c.set(2, 20)
8+
c.set(3, 30)
9+
t.equal(c.info(1), undefined)
10+
t.strictSame(c.info(2), { value: 20 })
11+
t.strictSame(c.info(3), { value: 30 })
12+
t.end()
13+
})
14+
15+
t.test('other info', t => {
16+
const c = new LRUCache<number, number>({
17+
max: 2,
18+
ttl: 1000,
19+
maxSize: 10000,
20+
})
21+
c.set(1, 10, { size: 100 })
22+
c.set(2, 20, { size: 200 })
23+
c.set(3, 30, { size: 300 })
24+
t.equal(c.info(1), undefined)
25+
t.match(c.info(2), {
26+
value: 20,
27+
size: 200,
28+
ttl: Number,
29+
start: Number,
30+
})
31+
t.match(c.info(3), {
32+
value: 30,
33+
size: 300,
34+
ttl: Number,
35+
start: Number,
36+
})
37+
t.end()
38+
})

0 commit comments

Comments
 (0)