Skip to content

Commit 01cfb31

Browse files
committed
Add #isExpired() private function for DRY TTL expiration check
Extracts TTL expiration logic into a single private function that: - Returns false if ttl === 0 or item.expiry === 0 (noTTL items) - Returns true if item.expiry <= Date.now() for items with TTL set Updates get() and cleanup() to use #isExpired() instead of duplicating logic. Size reductions from DRY: get() reduced by 4 lines, cleanup() by 5 lines.
1 parent d1157db commit 01cfb31

6 files changed

Lines changed: 73 additions & 49 deletions

File tree

coverage.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
ℹ file | line % | branch % | funcs % | uncovered lines
44
ℹ ----------------------------------------------------------
55
ℹ src | | | |
6-
ℹ lru.js | 100.00 | 99.26 | 100.00 |
6+
ℹ lru.js | 100.00 | 99.27 | 100.00 |
77
ℹ ----------------------------------------------------------
8-
ℹ all files | 100.00 | 99.26 | 100.00 |
8+
ℹ all files | 100.00 | 99.27 | 100.00 |
99
ℹ ----------------------------------------------------------
1010
ℹ end of coverage report

dist/tiny-lru.cjs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,21 @@ class LRU {
157157
return item !== undefined ? item.expiry : undefined;
158158
}
159159

160+
/**
161+
* Checks if an item has expired.
162+
*
163+
* @param {Object} item - The cache item to check.
164+
* @returns {boolean} True if the item has expired, false otherwise.
165+
* @private
166+
*/
167+
#isExpired(item) {
168+
if (this.ttl === 0 || item.expiry === 0) {
169+
return false;
170+
}
171+
172+
return item.expiry <= Date.now();
173+
}
174+
160175
/**
161176
* Retrieves a value from the cache by key without updating LRU order.
162177
* Note: Does not perform TTL checks or remove expired items.
@@ -179,21 +194,15 @@ class LRU {
179194
const item = this.items[key];
180195

181196
if (item !== undefined) {
182-
// Check TTL only if item has expiration set
183-
if (this.ttl > 0 && item.expiry !== 0) {
184-
if (item.expiry <= Date.now()) {
185-
this.delete(key);
186-
this.#stats.misses++;
187-
188-
return undefined;
189-
}
197+
if (!this.#isExpired(item)) {
198+
this.moveToEnd(item);
199+
this.#stats.hits++;
200+
return item.value;
190201
}
191202

192-
// Fast LRU update without full set() overhead
193-
this.moveToEnd(item);
194-
this.#stats.hits++;
195-
196-
return item.value;
203+
this.delete(key);
204+
this.#stats.misses++;
205+
return undefined;
197206
}
198207

199208
this.#stats.misses++;
@@ -471,12 +480,11 @@ class LRU {
471480
return 0;
472481
}
473482

474-
const now = Date.now();
475483
let removed = 0;
476484

477485
for (let x = this.first; x !== null; ) {
478486
const next = x.next;
479-
if (x.expiry !== 0 && x.expiry <= now) {
487+
if (this.#isExpired(x)) {
480488
const key = x.key;
481489
if (this.items[key] !== undefined) {
482490
delete this.items[key];

dist/tiny-lru.js

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,21 @@ class LRU {
155155
return item !== undefined ? item.expiry : undefined;
156156
}
157157

158+
/**
159+
* Checks if an item has expired.
160+
*
161+
* @param {Object} item - The cache item to check.
162+
* @returns {boolean} True if the item has expired, false otherwise.
163+
* @private
164+
*/
165+
#isExpired(item) {
166+
if (this.ttl === 0 || item.expiry === 0) {
167+
return false;
168+
}
169+
170+
return item.expiry <= Date.now();
171+
}
172+
158173
/**
159174
* Retrieves a value from the cache by key without updating LRU order.
160175
* Note: Does not perform TTL checks or remove expired items.
@@ -177,21 +192,15 @@ class LRU {
177192
const item = this.items[key];
178193

179194
if (item !== undefined) {
180-
// Check TTL only if item has expiration set
181-
if (this.ttl > 0 && item.expiry !== 0) {
182-
if (item.expiry <= Date.now()) {
183-
this.delete(key);
184-
this.#stats.misses++;
185-
186-
return undefined;
187-
}
195+
if (!this.#isExpired(item)) {
196+
this.moveToEnd(item);
197+
this.#stats.hits++;
198+
return item.value;
188199
}
189200

190-
// Fast LRU update without full set() overhead
191-
this.moveToEnd(item);
192-
this.#stats.hits++;
193-
194-
return item.value;
201+
this.delete(key);
202+
this.#stats.misses++;
203+
return undefined;
195204
}
196205

197206
this.#stats.misses++;
@@ -469,12 +478,11 @@ class LRU {
469478
return 0;
470479
}
471480

472-
const now = Date.now();
473481
let removed = 0;
474482

475483
for (let x = this.first; x !== null; ) {
476484
const next = x.next;
477-
if (x.expiry !== 0 && x.expiry <= now) {
485+
if (this.#isExpired(x)) {
478486
const key = x.key;
479487
if (this.items[key] !== undefined) {
480488
delete this.items[key];

dist/tiny-lru.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/tiny-lru.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/lru.js

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,21 @@ export class LRU {
148148
return item !== undefined ? item.expiry : undefined;
149149
}
150150

151+
/**
152+
* Checks if an item has expired.
153+
*
154+
* @param {Object} item - The cache item to check.
155+
* @returns {boolean} True if the item has expired, false otherwise.
156+
* @private
157+
*/
158+
#isExpired(item) {
159+
if (this.ttl === 0 || item.expiry === 0) {
160+
return false;
161+
}
162+
163+
return item.expiry <= Date.now();
164+
}
165+
151166
/**
152167
* Retrieves a value from the cache by key without updating LRU order.
153168
* Note: Does not perform TTL checks or remove expired items.
@@ -170,21 +185,15 @@ export class LRU {
170185
const item = this.items[key];
171186

172187
if (item !== undefined) {
173-
// Check TTL only if item has expiration set
174-
if (this.ttl > 0 && item.expiry !== 0) {
175-
if (item.expiry <= Date.now()) {
176-
this.delete(key);
177-
this.#stats.misses++;
178-
179-
return undefined;
180-
}
188+
if (!this.#isExpired(item)) {
189+
this.moveToEnd(item);
190+
this.#stats.hits++;
191+
return item.value;
181192
}
182193

183-
// Fast LRU update without full set() overhead
184-
this.moveToEnd(item);
185-
this.#stats.hits++;
186-
187-
return item.value;
194+
this.delete(key);
195+
this.#stats.misses++;
196+
return undefined;
188197
}
189198

190199
this.#stats.misses++;
@@ -462,12 +471,11 @@ export class LRU {
462471
return 0;
463472
}
464473

465-
const now = Date.now();
466474
let removed = 0;
467475

468476
for (let x = this.first; x !== null; ) {
469477
const next = x.next;
470-
if (x.expiry !== 0 && x.expiry <= now) {
478+
if (this.#isExpired(x)) {
471479
const key = x.key;
472480
if (this.items[key] !== undefined) {
473481
delete this.items[key];

0 commit comments

Comments
 (0)