@@ -95,6 +95,7 @@ func (mc *MemoryCache) Get(_ context.Context, key string, dest interface{}) (boo
9595
9696 memItem , ok := element .Value .(* memoryItem )
9797 if ! ok {
98+ mc .mutex .Unlock ()
9899 mc .updateStats (func (s * Stats ) { s .Misses ++ })
99100 mc .emitEvent (EventGet , key , nil , nil )
100101 return false , NewCacheError ("get" , key , errors .New ("invalid cache item type" ))
@@ -162,6 +163,7 @@ func (mc *MemoryCache) Set(_ context.Context, key string, value interface{}, ttl
162163 TTL : effectiveTTL ,
163164 Size : dataSize ,
164165 Namespace : mc .config .Namespace ,
166+ ExpiresAt : time.Time {}, // Default to no expiration
165167 }
166168
167169 if effectiveTTL > 0 {
@@ -177,7 +179,8 @@ func (mc *MemoryCache) Set(_ context.Context, key string, value interface{}, ttl
177179 defer mc .mutex .Unlock ()
178180
179181 // Check if key already exists
180- if element , exists := mc .items [formattedKey ]; exists {
182+ element , exists := mc .items [formattedKey ]
183+ if exists {
181184 // Update existing item
182185 oldMemItem , ok := element .Value .(* memoryItem )
183186 if ! ok {
@@ -192,20 +195,24 @@ func (mc *MemoryCache) Set(_ context.Context, key string, value interface{}, ttl
192195 mc .updateStats (func (s * Stats ) {
193196 s .Memory = s .Memory - oldMemItem .dataSize + dataSize
194197 })
195- } else {
196- // Add new item
197- element := mc .lruList .PushFront (memItem )
198- mc .items [formattedKey ] = element
199198
200- mc .updateStats (func (s * Stats ) {
201- s . Size ++
202- s . Memory += dataSize
203- })
199+ mc .updateStats (func (s * Stats ) { s . Sets ++ })
200+ mc . emitEvent ( EventSet , key , value , nil )
201+ return nil
202+ }
204203
205- // Check if we need to evict items
206- if mc .config .MaxSize > 0 && mc .stats .Size > mc .config .MaxSize {
207- mc .evictLRU ()
208- }
204+ // Add new item
205+ element = mc .lruList .PushFront (memItem )
206+ mc .items [formattedKey ] = element
207+
208+ mc .updateStats (func (s * Stats ) {
209+ s .Size ++
210+ s .Memory += dataSize
211+ })
212+
213+ // Check if we need to evict items
214+ if mc .config .MaxSize > 0 && mc .stats .Size > mc .config .MaxSize {
215+ mc .evictLRU ()
209216 }
210217
211218 mc .updateStats (func (s * Stats ) { s .Sets ++ })
@@ -250,17 +257,17 @@ func (mc *MemoryCache) Exists(_ context.Context, key string) (bool, error) {
250257 item := memItem .item
251258
252259 // Check if item has expired
253- if item .IsExpired () {
260+ if ! item .IsExpired () {
254261 mc .mutex .RUnlock ()
255- // Remove expired item
256- mc .mutex .Lock ()
257- mc .removeElement (element , formattedKey )
258- mc .mutex .Unlock ()
259- return false , nil
262+ return true , nil
260263 }
261264
262265 mc .mutex .RUnlock ()
263- return true , nil
266+ // Remove expired item
267+ mc .mutex .Lock ()
268+ mc .removeElement (element , formattedKey )
269+ mc .mutex .Unlock ()
270+ return false , nil
264271}
265272
266273// Clear removes all entries from the cache
@@ -364,13 +371,11 @@ func (mc *MemoryCache) SetTTL(_ context.Context, key string, ttl time.Duration)
364371 return NewCacheError ("setttl" , key , errors .New ("invalid item type" ))
365372 }
366373 item := memItem .item
367-
374+ item .ExpiresAt = time.Time {}
375+ item .TTL = 0
368376 if ttl > 0 {
369377 item .ExpiresAt = time .Now ().Add (ttl )
370378 item .TTL = ttl
371- } else {
372- item .ExpiresAt = time.Time {}
373- item .TTL = 0
374379 }
375380
376381 item .UpdatedAt = time .Now ()
@@ -430,17 +435,20 @@ func (mc *MemoryCache) evictLRU() {
430435 }
431436
432437 element := mc .lruList .Back ()
433- if element != nil {
434- memItem , ok := element .Value .(* memoryItem )
435- if ! ok {
436- return // Skip if invalid type
437- }
438- key := memItem .item .Key
439- mc .removeElement (element , key )
438+ if element == nil {
439+ return
440+ }
440441
441- mc .updateStats (func (s * Stats ) { s .Evictions ++ })
442- mc .emitEvent (EventEvict , key , nil , nil )
442+ memItem , ok := element .Value .(* memoryItem )
443+ if ! ok {
444+ return // Skip if invalid type
443445 }
446+
447+ key := memItem .item .Key
448+ mc .removeElement (element , key )
449+
450+ mc .updateStats (func (s * Stats ) { s .Evictions ++ })
451+ mc .emitEvent (EventEvict , key , nil , nil )
444452}
445453
446454// startCleanup starts the background cleanup goroutine
@@ -478,16 +486,21 @@ func (mc *MemoryCache) cleanupExpired() {
478486 }
479487 item := memItem .item
480488
481- if ! item .ExpiresAt .IsZero () && now .After (item .ExpiresAt ) {
482- expiredKeys = append ( expiredKeys , key )
489+ if item .ExpiresAt .IsZero () || ! now .After (item .ExpiresAt ) {
490+ continue
483491 }
492+
493+ expiredKeys = append (expiredKeys , key )
484494 }
485495
486496 // Remove expired items
487497 for _ , key := range expiredKeys {
488- if element , exists := mc .items [key ]; exists {
489- mc . removeElement ( element , key )
490- mc . emitEvent ( EventExpire , key , nil , nil )
498+ element , exists := mc .items [key ]
499+ if ! exists {
500+ continue
491501 }
502+
503+ mc .removeElement (element , key )
504+ mc .emitEvent (EventExpire , key , nil , nil )
492505 }
493506}
0 commit comments