From 39a0df98f6ec82357b130d26433220ad7f13d7b0 Mon Sep 17 00:00:00 2001 From: Matt Baer Date: Sun, 11 Jun 2017 13:46:59 -0400 Subject: [PATCH] Add memoization module --- memo/memo.go | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 memo/memo.go diff --git a/memo/memo.go b/memo/memo.go new file mode 100644 index 0000000..8592b17 --- /dev/null +++ b/memo/memo.go @@ -0,0 +1,56 @@ +package memo + +import ( + "sync" +) + +type ( + Memo struct { + f Func + mu sync.Mutex //guards cache + cache *entry + } + + Func func() (interface{}, error) +) + +type ( + entry struct { + res result + ready chan struct{} // close when res is read + } + + result struct { + value interface{} + err error + } +) + +func New(f Func) *Memo { + return &Memo{ + f: f, + } +} + +func (memo *Memo) Invalidate() { + memo.mu.Lock() + memo.cache = nil + memo.mu.Unlock() +} + +func (memo *Memo) Get() (value interface{}, err error) { + memo.mu.Lock() + if memo.cache == nil { + memo.cache = &entry{ready: make(chan struct{})} + memo.mu.Unlock() + + memo.cache.res.value, memo.cache.res.err = memo.f() + + close(memo.cache.ready) + } else { + memo.mu.Unlock() + + <-memo.cache.ready + } + return memo.cache.res.value, memo.cache.res.err +}