Source file src/internal/abi/map.go

     1  // Copyright 2023 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  package abi
     6  
     7  import (
     8  	"unsafe"
     9  )
    10  
    11  // Map constants common to several packages
    12  // runtime/runtime-gdb.py:MapTypePrinter contains its own copy
    13  const (
    14  	// Number of bits in the group.slot count.
    15  	MapGroupSlotsBits = 3
    16  
    17  	// Number of slots in a group.
    18  	MapGroupSlots = 1 << MapGroupSlotsBits // 8
    19  
    20  	// Maximum key or elem size to keep inline (instead of mallocing per element).
    21  	// Must fit in a uint8.
    22  	MapMaxKeyBytes  = 128
    23  	MapMaxElemBytes = 128
    24  
    25  	ctrlEmpty = 0b10000000
    26  	bitsetLSB = 0x0101010101010101
    27  
    28  	// Value of control word with all empty slots.
    29  	MapCtrlEmpty = bitsetLSB * uint64(ctrlEmpty)
    30  )
    31  
    32  type MapType struct {
    33  	Type
    34  	Key   *Type
    35  	Elem  *Type
    36  	Group *Type // internal type representing a slot group
    37  	// function for hashing keys (ptr to key, seed) -> hash
    38  	Hasher    func(unsafe.Pointer, uintptr) uintptr
    39  	GroupSize uintptr // == Group.Size_
    40  	// These fields describe how to access keys and elems within a group.
    41  	// The formulas key(i) = KeysOff + i*KeyStride and
    42  	// elem(i) = ElemsOff + i*ElemStride work for both group layouts:
    43  	//
    44  	// With GOEXPERIMENT=mapsplitgroup (split arrays KKKKVVVV):
    45  	//   KeysOff    = offset of keys array in group
    46  	//   KeyStride  = size of a single key
    47  	//   ElemsOff   = offset of elems array in group
    48  	//   ElemStride = size of a single elem
    49  	//
    50  	// Without (interleaved slots KVKVKVKV):
    51  	//   KeysOff    = offset of slots array in group
    52  	//   KeyStride  = size of a key/elem slot (stride between keys)
    53  	//   ElemsOff   = offset of first elem (slots offset + elem offset within slot)
    54  	//   ElemStride = size of a key/elem slot (stride between elems)
    55  	KeysOff    uintptr
    56  	KeyStride  uintptr
    57  	ElemsOff   uintptr
    58  	ElemStride uintptr
    59  	ElemOff    uintptr // GOEXPERIMENT=nomapsplitgroup only
    60  	Flags      uint32
    61  }
    62  
    63  // Flag values
    64  const (
    65  	MapNeedKeyUpdate = 1 << iota
    66  	MapHashMightPanic
    67  	MapIndirectKey
    68  	MapIndirectElem
    69  )
    70  
    71  func (mt *MapType) NeedKeyUpdate() bool { // true if we need to update key on an overwrite
    72  	return mt.Flags&MapNeedKeyUpdate != 0
    73  }
    74  func (mt *MapType) HashMightPanic() bool { // true if hash function might panic
    75  	return mt.Flags&MapHashMightPanic != 0
    76  }
    77  func (mt *MapType) IndirectKey() bool { // store ptr to key instead of key itself
    78  	return mt.Flags&MapIndirectKey != 0
    79  }
    80  func (mt *MapType) IndirectElem() bool { // store ptr to elem instead of elem itself
    81  	return mt.Flags&MapIndirectElem != 0
    82  }
    83  

View as plain text