Skip to content

Commit

Permalink
feat: updateAgeOnHas
Browse files Browse the repository at this point in the history
  • Loading branch information
isaacs committed Apr 7, 2022
1 parent 74044a7 commit 44c5ec9
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 9 deletions.
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,15 @@ If you put more stuff in it, then items will fall out.

Boolean, default false, only relevant if `ttl` is set.

* `updateAgeOnHas` - When using time-expiring entries with `ttl`, setting
this to `true` will make each item's age reset to 0 whenever its presence
in the cache is checked with `has()`, causing it to not expire. (It can
still fall out of cache based on recency of use, of course.)

This may be overridden by passing an options object to `cache.has()`.

Boolean, default false, only relevant if `ttl` is set.

## API

* `new LRUCache(options)`
Expand All @@ -319,7 +328,7 @@ If you put more stuff in it, then items will fall out.

* `cache.max`, `cache.maxSize`, `cache.allowStale`, `cache.noDisposeOnSet`,
`cache.sizeCalculation`, `cache.dispose`, `cache.maxSize`, `cache.ttl`,
`cache.updateAgeOnGet`
`cache.updateAgeOnGet`, `cache.updateAgeOnHas`

All option names are exposed as public members on the cache object.

Expand Down Expand Up @@ -392,9 +401,11 @@ If you put more stuff in it, then items will fall out.
Returns `undefined` if the item is stale, unless `allowStale` is set
either on the cache or in the options object.

* `has(key)`
* `has(key, { updateAgeOnHas } = {}) => Boolean`

Check if a key is in the cache, without updating the recency or age.
Check if a key is in the cache, without updating the recency of use.
Age is updated if `updateAgeOnHas` is set to `true` in either the
options or the constructor.

Will return `false` if the item is stale, even though it is technically
in the cache.
Expand Down
17 changes: 14 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class LRUCache {
ttlResolution = 1,
ttlAutopurge,
updateAgeOnGet,
updateAgeOnHas,
allowStale,
dispose,
disposeAfter,
Expand Down Expand Up @@ -176,6 +177,7 @@ class LRUCache {

this.allowStale = !!allowStale || !!stale
this.updateAgeOnGet = !!updateAgeOnGet
this.updateAgeOnHas = !!updateAgeOnHas
this.ttlResolution = isPosInt(ttlResolution) || ttlResolution === 0
? ttlResolution : 1
this.ttlAutopurge = !!ttlAutopurge
Expand Down Expand Up @@ -213,7 +215,7 @@ class LRUCache {
}

getRemainingTTL (key) {
return this.has(key) ? Infinity : 0
return this.has(key, { updateAgeOnHas: false }) ? Infinity : 0
}

initializeTTLTracking () {
Expand Down Expand Up @@ -555,8 +557,17 @@ class LRUCache {
return head
}

has (k) {
return this.keyMap.has(k) && !this.isStale(this.keyMap.get(k))
has (k, { updateAgeOnHas = this.updateAgeOnHas } = {}) {
const index = this.keyMap.get(k)
if (index !== undefined) {
if (!this.isStale(index)) {
if (updateAgeOnHas) {
this.updateItemAge(index)
}
return true
}
}
return false
}

// like get(), but without any LRU updating or TTL expiration
Expand Down
14 changes: 11 additions & 3 deletions test/ttl.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,16 +198,24 @@ const runTests = (LRU, t) => {
t.end()
})

t.test('ttl with updateAgeOnGet', t => {
const c = new LRU({ max: 5, ttl: 10, updateAgeOnGet: true, ttlResolution: 0 })
t.test('ttl with updateAgeOnGet/updateAgeOnHas', t => {
const c = new LRU({
max: 5,
ttl: 10,
updateAgeOnGet: true,
updateAgeOnHas: true,
ttlResolution: 0,
})
c.set(1, 1)
t.equal(c.get(1), 1)
clock.advance(5)
t.equal(c.get(1), 1)
t.equal(c.has(1), true)
clock.advance(5)
t.equal(c.get(1), 1)
clock.advance(1)
t.equal(c.getRemainingTTL(1), 9)
t.equal(c.has(1), true)
t.equal(c.getRemainingTTL(1), 10)
t.equal(c.get(1), 1)
t.equal(c.size, 1)
c.clear()
Expand Down

0 comments on commit 44c5ec9

Please sign in to comment.