summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cache.go58
-rw-r--r--init.go4
-rw-r--r--structs.go6
3 files changed, 68 insertions, 0 deletions
diff --git a/cache.go b/cache.go
new file mode 100644
index 0000000..c139306
--- /dev/null
+++ b/cache.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 forgepb
+
+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
+}
diff --git a/init.go b/init.go
index 0f400f8..874439c 100644
--- a/init.go
+++ b/init.go
@@ -24,6 +24,10 @@ func init() {
func Init() *Forge {
f := new(Forge)
+
+ // cache.go has Do()
+ // f.initOnce.Do(f.initWork)
+
f.Config = new(ForgeConfigs)
// load the ~/.config/forge/ config
diff --git a/structs.go b/structs.go
index 05ed89e..34550b5 100644
--- a/structs.go
+++ b/structs.go
@@ -1,12 +1,18 @@
package forgepb
import (
+ sync "sync"
+
"go.wit.com/lib/protobuf/gitpb"
"go.wit.com/lib/protobuf/zoopb"
)
// maybe an interface someday?
type Forge struct {
+ // one-time initialized data
+ initOnce sync.Once
+ initErr error // init error, if any
+
goSrc string // the path to go/src
Config *ForgeConfigs // config repos for readonly, private, etc
Repos *gitpb.Repos