3 // Copyright 2009 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
7 // Test maps, almost exhaustively.
20 func P(a []string) string {
22 for i := 0; i < len(a); i++ {
39 // Test a map literal.
40 mlit := map[string]int{"0": 0, "1": 1, "2": 2, "3": 3, "4": 4}
41 for i := 0; i < len(mlit); i++ {
42 s := string([]byte{byte(i) + '0'})
44 fmt.Printf("mlit[%s] = %d\n", s, mlit[s])
48 mib := make(map[int]bool)
49 mii := make(map[int]int)
50 mfi := make(map[float32]int)
51 mif := make(map[int]float32)
52 msi := make(map[string]int)
53 mis := make(map[int]string)
54 mss := make(map[string]string)
55 mspa := make(map[string][]string)
56 // BUG need an interface map both ways too
59 i int64 // can't use string here; struct values are only compared at the top level
62 mipT := make(map[int]*T)
63 mpTi := make(map[*T]int)
64 mit := make(map[int]T)
65 // mti := make(map[T] int)
68 mipM := make(map[int]M)
72 for i := 0; i < count; i++ {
74 s10 := strconv.Itoa(i * 10)
80 apT[2*i] = new(T) // need twice as many entries as we use, for the nonexistence check
86 mfi[float32(i)] = 10 * i
92 as := make([]string, 2)
104 if len(mib) != count {
105 fmt.Printf("len(mib) = %d\n", len(mib))
107 if len(mii) != count {
108 fmt.Printf("len(mii) = %d\n", len(mii))
110 if len(mfi) != count {
111 fmt.Printf("len(mfi) = %d\n", len(mfi))
113 if len(mif) != count {
114 fmt.Printf("len(mif) = %d\n", len(mif))
116 if len(msi) != count {
117 fmt.Printf("len(msi) = %d\n", len(msi))
119 if len(mis) != count {
120 fmt.Printf("len(mis) = %d\n", len(mis))
122 if len(mss) != count {
123 fmt.Printf("len(mss) = %d\n", len(mss))
125 if len(mspa) != count {
126 fmt.Printf("len(mspa) = %d\n", len(mspa))
128 if len(mipT) != count {
129 fmt.Printf("len(mipT) = %d\n", len(mipT))
131 if len(mpTi) != count {
132 fmt.Printf("len(mpTi) = %d\n", len(mpTi))
134 // if len(mti) != count {
135 // fmt.Printf("len(mti) = %d\n", len(mti))
137 if len(mipM) != count {
138 fmt.Printf("len(mipM) = %d\n", len(mipM))
140 // if len(mti) != count {
141 // fmt.Printf("len(mti) = %d\n", len(mti))
143 if len(mit) != count {
144 fmt.Printf("len(mit) = %d\n", len(mit))
147 // test construction directly
148 for i := 0; i < count; i++ {
150 s10 := strconv.Itoa(i * 10)
152 // BUG m := M(i, i+1)
153 if mib[i] != (i != 0) {
154 fmt.Printf("mib[%d] = %t\n", i, mib[i])
157 fmt.Printf("mii[%d] = %d\n", i, mii[i])
160 fmt.Printf("mfi[%d] = %d\n", i, mfi[f])
162 if mif[i] != 10.0*f {
163 fmt.Printf("mif[%d] = %g\n", i, mif[i])
166 fmt.Printf("mis[%d] = %s\n", i, mis[i])
169 fmt.Printf("msi[%s] = %d\n", s, msi[s])
172 fmt.Printf("mss[%s] = %g\n", s, mss[s])
174 for j := 0; j < len(mspa[s]); j++ {
175 if mspa[s][j] != s10 {
176 fmt.Printf("mspa[%s][%d] = %s\n", s, j, mspa[s][j])
179 if mipT[i].i != int64(i) || mipT[i].f != f {
180 fmt.Printf("mipT[%d] = %v\n", i, mipT[i])
182 if mpTi[apT[i]] != i {
183 fmt.Printf("mpTi[apT[%d]] = %d\n", i, mpTi[apT[i]])
186 // fmt.Printf("mti[%s] = %s\n", s, mti[t])
188 if mipM[i][i] != i+1 {
189 fmt.Printf("mipM[%d][%d] = %d\n", i, i, mipM[i][i])
192 // fmt.Printf("mti[%v] = %d\n", t, mti[t])
194 if mit[i].i != int64(i) || mit[i].f != f {
195 fmt.Printf("mit[%d] = {%d %g}\n", i, mit[i].i, mit[i].f)
199 // test existence with tuple check
200 // failed lookups yield a false value for the boolean.
201 for i := 0; i < count; i++ {
207 fmt.Printf("tuple existence decl: mib[%d]\n", i)
211 fmt.Printf("tuple existence assign: mib[%d]\n", i)
217 fmt.Printf("tuple existence decl: mii[%d]\n", i)
221 fmt.Printf("tuple existence assign: mii[%d]\n", i)
227 fmt.Printf("tuple existence decl: mfi[%d]\n", i)
231 fmt.Printf("tuple existence assign: mfi[%d]\n", i)
237 fmt.Printf("tuple existence decl: mif[%d]\n", i)
241 fmt.Printf("tuple existence assign: mif[%d]\n", i)
247 fmt.Printf("tuple existence decl: mis[%d]\n", i)
251 fmt.Printf("tuple existence assign: mis[%d]\n", i)
257 fmt.Printf("tuple existence decl: msi[%d]\n", i)
261 fmt.Printf("tuple existence assign: msi[%d]\n", i)
267 fmt.Printf("tuple existence decl: mss[%d]\n", i)
271 fmt.Printf("tuple existence assign: mss[%d]\n", i)
277 fmt.Printf("tuple existence decl: mspa[%d]\n", i)
281 fmt.Printf("tuple existence assign: mspa[%d]\n", i)
287 fmt.Printf("tuple existence decl: mipT[%d]\n", i)
291 fmt.Printf("tuple existence assign: mipT[%d]\n", i)
297 fmt.Printf("tuple existence decl: mpTi[apT[%d]]\n", i)
301 fmt.Printf("tuple existence assign: mpTi[apT[%d]]\n", i)
307 fmt.Printf("tuple existence decl: mipM[%d]\n", i)
311 fmt.Printf("tuple existence assign: mipM[%d]\n", i)
317 fmt.Printf("tuple existence decl: mit[%d]\n", i)
321 fmt.Printf("tuple existence assign: mit[%d]\n", i)
327 // fmt.Printf("tuple existence decl: mti[%d]\n", i)
331 // fmt.Printf("tuple existence assign: mti[%d]\n", i)
336 // test nonexistence with tuple check
337 // failed lookups yield a false value for the boolean.
338 for i := count; i < 2*count; i++ {
344 fmt.Printf("tuple nonexistence decl: mib[%d]", i)
348 fmt.Printf("tuple nonexistence assign: mib[%d]", i)
354 fmt.Printf("tuple nonexistence decl: mii[%d]", i)
358 fmt.Printf("tuple nonexistence assign: mii[%d]", i)
364 fmt.Printf("tuple nonexistence decl: mfi[%d]", i)
368 fmt.Printf("tuple nonexistence assign: mfi[%d]", i)
374 fmt.Printf("tuple nonexistence decl: mif[%d]", i)
378 fmt.Printf("tuple nonexistence assign: mif[%d]", i)
384 fmt.Printf("tuple nonexistence decl: mis[%d]", i)
388 fmt.Printf("tuple nonexistence assign: mis[%d]", i)
394 fmt.Printf("tuple nonexistence decl: msi[%d]", i)
398 fmt.Printf("tuple nonexistence assign: msi[%d]", i)
404 fmt.Printf("tuple nonexistence decl: mss[%d]", i)
408 fmt.Printf("tuple nonexistence assign: mss[%d]", i)
414 fmt.Printf("tuple nonexistence decl: mspa[%d]", i)
418 fmt.Printf("tuple nonexistence assign: mspa[%d]", i)
424 fmt.Printf("tuple nonexistence decl: mipT[%d]", i)
428 fmt.Printf("tuple nonexistence assign: mipT[%d]", i)
434 fmt.Printf("tuple nonexistence decl: mpTi[apt[%d]]", i)
438 fmt.Printf("tuple nonexistence assign: mpTi[apT[%d]]", i)
444 fmt.Printf("tuple nonexistence decl: mipM[%d]", i)
448 fmt.Printf("tuple nonexistence assign: mipM[%d]", i)
454 // fmt.Printf("tuple nonexistence decl: mti[%d]", i)
458 // fmt.Printf("tuple nonexistence assign: mti[%d]", i)
464 fmt.Printf("tuple nonexistence decl: mit[%d]", i)
468 fmt.Printf("tuple nonexistence assign: mit[%d]", i)
473 // tests for structured map element updates
474 for i := 0; i < count; i++ {
476 mspa[s][i%2] = "deleted"
477 if mspa[s][i%2] != "deleted" {
478 fmt.Printf("update mspa[%s][%d] = %s\n", s, i%2, mspa[s][i%2])
482 if mipT[i].i != int64(i)+1 {
483 fmt.Printf("update mipT[%d].i = %d\n", i, mipT[i].i)
485 mipT[i].f = float32(i + 1)
486 if mipT[i].f != float32(i+1) {
487 fmt.Printf("update mipT[%d].f = %g\n", i, mipT[i].f)
491 if mipM[i][i] != (i+1)+1 {
492 fmt.Printf("update mipM[%d][%d] = %d\n", i, i, mipM[i][i])
496 // test range on nil map
497 var mnil map[string]int
498 for _, _ = range mnil {
504 // Test floating point numbers in maps.
505 // Two map keys refer to the same entry if the keys are ==.
506 // The special cases, then, are that +0 == -0 and that NaN != NaN.
511 nz = math.Float32frombits(1 << 31)
512 nana = float32(math.NaN())
513 nanb = math.Float32frombits(math.Float32bits(nana) ^ 2)
516 m := map[float32]string{
522 fmt.Println("float32 map cannot read back m[+0]:", m[pz])
525 fmt.Println("float32 map does not treat", pz, "and", nz, "as equal for read")
526 fmt.Println("float32 map does not treat -0 and +0 as equal for read")
530 fmt.Println("float32 map does not treat -0 and +0 as equal for write")
532 if _, ok := m[nana]; ok {
533 fmt.Println("float32 map allows NaN lookup (a)")
535 if _, ok := m[nanb]; ok {
536 fmt.Println("float32 map allows NaN lookup (b)")
539 fmt.Println("float32 map should have 3 entries:", m)
544 fmt.Println("float32 map should have 5 entries:", m)
551 nz = math.Float64frombits(1 << 63)
552 nana = float64(math.NaN())
553 nanb = math.Float64frombits(math.Float64bits(nana) ^ 2)
556 m := map[float64]string{
562 fmt.Println("float64 map does not treat -0 and +0 as equal for read")
566 fmt.Println("float64 map does not treat -0 and +0 as equal for write")
568 if _, ok := m[nana]; ok {
569 fmt.Println("float64 map allows NaN lookup (a)")
571 if _, ok := m[nanb]; ok {
572 fmt.Println("float64 map allows NaN lookup (b)")
575 fmt.Println("float64 map should have 3 entries:", m)
580 fmt.Println("float64 map should have 5 entries:", m)
587 nz = complex(0, math.Float32frombits(1<<31))
588 nana = complex(5, float32(math.NaN()))
589 nanb = complex(5, math.Float32frombits(math.Float32bits(float32(math.NaN()))^2))
592 m := map[complex64]string{
598 fmt.Println("complex64 map does not treat -0 and +0 as equal for read")
602 fmt.Println("complex64 map does not treat -0 and +0 as equal for write")
604 if _, ok := m[nana]; ok {
605 fmt.Println("complex64 map allows NaN lookup (a)")
607 if _, ok := m[nanb]; ok {
608 fmt.Println("complex64 map allows NaN lookup (b)")
611 fmt.Println("complex64 map should have 3 entries:", m)
616 fmt.Println("complex64 map should have 5 entries:", m)
623 nz = complex(0, math.Float64frombits(1<<63))
624 nana = complex(5, float64(math.NaN()))
625 nanb = complex(5, math.Float64frombits(math.Float64bits(float64(math.NaN()))^2))
628 m := map[complex128]string{
634 fmt.Println("complex128 map does not treat -0 and +0 as equal for read")
638 fmt.Println("complex128 map does not treat -0 and +0 as equal for write")
640 if _, ok := m[nana]; ok {
641 fmt.Println("complex128 map allows NaN lookup (a)")
643 if _, ok := m[nanb]; ok {
644 fmt.Println("complex128 map allows NaN lookup (b)")
647 fmt.Println("complex128 map should have 3 entries:", m)
652 fmt.Println("complex128 map should have 5 entries:", m)
658 // Test that NaNs in maps don't go quadratic.
659 t := func(n int) time.Duration {
661 m := map[float64]int{}
663 for i := 0; i < n; i++ {
667 panic("wrong size map after nan insertion")
669 return time.Since(t0)
672 // Depending on the machine and OS, this test might be too fast
673 // to measure with accurate enough granularity. On failure,
674 // make it run longer, hoping that the timing granularity
675 // is eventually sufficient.
677 n := 30000 // 0.02 seconds on a MacBook Air
682 // should be 2x (linear); allow up to 3x
688 fmt.Printf("too slow: %d inserts: %v; %d inserts: %v\n", n, t1, 2*n, t2)