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.
19 opLoad
= mapOp("Load")
20 opStore
= mapOp("Store")
21 opLoadOrStore
= mapOp("LoadOrStore")
22 opDelete
= mapOp("Delete")
25 var mapOps
= [...]mapOp
{opLoad
, opStore
, opLoadOrStore
, opDelete
}
27 // mapCall is a quick.Generator for calls on mapInterface.
33 func (c mapCall
) apply(m mapInterface
) (interface{}, bool) {
41 return m
.LoadOrStore(c
.k
, c
.v
)
46 panic("invalid mapOp")
50 type mapResult
struct {
55 func randValue(r
*rand
.Rand
) interface{} {
56 b
:= make([]byte, r
.Intn(4))
58 b
[i
] = 'a' + byte(rand
.Intn(26))
63 func (mapCall
) Generate(r
*rand
.Rand
, size
int) reflect
.Value
{
64 c
:= mapCall
{op
: mapOps
[rand
.Intn(len(mapOps
))], k
: randValue(r
)}
66 case opStore
, opLoadOrStore
:
69 return reflect
.ValueOf(c
)
72 func applyCalls(m mapInterface
, calls
[]mapCall
) (results
[]mapResult
, final
map[interface{}]interface{}) {
73 for _
, c
:= range calls
{
75 results
= append(results
, mapResult
{v
, ok
})
78 final
= make(map[interface{}]interface{})
79 m
.Range(func(k
, v
interface{}) bool {
87 func applyMap(calls
[]mapCall
) ([]mapResult
, map[interface{}]interface{}) {
88 return applyCalls(new(sync
.Map
), calls
)
91 func applyRWMutexMap(calls
[]mapCall
) ([]mapResult
, map[interface{}]interface{}) {
92 return applyCalls(new(RWMutexMap
), calls
)
95 func applyDeepCopyMap(calls
[]mapCall
) ([]mapResult
, map[interface{}]interface{}) {
96 return applyCalls(new(DeepCopyMap
), calls
)
99 func TestMapMatchesRWMutex(t
*testing
.T
) {
100 if err
:= quick
.CheckEqual(applyMap
, applyRWMutexMap
, nil); err
!= nil {
105 func TestMapMatchesDeepCopy(t
*testing
.T
) {
106 if err
:= quick
.CheckEqual(applyMap
, applyDeepCopyMap
, nil); err
!= nil {
111 func TestConcurrentRange(t
*testing
.T
) {
112 const mapSize
= 1 << 10
115 for n
:= int64(1); n
<= mapSize
; n
++ {
119 done
:= make(chan struct{})
120 var wg sync
.WaitGroup
125 for g
:= int64(runtime
.GOMAXPROCS(0)); g
> 0; g
-- {
126 r
:= rand
.New(rand
.NewSource(g
))
130 for i
:= int64(0); ; i
++ {
136 for n
:= int64(1); n
< mapSize
; n
++ {
137 if r
.Int63n(mapSize
) == 0 {
151 for n
:= iters
; n
> 0; n
-- {
152 seen
:= make(map[int64]bool, mapSize
)
154 m
.Range(func(ki
, vi
interface{}) bool {
155 k
, v
:= ki
.(int64), vi
.(int64)
157 t
.Fatalf("while Storing multiples of %v, Range saw value %v", k
, v
)
160 t
.Fatalf("Range visited key %v twice", k
)
166 if len(seen
) != mapSize
{
167 t
.Fatalf("Range visited %v elements of %v-element Map", len(seen
), mapSize
)