Last active
December 10, 2017 11:42
-
-
Save kamal-github/02c1cb4b6e19dbadf8993b01d1277bef to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Func is the type of the function to memoize. | |
type Func func(key string) (interface{}, error) | |
type result struct { | |
value interface{} | |
err error | |
} | |
type entry struct { | |
res result | |
ready chan struct{} // closed when res is ready | |
} | |
func New(f Func) *Memo { | |
return &Memo{f: f, cache: make(map[string]*entry)} | |
} | |
type Memo struct { | |
f Func | |
mu sync.Mutex // guards cache | |
cache map[string]*entry | |
} | |
func (memo *Memo) Get(key string) (value interface{}, err error) { | |
memo.mu.Lock() | |
e := memo.cache[key] | |
if e == nil { | |
// This is the first request for this key. | |
// This goroutine becomes responsible for computing | |
// the value and broadcasting the ready condition. | |
e = &entry{ready: make(chan struct{})} | |
memo.cache[key] = e | |
memo.mu.Unlock() | |
e.res.value, e.res.err = memo.f(key) | |
close(e.ready) // broadcast ready condition | |
} else { | |
// This is a repeat request for this key. | |
memo.mu.Unlock() | |
<-e.ready // wait for ready condition | |
} | |
return e.res.value, e.res.err | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment