Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / mod@v0.3.0 / sumdb / cache.go
1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // Parallel cache.
6 // This file is copied from cmd/go/internal/par.
7
8 package sumdb
9
10 import (
11         "sync"
12         "sync/atomic"
13 )
14
15 // parCache runs an action once per key and caches the result.
16 type parCache struct {
17         m sync.Map
18 }
19
20 type cacheEntry struct {
21         done   uint32
22         mu     sync.Mutex
23         result interface{}
24 }
25
26 // Do calls the function f if and only if Do is being called for the first time with this key.
27 // No call to Do with a given key returns until the one call to f returns.
28 // Do returns the value returned by the one call to f.
29 func (c *parCache) Do(key interface{}, f func() interface{}) interface{} {
30         entryIface, ok := c.m.Load(key)
31         if !ok {
32                 entryIface, _ = c.m.LoadOrStore(key, new(cacheEntry))
33         }
34         e := entryIface.(*cacheEntry)
35         if atomic.LoadUint32(&e.done) == 0 {
36                 e.mu.Lock()
37                 if atomic.LoadUint32(&e.done) == 0 {
38                         e.result = f()
39                         atomic.StoreUint32(&e.done, 1)
40                 }
41                 e.mu.Unlock()
42         }
43         return e.result
44 }
45
46 // Get returns the cached result associated with key.
47 // It returns nil if there is no such result.
48 // If the result for key is being computed, Get does not wait for the computation to finish.
49 func (c *parCache) Get(key interface{}) interface{} {
50         entryIface, ok := c.m.Load(key)
51         if !ok {
52                 return nil
53         }
54         e := entryIface.(*cacheEntry)
55         if atomic.LoadUint32(&e.done) == 0 {
56                 return nil
57         }
58         return e.result
59 }