-
Notifications
You must be signed in to change notification settings - Fork 1
/
memoize_with_cache_err.go
48 lines (37 loc) · 1.04 KB
/
memoize_with_cache_err.go
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
package memoize
import (
"sync"
"github.com/emad-elsaid/memoize/cache"
)
// Pair is a tuple of value of type T and an error
type Pair[T any] struct {
V T
Err error
}
type MemoizerWithCacheErr[In any, Out any] struct {
inFlight cache.Cache[In, *sync.Mutex]
Cache cache.Cacher[In, Pair[Out]]
Fun func(In) (Out, error)
}
// Do calls the memoized function with input i and memoize the result and return it
func (m *MemoizerWithCacheErr[In, Out]) Do(i In) (Out, error) {
inFlight, _ := m.inFlight.LoadOrStore(i, new(sync.Mutex))
inFlight.Lock()
val, ok := m.Cache.Load(i)
if !ok {
v, err := m.Fun(i)
val = Pair[Out]{V: v, Err: err}
m.Cache.Store(i, val)
}
inFlight.Unlock()
m.inFlight.Delete(i)
return val.V, val.Err
}
// NewWithCacheErr creates a new MemoizerWithCacheErr that wraps fun and uses the c Cacher. and returns the Do function.
func NewWithCacheErr[In, Out any](c cache.Cacher[In, Pair[Out]], fun func(In) (Out, error)) func(In) (Out, error) {
m := MemoizerWithCacheErr[In, Out]{
Cache: c,
Fun: fun,
}
return m.Do
}