1 // Copyright 2016 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.
12 // This file contains reference map implementations for unit-tests.
14 // mapInterface is the interface Map implements.
15 type mapInterface
interface {
18 LoadOrStore(key
, value any
) (actual any
, loaded
bool)
19 LoadAndDelete(key any
) (value any
, loaded
bool)
21 Range(func(key
, value any
) (shouldContinue
bool))
24 // RWMutexMap is an implementation of mapInterface using a sync.RWMutex.
25 type RWMutexMap
struct {
30 func (m
*RWMutexMap
) Load(key any
) (value any
, ok
bool) {
32 value
, ok
= m
.dirty
[key
]
37 func (m
*RWMutexMap
) Store(key
, value any
) {
40 m
.dirty
= make(map[any
]any
)
46 func (m
*RWMutexMap
) LoadOrStore(key
, value any
) (actual any
, loaded
bool) {
48 actual
, loaded
= m
.dirty
[key
]
52 m
.dirty
= make(map[any
]any
)
60 func (m
*RWMutexMap
) LoadAndDelete(key any
) (value any
, loaded
bool) {
62 value
, loaded
= m
.dirty
[key
]
72 func (m
*RWMutexMap
) Delete(key any
) {
78 func (m
*RWMutexMap
) Range(f
func(key
, value any
) (shouldContinue
bool)) {
80 keys
:= make([]any
, 0, len(m
.dirty
))
81 for k
:= range m
.dirty
{
82 keys
= append(keys
, k
)
86 for _
, k
:= range keys
{
97 // DeepCopyMap is an implementation of mapInterface using a Mutex and
98 // atomic.Value. It makes deep copies of the map on every write to avoid
99 // acquiring the Mutex in Load.
100 type DeepCopyMap
struct {
105 func (m
*DeepCopyMap
) Load(key any
) (value any
, ok
bool) {
106 clean
, _
:= m
.clean
.Load().(map[any
]any
)
107 value
, ok
= clean
[key
]
111 func (m
*DeepCopyMap
) Store(key
, value any
) {
119 func (m
*DeepCopyMap
) LoadOrStore(key
, value any
) (actual any
, loaded
bool) {
120 clean
, _
:= m
.clean
.Load().(map[any
]any
)
121 actual
, loaded
= clean
[key
]
123 return actual
, loaded
127 // Reload clean in case it changed while we were waiting on m.mu.
128 clean
, _
= m
.clean
.Load().(map[any
]any
)
129 actual
, loaded
= clean
[key
]
137 return actual
, loaded
140 func (m
*DeepCopyMap
) LoadAndDelete(key any
) (value any
, loaded
bool) {
143 value
, loaded
= dirty
[key
]
150 func (m
*DeepCopyMap
) Delete(key any
) {
158 func (m
*DeepCopyMap
) Range(f
func(key
, value any
) (shouldContinue
bool)) {
159 clean
, _
:= m
.clean
.Load().(map[any
]any
)
160 for k
, v
:= range clean
{
167 func (m
*DeepCopyMap
) dirty() map[any
]any
{
168 clean
, _
:= m
.clean
.Load().(map[any
]any
)
169 dirty
:= make(map[any
]any
, len(clean
)+1)
170 for k
, v
:= range clean
{