Source file test/stress/maps.go

     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  }
   114  

View as plain text