Documentation
¶
Overview ¶
Package multicache provides a high-performance adaptive cache with optional persistence.
Index ¶
- type Cache
- func (*Cache[K, V]) Close()
- func (c *Cache[K, V]) Delete(key K)
- func (c *Cache[K, V]) Flush() int
- func (c *Cache[K, V]) Get(key K) (V, bool)
- func (c *Cache[K, V]) GetSet(key K, loader func() (V, error), ttl ...time.Duration) (V, error)
- func (c *Cache[K, V]) Len() int
- func (c *Cache[K, V]) Set(key K, value V, ttl ...time.Duration)
- func (c *Cache[K, V]) SetIfAbsent(key K, value V, ttl ...time.Duration) (V, bool)
- type Option
- type Store
- type TieredCache
- func (c *TieredCache[K, V]) Close() error
- func (c *TieredCache[K, V]) Delete(ctx context.Context, key K) error
- func (c *TieredCache[K, V]) Flush(ctx context.Context) (int, error)
- func (c *TieredCache[K, V]) Get(ctx context.Context, key K) (V, bool, error)
- func (c *TieredCache[K, V]) GetSet(ctx context.Context, key K, loader func(context.Context) (V, error), ...) (V, error)
- func (c *TieredCache[K, V]) Len() int
- func (c *TieredCache[K, V]) Set(ctx context.Context, key K, value V, ttl ...time.Duration) error
- func (c *TieredCache[K, V]) SetAsync(ctx context.Context, key K, value V, ttl ...time.Duration) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Cache ¶
type Cache[K comparable, V any] struct { // contains filtered or unexported fields }
Cache is a fast in-memory cache without persistence. All operations are context-free and never return errors.
func New ¶
func New[K comparable, V any](opts ...Option) *Cache[K, V]
New creates a new in-memory cache.
Example:
cache := multicache.New[string, User](
multicache.Size(10000),
multicache.TTL(time.Hour),
)
defer cache.Close()
cache.Set("user:123", user) // uses default TTL
cache.Set("user:123", user, time.Hour) // explicit TTL
user, ok := cache.Get("user:123")
func (*Cache[K, V]) Close ¶
func (*Cache[K, V]) Close()
Close releases resources held by the cache. For Cache this is a no-op, but provided for API consistency.
func (*Cache[K, V]) Delete ¶
func (c *Cache[K, V]) Delete(key K)
Delete removes a value from the cache.
func (*Cache[K, V]) Flush ¶
Flush removes all entries from the cache. Returns the number of entries removed.
func (*Cache[K, V]) Get ¶
Get retrieves a value from the cache. Returns the value and true if found, or the zero value and false if not found.
func (*Cache[K, V]) GetSet ¶
GetSet retrieves a value from the cache, or calls loader to compute and store it. This prevents thundering herd: if multiple goroutines request the same missing key concurrently, only one loader runs while others wait for its result.
Example:
user, err := cache.GetSet("user:123", func() (User, error) {
return fetchUserFromDB("123")
})
// Or with explicit TTL:
user, err := cache.GetSet("user:123", func() (User, error) {
return fetchUserFromDB("123")
}, time.Hour)
func (*Cache[K, V]) Set ¶
Set stores a value in the cache. If no TTL is provided, the default TTL is used. If no default TTL is configured, the entry never expires.
func (*Cache[K, V]) SetIfAbsent ¶
SetIfAbsent stores value only if key doesn't exist. Returns the existing value and true if found, or the new value and false if stored. Unlike GetSet, this has no thundering herd protection - use when value is precomputed.
type Option ¶
type Option func(*config)
Option configures a Cache.
type Store ¶
type Store[K comparable, V any] interface { // ValidateKey checks if a key is valid for this persistence store. ValidateKey(key K) error // Get retrieves a value from persistent storage. Get(ctx context.Context, key K) (V, time.Time, bool, error) // Set saves a value to persistent storage with an expiry time. Set(ctx context.Context, key K, value V, expiry time.Time) error // Delete removes a value from persistent storage. Delete(ctx context.Context, key K) error // Cleanup removes expired entries older than maxAge. Cleanup(ctx context.Context, maxAge time.Duration) (int, error) // Location returns the storage location for a given key. Location(key K) string // Flush removes all entries from persistent storage. Flush(ctx context.Context) (int, error) // Len returns the number of entries in persistent storage. Len(ctx context.Context) (int, error) // Close releases any resources held by the persistence store. Close() error }
Store defines the interface for cache persistence backends. Uses only standard library types, so implementations can satisfy it without importing this package.
type TieredCache ¶
type TieredCache[K comparable, V any] struct { // Store provides direct access to the persistence layer. // Use this for persistence-specific operations: // cache.Store.Len(ctx) // cache.Store.Flush(ctx) // cache.Store.Cleanup(ctx, maxAge) Store Store[K, V] // contains filtered or unexported fields }
TieredCache is a cache with an in-memory layer backed by persistent storage. The memory layer provides fast access, while the store provides durability. Core operations require context for I/O, while memory operations like Len() do not.
func NewTiered ¶
func NewTiered[K comparable, V any](store Store[K, V], opts ...Option) (*TieredCache[K, V], error)
NewTiered creates a cache with an in-memory layer backed by persistent storage.
Example:
store, _ := localfs.New[string, User]("myapp", "")
cache, err := multicache.NewTiered[string, User](store,
multicache.Size(10000),
multicache.TTL(time.Hour),
)
if err != nil {
return err
}
defer cache.Close()
cache.Set(ctx, "user:123", user) // uses default TTL
cache.Set(ctx, "user:123", user, time.Hour) // explicit TTL
user, ok, err := cache.Get(ctx, "user:123")
storeCount, _ := cache.Store.Len(ctx)
func (*TieredCache[K, V]) Close ¶
func (c *TieredCache[K, V]) Close() error
Close releases resources held by the cache.
func (*TieredCache[K, V]) Delete ¶
func (c *TieredCache[K, V]) Delete(ctx context.Context, key K) error
Delete removes a value from the cache. The value is always removed from memory. Returns an error if persistence deletion fails.
func (*TieredCache[K, V]) Flush ¶
func (c *TieredCache[K, V]) Flush(ctx context.Context) (int, error)
Flush removes all entries from the cache, including persistent storage. Returns the total number of entries removed from memory and persistence.
func (*TieredCache[K, V]) Get ¶
func (c *TieredCache[K, V]) Get(ctx context.Context, key K) (V, bool, error)
Get retrieves a value from the cache. It first checks the memory cache, then falls back to persistence.
func (*TieredCache[K, V]) GetSet ¶
func (c *TieredCache[K, V]) GetSet(ctx context.Context, key K, loader func(context.Context) (V, error), ttl ...time.Duration) (V, error)
GetSet retrieves a value from the cache (memory or persistence), or calls loader to compute and store it. This prevents thundering herd: if multiple goroutines request the same missing key concurrently, only one loader runs while others wait for its result.
Example:
user, err := cache.GetSet(ctx, "user:123", func(ctx context.Context) (User, error) {
return fetchUserFromAPI(ctx, "123")
})
// Or with explicit TTL:
user, err := cache.GetSet(ctx, "user:123", func(ctx context.Context) (User, error) {
return fetchUserFromAPI(ctx, "123")
}, time.Hour)
func (*TieredCache[K, V]) Len ¶
func (c *TieredCache[K, V]) Len() int
Len returns the number of entries in the memory cache. For persistence entry count, use cache.Store.Len(ctx).
func (*TieredCache[K, V]) Set ¶
Set stores a value in the cache. If no TTL is provided, the default TTL is used. The value is ALWAYS stored in memory, even if persistence fails. Returns an error if the key violates persistence constraints or if persistence fails.
func (*TieredCache[K, V]) SetAsync ¶
func (c *TieredCache[K, V]) SetAsync(ctx context.Context, key K, value V, ttl ...time.Duration) error
SetAsync stores a value in the cache, handling persistence asynchronously. If no TTL is provided, the default TTL is used. Key validation and in-memory caching happen synchronously. Persistence errors are logged but not returned (fire-and-forget). Returns an error only for validation failures (e.g., invalid key format).