summaryrefslogtreecommitdiff
path: root/modCache.go
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2025-10-21 13:43:10 -0500
committerJeff Carr <[email protected]>2025-10-21 13:43:10 -0500
commitda341996abaf5ce4f113b586a01f8aede0edd672 (patch)
tree37585e60b061938f037589867043885482b0efdb /modCache.go
parent64b29a3807917b6203b85d8f7f99ff622b947784 (diff)
sample code
Diffstat (limited to 'modCache.go')
-rw-r--r--modCache.go58
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
+}