diff options
Diffstat (limited to 'src/runtime/export_map_swiss_test.go')
| -rw-r--r-- | src/runtime/export_map_swiss_test.go | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/runtime/export_map_swiss_test.go b/src/runtime/export_map_swiss_test.go new file mode 100644 index 0000000000..ac0308fce0 --- /dev/null +++ b/src/runtime/export_map_swiss_test.go @@ -0,0 +1,58 @@ +// 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 + +import ( + "internal/abi" + "unsafe" +) + +func MapBucketsCount(m map[int]int) int { + h := *(**hmap)(unsafe.Pointer(&m)) + return 1 << h.B +} + +func MapBucketsPointerIsNil(m map[int]int) bool { + h := *(**hmap)(unsafe.Pointer(&m)) + return h.buckets == nil +} + +func MapTombstoneCheck(m map[int]int) { + // Make sure emptyOne and emptyRest are distributed correctly. + // We should have a series of filled and emptyOne cells, followed by + // a series of emptyRest cells. + h := *(**hmap)(unsafe.Pointer(&m)) + i := any(m) + t := *(**maptype)(unsafe.Pointer(&i)) + + for x := 0; x < 1<<h.B; x++ { + b0 := (*bmap)(add(h.buckets, uintptr(x)*uintptr(t.BucketSize))) + n := 0 + for b := b0; b != nil; b = b.overflow(t) { + for i := 0; i < abi.SwissMapBucketCount; i++ { + if b.tophash[i] != emptyRest { + n++ + } + } + } + k := 0 + for b := b0; b != nil; b = b.overflow(t) { + for i := 0; i < abi.SwissMapBucketCount; i++ { + if k < n && b.tophash[i] == emptyRest { + panic("early emptyRest") + } + if k >= n && b.tophash[i] != emptyRest { + panic("late non-emptyRest") + } + if k == n-1 && b.tophash[i] == emptyOne { + panic("last non-emptyRest entry is emptyOne") + } + k++ + } + } + } +} |
