22
33/**
44 * In-memory LRU cache implementation for RERUM API
5- * Caches query, search, and id lookup results to reduce MongoDB Atlas load
5+ * Caches read operation results to reduce MongoDB Atlas load.
6+ * Uses smart invalidation during writes to invalidate affected cached reads.
67 * @author thehabes
78 */
89
@@ -95,6 +96,7 @@ class LRUCache {
9596
9697 /**
9798 * Remove tail node (least recently used)
99+ * Record eviction by increasing eviction count.
98100 */
99101 removeTail ( ) {
100102 if ( ! this . tail ) return null
@@ -123,6 +125,7 @@ class LRUCache {
123125
124126 /**
125127 * Get value from cache
128+ * Record hits and misses for the stats
126129 * @param {string } key - Cache key
127130 * @returns {* } Cached value or null if not found/expired
128131 */
@@ -166,6 +169,7 @@ class LRUCache {
166169
167170 /**
168171 * Set value in cache
172+ * Record the set for the stats
169173 * @param {string } key - Cache key
170174 * @param {* } value - Value to cache
171175 */
@@ -174,6 +178,7 @@ class LRUCache {
174178
175179 // Check if key already exists
176180 if ( this . cache . has ( key ) ) {
181+ // This set overwrites this existing node and moves it to the head.
177182 const node = this . cache . get ( key )
178183 node . value = value
179184 node . timestamp = Date . now ( )
@@ -235,16 +240,12 @@ class LRUCache {
235240 if ( typeof pattern === 'string' ) {
236241 // Simple string matching
237242 for ( const key of this . cache . keys ( ) ) {
238- if ( key . includes ( pattern ) ) {
239- keysToDelete . push ( key )
240- }
243+ if ( key . includes ( pattern ) ) keysToDelete . push ( key )
241244 }
242245 } else if ( pattern instanceof RegExp ) {
243246 // Regex matching
244247 for ( const key of this . cache . keys ( ) ) {
245- if ( pattern . test ( key ) ) {
246- keysToDelete . push ( key )
247- }
248+ if ( pattern . test ( key ) ) keysToDelete . push ( key )
248249 }
249250 }
250251
@@ -254,28 +255,6 @@ class LRUCache {
254255 return keysToDelete . length
255256 }
256257
257- /**
258- * Invalidate cache for a specific object ID
259- * This clears the ID cache and any query/search results that might contain it
260- * @param {string } id - Object ID to invalidate
261- */
262- invalidateById ( id ) {
263- const idKey = `id:${ id } `
264- let count = 0
265-
266- // Delete direct ID cache
267- if ( this . delete ( idKey ) ) {
268- count ++
269- }
270-
271- // Invalidate all queries and searches (conservative approach)
272- // In a production environment, you might want to be more selective
273- count += this . invalidate ( / ^ ( q u e r y | s e a r c h | s e a r c h P h r a s e ) : / )
274-
275- this . stats . invalidations += count
276- return count
277- }
278-
279258 /**
280259 * Smart invalidation based on object properties
281260 * Only invalidates query/search caches that could potentially match this object
@@ -330,10 +309,7 @@ class LRUCache {
330309 */
331310 objectMatchesQuery ( obj , query ) {
332311 // For query endpoint: check if object matches the query body
333- if ( query . body && typeof query . body === 'object' ) {
334- return this . objectContainsProperties ( obj , query . body )
335- }
336-
312+ if ( query . body && typeof query . body === 'object' ) return this . objectContainsProperties ( obj , query . body )
337313 // For direct queries (like {"type":"CacheTest"}), check if object matches
338314 return this . objectContainsProperties ( obj , query )
339315 }
0 commit comments