github.com/dannin/go@v0.0.0-20161031215817-d35dfd405eaa/test/stress/maps.go (about) 1 // Copyright 2013 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 package main 6 7 import ( 8 "math/rand" 9 "runtime" 10 "sync" 11 ) 12 13 func mapTypes() []MapType { 14 // TODO(bradfitz): bunch more map types of all different key and value types. 15 // Use reflect.MapOf and a program to generate lots of types & struct types. 16 // For now, just one: 17 return []MapType{intMapType{}} 18 } 19 20 type MapType interface { 21 NewMap() Map 22 } 23 24 type Map interface { 25 AddItem() 26 DelItem() 27 Len() int 28 GetItem() 29 RangeAll() 30 } 31 32 func stressMapType(mt MapType, done func()) { 33 defer done() 34 m := mt.NewMap() 35 for m.Len() < 10000 { 36 Println("map at ", m.Len()) 37 if m.Len()%100 == 0 { 38 runtime.Gosched() 39 } 40 m.AddItem() 41 m.AddItem() 42 m.DelItem() 43 var wg sync.WaitGroup 44 const numGets = 10 45 wg.Add(numGets) 46 for i := 0; i < numGets; i++ { 47 go func(i int) { 48 if i&1 == 0 { 49 m.GetItem() 50 } else { 51 m.RangeAll() 52 } 53 wg.Done() 54 }(i) 55 } 56 wg.Wait() 57 } 58 for m.Len() > 0 { 59 m.DelItem() 60 } 61 } 62 63 type intMapType struct{} 64 65 func (intMapType) NewMap() Map { 66 return make(intMap) 67 } 68 69 var deadcafe = []byte("\xDE\xAD\xCA\xFE") 70 71 type intMap map[int][]byte 72 73 func (m intMap) AddItem() { 74 s0 := len(m) 75 for len(m) == s0 { 76 key := rand.Intn(s0 + 1) 77 m[key] = make([]byte, rand.Intn(64<<10)) 78 } 79 } 80 81 func (m intMap) DelItem() { 82 for k := range m { 83 delete(m, k) 84 return 85 } 86 } 87 88 func (m intMap) GetItem() { 89 key := rand.Intn(len(m)) 90 if s, ok := m[key]; ok { 91 copy(s, deadcafe) 92 } 93 } 94 95 func (m intMap) Len() int { return len(m) } 96 97 func (m intMap) RangeAll() { 98 for _ = range m { 99 } 100 for range m { 101 } 102 } 103 104 func stressMaps() { 105 for { 106 var wg sync.WaitGroup 107 for _, mt := range mapTypes() { 108 wg.Add(1) 109 go stressMapType(mt, wg.Done) 110 } 111 wg.Wait() 112 } 113 }