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.
18
// negative zero is a good test because:
19
// 1) 0 and -0 are equal, yet have distinct representations.
20
// 2) 0 is represented as all zeros, -0 isn't.
21
// I'm not sure the language spec actually requires this behavior,
22
// but it's what the current map implementation does.
23
func TestNegativeZero(t *testing.T) {
24
m := make(map[float64]bool, 0)
27
m[math.Copysign(0.0, -1.0)] = true // should overwrite +0 entry
30
t.Error("length wrong")
34
if math.Copysign(1.0, k) > 0 {
39
m = make(map[float64]bool, 0)
40
m[math.Copysign(0.0, -1.0)] = true
41
m[+0.0] = true // should overwrite -0.0 entry
44
t.Error("length wrong")
48
if math.Copysign(1.0, k) < 0 {
54
// nan is a good test because nan != nan, and nan has
55
// a randomized hash value.
56
func TestNan(t *testing.T) {
57
m := make(map[float64]int, 0)
63
t.Error("length wrong")
68
t.Error("nan disappeared")
70
if (v & (v - 1)) != 0 {
71
t.Error("value wrong")
76
t.Error("values wrong")
80
// Maps aren't actually copied on assignment.
81
func TestAlias(t *testing.T) {
82
m := make(map[int]int, 0)
87
t.Error("alias didn't work")
91
func TestGrowWithNaN(t *testing.T) {
92
m := make(map[float64]int, 4)
100
for k, v := range m {
102
// force a hashtable resize
103
for i := 0; i < 100; i++ {
114
t.Error("NaN keys lost during grow")
117
t.Error("NaN values lost during grow")
121
type FloatInt struct {
126
func TestGrowWithNegativeZero(t *testing.T) {
127
negzero := math.Copysign(0.0, -1.0)
128
m := make(map[FloatInt]int, 4)
129
m[FloatInt{0.0, 0}] = 1
130
m[FloatInt{0.0, 1}] = 2
131
m[FloatInt{0.0, 2}] = 4
132
m[FloatInt{0.0, 3}] = 8
137
// The first iteration should return the +0 key.
138
// The subsequent iterations should return the -0 key.
139
// I'm not really sure this is required by the spec,
140
// but it makes sense.
141
// TODO: are we allowed to get the first entry returned again???
142
for k, v := range m {
145
} // ignore entries added to grow table
147
if math.Copysign(1.0, k.x) < 0 {
149
t.Error("key/value not updated together 1")
155
t.Error("key/value not updated together 2", k, v)
160
// force a hashtable resize
161
for i := 0; i < 100; i++ {
162
m[FloatInt{3.0, i}] = 0
164
// then change all the entries
166
m[FloatInt{negzero, 0}] = 1 | 16
167
m[FloatInt{negzero, 1}] = 2 | 16
168
m[FloatInt{negzero, 2}] = 4 | 16
169
m[FloatInt{negzero, 3}] = 8 | 16
174
t.Error("entry missing", s)
177
t.Error("wrong number of entries returned by iterator", cnt)
180
t.Error("update to negzero missed by iteration", negcnt)
184
func TestIterGrowAndDelete(t *testing.T) {
185
m := make(map[int]int, 4)
186
for i := 0; i < 100; i++ {
193
for i := 100; i < 1000; i++ {
196
// delete all odd keys
197
for i := 1; i < 1000; i += 2 {
203
t.Error("odd value returned")
209
// make sure old bucket arrays don't get GCd while
210
// an iterator is still using them.
211
func TestIterGrowWithGC(t *testing.T) {
212
m := make(map[int]int, 4)
213
for i := 0; i < 16; i++ {
220
bitmask |= 1 << uint(k)
224
for i := 100; i < 1000; i++ {
232
if bitmask != 1<<16-1 {
233
t.Error("missing key", bitmask)
237
func testConcurrentReadsAfterGrowth(t *testing.T, useReflect bool) {
238
if runtime.GOMAXPROCS(-1) == 1 {
239
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(16))
245
numLoop, numGrowStep = 2, 500
247
for i := 0; i < numLoop; i++ {
248
m := make(map[int]int, 0)
249
for gs := 0; gs < numGrowStep; gs++ {
251
var wg sync.WaitGroup
252
wg.Add(numReader * 2)
253
for nr := 0; nr < numReader; nr++ {
261
for key := 0; key < gs; key++ {
269
mv := reflect.ValueOf(m)
271
for _, k := range keys {
282
func TestConcurrentReadsAfterGrowth(t *testing.T) {
283
testConcurrentReadsAfterGrowth(t, false)
286
func TestConcurrentReadsAfterGrowthReflect(t *testing.T) {
287
testConcurrentReadsAfterGrowth(t, true)
290
func TestBigItems(t *testing.T) {
292
for i := 0; i < 256; i++ {
295
m := make(map[[256]string][256]string, 4)
296
for i := 0; i < 100; i++ {
297
key[37] = fmt.Sprintf("string%02d", i)
301
var values [100]string
303
for k, v := range m {
308
sort.Strings(keys[:])
309
sort.Strings(values[:])
310
for i := 0; i < 100; i++ {
311
if keys[i] != fmt.Sprintf("string%02d", i) {
312
t.Errorf("#%d: missing key: %v", i, keys[i])
314
if values[i] != fmt.Sprintf("string%02d", i) {
315
t.Errorf("#%d: missing value: %v", i, values[i])
323
func TestEmptyKeyAndValue(t *testing.T) {
324
a := make(map[int]empty, 4)
325
b := make(map[empty]int, 4)
326
c := make(map[empty]empty, 4)
333
t.Errorf("empty value insert problem")
336
t.Errorf("empty key returned wrong value")
340
// Tests a map with a single bucket, with same-lengthed short keys
341
// ("quick keys") as well as long keys.
342
func TestSingleBucketMapStringKeys_DupLen(t *testing.T) {
343
testMapLookups(t, map[string]string{
347
"bar": "barval", // same key length as "foo"
349
strings.Repeat("x", 128): "longval1",
350
strings.Repeat("y", 128): "longval2",
354
// Tests a map with a single bucket, with all keys having different lengths.
355
func TestSingleBucketMapStringKeys_NoDupLen(t *testing.T) {
356
testMapLookups(t, map[string]string{
363
strings.Repeat("x", 128): "longval",
367
func testMapLookups(t *testing.T, m map[string]string) {
368
for k, v := range m {
370
t.Fatalf("m[%q] = %q; want %q", k, m[k], v)