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