Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / sync@v0.0.0-20200625203802-6e8e738ad208 / syncmap / map_reference_test.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/sync@v0.0.0-20200625203802-6e8e738ad208/syncmap/map_reference_test.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/sync@v0.0.0-20200625203802-6e8e738ad208/syncmap/map_reference_test.go
new file mode 100644 (file)
index 0000000..923c51b
--- /dev/null
@@ -0,0 +1,151 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syncmap_test
+
+import (
+       "sync"
+       "sync/atomic"
+)
+
+// This file contains reference map implementations for unit-tests.
+
+// mapInterface is the interface Map implements.
+type mapInterface interface {
+       Load(interface{}) (interface{}, bool)
+       Store(key, value interface{})
+       LoadOrStore(key, value interface{}) (actual interface{}, loaded bool)
+       Delete(interface{})
+       Range(func(key, value interface{}) (shouldContinue bool))
+}
+
+// RWMutexMap is an implementation of mapInterface using a sync.RWMutex.
+type RWMutexMap struct {
+       mu    sync.RWMutex
+       dirty map[interface{}]interface{}
+}
+
+func (m *RWMutexMap) Load(key interface{}) (value interface{}, ok bool) {
+       m.mu.RLock()
+       value, ok = m.dirty[key]
+       m.mu.RUnlock()
+       return
+}
+
+func (m *RWMutexMap) Store(key, value interface{}) {
+       m.mu.Lock()
+       if m.dirty == nil {
+               m.dirty = make(map[interface{}]interface{})
+       }
+       m.dirty[key] = value
+       m.mu.Unlock()
+}
+
+func (m *RWMutexMap) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) {
+       m.mu.Lock()
+       actual, loaded = m.dirty[key]
+       if !loaded {
+               actual = value
+               if m.dirty == nil {
+                       m.dirty = make(map[interface{}]interface{})
+               }
+               m.dirty[key] = value
+       }
+       m.mu.Unlock()
+       return actual, loaded
+}
+
+func (m *RWMutexMap) Delete(key interface{}) {
+       m.mu.Lock()
+       delete(m.dirty, key)
+       m.mu.Unlock()
+}
+
+func (m *RWMutexMap) Range(f func(key, value interface{}) (shouldContinue bool)) {
+       m.mu.RLock()
+       keys := make([]interface{}, 0, len(m.dirty))
+       for k := range m.dirty {
+               keys = append(keys, k)
+       }
+       m.mu.RUnlock()
+
+       for _, k := range keys {
+               v, ok := m.Load(k)
+               if !ok {
+                       continue
+               }
+               if !f(k, v) {
+                       break
+               }
+       }
+}
+
+// DeepCopyMap is an implementation of mapInterface using a Mutex and
+// atomic.Value.  It makes deep copies of the map on every write to avoid
+// acquiring the Mutex in Load.
+type DeepCopyMap struct {
+       mu    sync.Mutex
+       clean atomic.Value
+}
+
+func (m *DeepCopyMap) Load(key interface{}) (value interface{}, ok bool) {
+       clean, _ := m.clean.Load().(map[interface{}]interface{})
+       value, ok = clean[key]
+       return value, ok
+}
+
+func (m *DeepCopyMap) Store(key, value interface{}) {
+       m.mu.Lock()
+       dirty := m.dirty()
+       dirty[key] = value
+       m.clean.Store(dirty)
+       m.mu.Unlock()
+}
+
+func (m *DeepCopyMap) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) {
+       clean, _ := m.clean.Load().(map[interface{}]interface{})
+       actual, loaded = clean[key]
+       if loaded {
+               return actual, loaded
+       }
+
+       m.mu.Lock()
+       // Reload clean in case it changed while we were waiting on m.mu.
+       clean, _ = m.clean.Load().(map[interface{}]interface{})
+       actual, loaded = clean[key]
+       if !loaded {
+               dirty := m.dirty()
+               dirty[key] = value
+               actual = value
+               m.clean.Store(dirty)
+       }
+       m.mu.Unlock()
+       return actual, loaded
+}
+
+func (m *DeepCopyMap) Delete(key interface{}) {
+       m.mu.Lock()
+       dirty := m.dirty()
+       delete(dirty, key)
+       m.clean.Store(dirty)
+       m.mu.Unlock()
+}
+
+func (m *DeepCopyMap) Range(f func(key, value interface{}) (shouldContinue bool)) {
+       clean, _ := m.clean.Load().(map[interface{}]interface{})
+       for k, v := range clean {
+               if !f(k, v) {
+                       break
+               }
+       }
+}
+
+func (m *DeepCopyMap) dirty() map[interface{}]interface{} {
+       clean, _ := m.clean.Load().(map[interface{}]interface{})
+       dirty := make(map[interface{}]interface{}, len(clean)+1)
+       for k, v := range clean {
+               dirty[k] = v
+       }
+       return dirty
+}