-
-
Save arehmandev/57c8d6fd25723275882693c0815bea01 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
type Func func(key string) (interface{}, error) | |
type result struct { | |
value interface{} | |
err error | |
} | |
type entry struct { | |
res result | |
ready chan struct{} | |
} | |
type request struct { | |
key string | |
response chan<- result | |
} | |
type Memo struct { | |
requests chan request | |
} | |
func New(f Func) *Memo { | |
memo := &Memo{ | |
requests: make(chan request), | |
} | |
go memo.server(f) | |
return memo | |
} | |
func (memo *Memo) Get(key string) (interface{}, error) { | |
response := make(chan result) | |
memo.requests <- request{key, response} | |
res := <-response | |
return res.value, res.err | |
} | |
func (memo *Memo) Close() { | |
close(memo.requests) | |
} | |
func (memo *Memo) server(f Func) { | |
cache := make(map[string]*entry) | |
for req := range memo.requests { | |
e := cache[req.key] | |
if e == nil { | |
e = &entry{ | |
ready: make(chan struct{}), | |
} | |
cache[req.key] = e | |
go e.call(f, req.value) | |
} | |
go e.deliver(req.response) | |
} | |
} | |
func (e *entry) call(f Func, key string) { | |
e.res.value, e.res.err = f(key) | |
close(e.ready) | |
} | |
func (e *entry) deliver(response chan<- result) { | |
<-e.ready | |
response <- e.res | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment