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
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}