@@ -30,8 +30,10 @@ class CacheNode {
3030 * - Pattern-based invalidation for cache clearing
3131 */
3232class LRUCache {
33- constructor ( maxSize = 1000 , ttl = 300000 ) { // Default: 1000 entries, 5 minutes TTL
33+ constructor ( maxSize = 1000 , maxBytes = 1000000000 , ttl = 300000 ) { // Default: 1000 entries, 1000 MB , 5 minutes TTL
3434 this . maxSize = maxSize
35+ this . maxBytes = maxBytes
36+ this . life = Date . now ( )
3537 this . ttl = ttl // Time to live in milliseconds
3638 this . cache = new Map ( )
3739 this . head = null // Most recently used
@@ -173,10 +175,19 @@ class LRUCache {
173175 this . head = newNode
174176 if ( ! this . tail ) this . tail = newNode
175177
178+ // Check length limit
179+ if ( this . cache . size > this . maxSize ) this . removeTail ( )
180+
176181 // Check size limit
177- if ( this . cache . size > this . maxSize ) {
178- this . removeTail ( )
182+ let bytes = Buffer . byteLength ( JSON . stringify ( this . cache ) , 'utf8' )
183+ if ( bytes > this . maxBytes ) {
184+ console . warn ( "Cache byte size exceeded. Objects are being evicted." )
185+ while ( bytes > this . maxBytes ) {
186+ this . removeTail ( )
187+ bytes = Buffer . byteLength ( JSON . stringify ( this . cache ) , 'utf8' )
188+ }
179189 }
190+
180191 }
181192
182193 /**
@@ -367,7 +378,10 @@ class LRUCache {
367378 return {
368379 ...this . stats ,
369380 size : this . cache . size ,
381+ bytes : Buffer . byteLength ( JSON . stringify ( this . cache ) , 'utf8' ) ,
382+ lifespan : readableAge ( Date . now ( ) - this . life )
370383 maxSize : this . maxSize ,
384+ maxBytes : this . maxBytes
371385 hitRate : `${ hitRate } %` ,
372386 ttl : this . ttl
373387 }
@@ -377,7 +391,7 @@ class LRUCache {
377391 * Get detailed information about cache entries
378392 * Useful for debugging
379393 */
380- getDetails ( ) {
394+ getDetailsByEntry ( ) {
381395 const entries = [ ]
382396 let current = this . head
383397 let position = 0
@@ -386,23 +400,36 @@ class LRUCache {
386400 entries . push ( {
387401 position,
388402 key : current . key ,
389- age : Date . now ( ) - current . timestamp ,
403+ age : readableAge ( Date . now ( ) - current . timestamp ) ,
390404 hits : current . hits ,
391- size : JSON . stringify ( current . value ) . length
405+ size : JSON . stringify ( current . value ) . length ,
406+ bytes : Buffer . byteLength ( JSON . stringify ( current . value ) , 'utf8' )
392407 } )
393408 current = current . next
394409 position ++
395410 }
396411
397412 return entries
398413 }
414+
415+ readableAge ( mili ) {
416+ const seconds = Math . floor ( mili / 1000 )
417+ const minutes = Math . floor ( seconds / 60 )
418+ const hours = Math . floor ( minutes / 60 )
419+ const days = Math . floor ( hours / 24 )
420+ parts . push ( `${ Math . floor ( days ) } day${ Math . floor ( dats ) !== 1 ? 's' : '' } ` )
421+ parts . push ( `${ hours } hour${ hours !== 1 ? 's' : '' } ` )
422+ parts . push ( `${ minutes } minute${ minutes !== 1 ? 's' : '' } ` )
423+ parts . push ( `${ seconds } second${ seconds !== 1 ? 's' : '' } ` )
424+ return parts . join ( ", " )
425+ }
399426}
400427
401428// Create singleton cache instance
402429// Configuration can be adjusted via environment variables
403430const CACHE_MAX_SIZE = parseInt ( process . env . CACHE_MAX_SIZE ?? 1000 )
404- const CACHE_TTL = parseInt ( process . env . CACHE_TTL ?? 300000 ) // 5 minutes default
405-
431+ const CACHE_MAX_BYTES = parseInt ( process . env . CACHE_MAX_BYTES ?? 1000000000 ) // 1000 MB
432+ const CACHE_TTL = parseInt ( process . env . CACHE_TTL ?? 10000 ) // 5 minutes default
406433const cache = new LRUCache ( CACHE_MAX_SIZE , CACHE_TTL )
407-
434+ // Could also export this 'cache' as a instance of the LRUCache Class, but no use case for it yet.
408435export default cache
0 commit comments