Files
cache/lru/cache.go
T

118 lines
2.7 KiB
Go

// Copyright (C) 2019-2025, Lux Industries, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
// Package lru provides the ONE standard LRU cache implementation using container package.
package lru
import (
"sync"
"github.com/luxfi/cache"
"github.com/luxfi/container"
)
// Cache is the standard LRU cache - ONE implementation, no duplicates
type Cache[K comparable, V any] struct {
mu sync.Mutex
containerCache container.Cache[K, V] // Uses container package internally
capacity int
onEvict func(K, V)
}
// NewCache creates a new LRU cache - THE standard way
func NewCache[K comparable, V any](size int) *Cache[K, V] {
if size <= 0 {
size = 1
}
return &Cache[K, V]{
containerCache: container.NewLRUCache[K, V](size),
capacity: size,
onEvict: nil,
}
}
// NewCacheWithOnEvict creates cache with eviction callback
func NewCacheWithOnEvict[K comparable, V any](size int, onEvict func(K, V)) *Cache[K, V] {
if size <= 0 {
size = 1
}
return &Cache[K, V]{
containerCache: container.NewLRUCacheWithOnEvict[K, V](size, onEvict),
capacity: size,
onEvict: onEvict,
}
}
// Get retrieves value from cache
func (c *Cache[K, V]) Get(key K) (value V, ok bool) {
c.mu.Lock()
defer c.mu.Unlock()
return c.containerCache.Get(key)
}
// Put adds value to cache
func (c *Cache[K, V]) Put(key K, value V) {
c.mu.Lock()
defer c.mu.Unlock()
c.containerCache.Put(key, value)
}
// Delete removes value from cache
func (c *Cache[K, V]) Delete(key K) {
c.mu.Lock()
defer c.mu.Unlock()
c.containerCache.Delete(key)
}
// Len returns cache size
func (c *Cache[K, V]) Len() int {
c.mu.Lock()
defer c.mu.Unlock()
return c.containerCache.Len()
}
// Clear removes all items
func (c *Cache[K, V]) Clear() {
c.mu.Lock()
defer c.mu.Unlock()
c.containerCache = container.NewLRUCache[K, V](c.capacity)
}
// Contains checks key existence
func (c *Cache[K, V]) Contains(key K) bool {
c.mu.Lock()
defer c.mu.Unlock()
_, ok := c.containerCache.Get(key)
return ok
}
// Size returns cache size
func (c *Cache[K, V]) Size() int {
return c.Len()
}
// Evict removes a key from cache (required by Cacher interface)
func (c *Cache[K, V]) Evict(key K) {
c.Delete(key)
}
// Flush removes all entries from cache (required by Cacher interface)
func (c *Cache[K, V]) Flush() {
c.Clear()
}
// PortionFilled returns fraction of cache currently filled (0 --> 1)
func (c *Cache[K, V]) PortionFilled() float64 {
c.mu.Lock()
defer c.mu.Unlock()
current := float64(c.Len())
capacity := float64(c.capacity)
if capacity == 0 {
return 0
}
return current / capacity
}
// Interface compliance
var _ cache.Cacher[struct{}, struct{}] = (*Cache[struct{}, struct{}])(nil)