| // Copyright 2024 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| //go:build goexperiment.swissmap | |
| package runtime_test | |
| import ( | |
| "internal/abi" | |
| "internal/goarch" | |
| "internal/runtime/maps" | |
| "slices" | |
| "testing" | |
| "unsafe" | |
| ) | |
| func TestHmapSize(t *testing.T) { | |
| // The structure of Map is defined in internal/runtime/maps/map.go | |
| // and in cmd/compile/internal/reflectdata/map_swiss.go and must be in sync. | |
| // The size of Map should be 48 bytes on 64 bit and 32 bytes on 32 bit platforms. | |
| wantSize := uintptr(2*8 + 4*goarch.PtrSize) | |
| gotSize := unsafe.Sizeof(maps.Map{}) | |
| if gotSize != wantSize { | |
| t.Errorf("sizeof(maps.Map{})==%d, want %d", gotSize, wantSize) | |
| } | |
| } | |
| // See also reflect_test.TestGroupSizeZero. | |
| func TestGroupSizeZero(t *testing.T) { | |
| var m map[struct{}]struct{} | |
| mTyp := abi.TypeOf(m) | |
| mt := (*abi.SwissMapType)(unsafe.Pointer(mTyp)) | |
| // internal/runtime/maps when create pointers to slots, even if slots | |
| // are size 0. The compiler should have reserved an extra word to | |
| // ensure that pointers to the zero-size type at the end of group are | |
| // valid. | |
| if mt.Group.Size() <= 8 { | |
| t.Errorf("Group size got %d want >8", mt.Group.Size()) | |
| } | |
| } | |
| func TestMapIterOrder(t *testing.T) { | |
| sizes := []int{3, 7, 9, 15} | |
| for _, n := range sizes { | |
| for i := 0; i < 1000; i++ { | |
| // Make m be {0: true, 1: true, ..., n-1: true}. | |
| m := make(map[int]bool) | |
| for i := 0; i < n; i++ { | |
| m[i] = true | |
| } | |
| // Check that iterating over the map produces at least two different orderings. | |
| ord := func() []int { | |
| var s []int | |
| for key := range m { | |
| s = append(s, key) | |
| } | |
| return s | |
| } | |
| first := ord() | |
| ok := false | |
| for try := 0; try < 100; try++ { | |
| if !slices.Equal(first, ord()) { | |
| ok = true | |
| break | |
| } | |
| } | |
| if !ok { | |
| t.Errorf("Map with n=%d elements had consistent iteration order: %v", n, first) | |
| break | |
| } | |
| } | |
| } | |
| } |