| // 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" | |
| ) | |
| const RuntimeHmapSize = unsafe.Sizeof(hmap{}) | |
| func OverLoadFactor(count int, B uint8) bool { | |
| return overLoadFactor(count, B) | |
| } | |
| 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.OldMapBucketCount; i++ { | |
| if b.tophash[i] != emptyRest { | |
| n++ | |
| } | |
| } | |
| } | |
| k := 0 | |
| for b := b0; b != nil; b = b.overflow(t) { | |
| for i := 0; i < abi.OldMapBucketCount; 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++ | |
| } | |
| } | |
| } | |
| } |