Source file src/runtime/map_swiss_test.go

     1  // Copyright 2024 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  //go:build goexperiment.swissmap
     6  
     7  package runtime_test
     8  
     9  import (
    10  	"internal/abi"
    11  	"internal/goarch"
    12  	"internal/runtime/maps"
    13  	"slices"
    14  	"testing"
    15  	"unsafe"
    16  )
    17  
    18  func TestHmapSize(t *testing.T) {
    19  	// The structure of Map is defined in internal/runtime/maps/map.go
    20  	// and in cmd/compile/internal/reflectdata/map_swiss.go and must be in sync.
    21  	// The size of Map should be 48 bytes on 64 bit and 32 bytes on 32 bit platforms.
    22  	wantSize := uintptr(2*8 + 4*goarch.PtrSize)
    23  	gotSize := unsafe.Sizeof(maps.Map{})
    24  	if gotSize != wantSize {
    25  		t.Errorf("sizeof(maps.Map{})==%d, want %d", gotSize, wantSize)
    26  	}
    27  }
    28  
    29  // See also reflect_test.TestGroupSizeZero.
    30  func TestGroupSizeZero(t *testing.T) {
    31  	var m map[struct{}]struct{}
    32  	mTyp := abi.TypeOf(m)
    33  	mt := (*abi.SwissMapType)(unsafe.Pointer(mTyp))
    34  
    35  	// internal/runtime/maps when create pointers to slots, even if slots
    36  	// are size 0. The compiler should have reserved an extra word to
    37  	// ensure that pointers to the zero-size type at the end of group are
    38  	// valid.
    39  	if mt.Group.Size() <= 8 {
    40  		t.Errorf("Group size got %d want >8", mt.Group.Size())
    41  	}
    42  }
    43  
    44  func TestMapIterOrder(t *testing.T) {
    45  	sizes := []int{3, 7, 9, 15}
    46  	for _, n := range sizes {
    47  		for i := 0; i < 1000; i++ {
    48  			// Make m be {0: true, 1: true, ..., n-1: true}.
    49  			m := make(map[int]bool)
    50  			for i := 0; i < n; i++ {
    51  				m[i] = true
    52  			}
    53  			// Check that iterating over the map produces at least two different orderings.
    54  			ord := func() []int {
    55  				var s []int
    56  				for key := range m {
    57  					s = append(s, key)
    58  				}
    59  				return s
    60  			}
    61  			first := ord()
    62  			ok := false
    63  			for try := 0; try < 100; try++ {
    64  				if !slices.Equal(first, ord()) {
    65  					ok = true
    66  					break
    67  				}
    68  			}
    69  			if !ok {
    70  				t.Errorf("Map with n=%d elements had consistent iteration order: %v", n, first)
    71  				break
    72  			}
    73  		}
    74  	}
    75  }
    76  

View as plain text