1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
// Copyright (C) 2023 Luke Shumaker <lukeshu@lukeshu.com>
//
// SPDX-License-Identifier: GPL-2.0-or-later
package containers
import (
"context"
)
// A Source is something that a Cache sits in front of.
type Source[K comparable, V any] interface {
// Load updates a 'V' (which is reused across the lifetime of
// the cache, and may or may not be zero) to be set to the
// value for the 'K'.
Load(context.Context, K, *V)
// Flush does whatever it needs to in order to ensure that if
// the program exited right now, no one would be upset. Flush
// being called does not mean that the entry is being evicted
// from the cache.
Flush(context.Context, *V)
}
type Cache[K comparable, V any] interface {
// Acquire loads the value for `k` (possibly from the cache),
// records that value in to the cache, and increments the
// cache entry's in-use counter preventing it from being
// evicted.
//
// If the cache is at capacity and all entries are in-use,
// then Acquire blocks until an entry becomes available (via
// `Release`).
Acquire(context.Context, K) *V
// Release decrements the in-use counter for the cache entry
// for `k`. If the in-use counter drops to 0, then that entry
// may be evicted.
//
// It is invalid (runtime-panic) to call Release for an entry
// that does not have a positive in-use counter.
Release(K)
// Delete invalidates/removes an entry from the cache. Blocks
// until the in-user counter drops to 0.
//
// It is valid to call Delete on an entry that does not exist
// in the cache.
Delete(K)
// Flush does whatever it needs to in order to ensure that if
// the program exited right now, no one would be upset. Flush
// does not empty the cache.
Flush(context.Context)
}
// SourceFunc implements Source. Load calls the function, and Flush
// is a no-op.
type SourceFunc[K comparable, V any] func(context.Context, K, *V)
var _ Source[int, string] = SourceFunc[int, string](nil)
func (fn SourceFunc[K, V]) Load(ctx context.Context, k K, v *V) { fn(ctx, k, v) }
func (SourceFunc[K, V]) Flush(context.Context, *V) {}
|