diff options
| author | Jeff Carr <[email protected]> | 2025-10-21 13:43:10 -0500 |
|---|---|---|
| committer | Jeff Carr <[email protected]> | 2025-10-21 13:43:10 -0500 |
| commit | da341996abaf5ce4f113b586a01f8aede0edd672 (patch) | |
| tree | 37585e60b061938f037589867043885482b0efdb /modCache.go | |
| parent | 64b29a3807917b6203b85d8f7f99ff622b947784 (diff) | |
sample code
Diffstat (limited to 'modCache.go')
| -rw-r--r-- | modCache.go | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/modCache.go b/modCache.go new file mode 100644 index 0000000..d02e046 --- /dev/null +++ b/modCache.go @@ -0,0 +1,58 @@ +// I put this here to look at and think about +// from mod/sumdb/cache.go + +// Parallel cache. +// This file is copied from cmd/go/internal/par. + +package ENV + +import ( + "sync" + "sync/atomic" +) + +// parCache runs an action once per key and caches the result. +type parCache struct { + m sync.Map +} + +type cacheEntry struct { + done uint32 + mu sync.Mutex + result interface{} +} + +// Do calls the function f if and only if Do is being called for the first time with this key. +// No call to Do with a given key returns until the one call to f returns. +// Do returns the value returned by the one call to f. +func (c *parCache) Do(key interface{}, f func() interface{}) interface{} { + entryIface, ok := c.m.Load(key) + if !ok { + entryIface, _ = c.m.LoadOrStore(key, new(cacheEntry)) + } + e := entryIface.(*cacheEntry) + if atomic.LoadUint32(&e.done) == 0 { + e.mu.Lock() + if atomic.LoadUint32(&e.done) == 0 { + e.result = f() + atomic.StoreUint32(&e.done, 1) + } + e.mu.Unlock() + } + return e.result +} + +// Get returns the cached result associated with key. +// It returns nil if there is no such result. +// If the result for key is being computed, Get does not wait for the computation to finish. +func (c *parCache) Get(key interface{}) interface{} { + entryIface, ok := c.m.Load(key) + if !ok { + return nil + } + e := entryIface.(*cacheEntry) + if atomic.LoadUint32(&e.done) == 0 { + return nil + } + return e.result +} |
