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}