lru.go

 1package lru
 2
 3import (
 4	"context"
 5
 6	"github.com/charmbracelet/soft-serve/server/cache"
 7	lru "github.com/hashicorp/golang-lru/v2"
 8)
 9
10// Cache is a memory cache that uses a LRU cache policy.
11type Cache struct {
12	cache   *lru.Cache[string, any]
13	onEvict func(key string, value any)
14	size    int
15}
16
17var _ cache.Cache = (*Cache)(nil)
18
19// WithSize sets the cache size.
20func WithSize(s int) cache.Option {
21	return func(c cache.Cache) {
22		ca := c.(*Cache)
23		ca.size = s
24	}
25}
26
27// WithEvictCallback sets the eviction callback.
28func WithEvictCallback(cb func(key string, value any)) cache.Option {
29	return func(c cache.Cache) {
30		ca := c.(*Cache)
31		ca.onEvict = cb
32	}
33}
34
35// NewCache returns a new Cache.
36func NewCache(_ context.Context, opts ...cache.Option) (cache.Cache, error) {
37	c := &Cache{}
38	for _, opt := range opts {
39		opt(c)
40	}
41
42	if c.size <= 0 {
43		c.size = 1
44	}
45
46	var err error
47	c.cache, err = lru.NewWithEvict(c.size, c.onEvict)
48	if err != nil {
49		return nil, err
50	}
51
52	return c, nil
53}
54
55// Delete implements cache.Cache.
56func (c *Cache) Delete(_ context.Context, key string) {
57	c.cache.Remove(key)
58}
59
60// Get implements cache.Cache.
61func (c *Cache) Get(_ context.Context, key string) (value any, ok bool) {
62	value, ok = c.cache.Get(key)
63	return
64}
65
66// Keys implements cache.Cache.
67func (c *Cache) Keys(_ context.Context) []string {
68	return c.cache.Keys()
69}
70
71// Set implements cache.Cache.
72func (c *Cache) Set(_ context.Context, key string, val any, _ ...cache.ItemOption) {
73	c.cache.Add(key, val)
74}
75
76// Len implements cache.Cache.
77func (c *Cache) Len(_ context.Context) int64 {
78	return int64(c.cache.Len())
79}
80
81// Contains implements cache.Cache.
82func (c *Cache) Contains(_ context.Context, key string) bool {
83	return c.cache.Contains(key)
84}