摘要:今天我们来学习 Golang 中的 另外一种常用的数据类型,通过数据结构和源码来分析 golang 中的 map 是如何实现的。

 

数据结构

bucketCntBits = 3
bucketCnt = 1 << bucketCntBits

// Maximum average load of a bucket that triggers growth is 6.5.
// Represent as loadFactorNum/loadFactorDen, to allow integer math.
loadFactorNum = 13
loadFactorDen = 2

type hmap struct {
    count      int      //哈希表中元素数量
    flags      uint8  //标志位,每一位有特定的含义,比如写标识
    B          uint8  //bucket 的数量,len(buckets) = pow(2, B)
    noverflow  uint16
    hash0      uint32  //传入 Hash 函数的哈希种子
    buckets    *bmap   //指向 bmap 结构体数组的指针
    oldbuckets *bmap   //哈希扩容时候用到,和 Redis 哈希扩容策略相同
    nevacuate  uintptr
    extra      unsafe.Pointer // *mapextra
 }


type bmap struct {
    topbits [8]uint8 //存储哈希值的高 8 位
    keys[8] keytype  //存储 8 个 key
    values[8] valuetype  //存储 8 个 value
    pad      uintptr  //内存对齐
    overflow uintptr  //溢出桶指针,能减少扩容频率
}

// mapextra holds fields that are not present on all maps.
type mapextra struct {
    // If both key and elem do not contain pointers and are inline, then we mark bucket
    // type as containing no pointers. This avoids scanning such maps.
    // However, bmap.overflow is a pointer. In order to keep overflow buckets
    // alive, we store pointers to all overflow buckets in hmap.extra.overflow and hmap.extra.oldoverflow.
    // overflow and oldoverflow are only used if key and elem do not contain pointers.
    // overflow contains overflow buckets for hmap.buckets.
    // oldoverflow contains overflow buckets for hmap.oldbuckets.
    // The indirection allows to store a pointer to the slice in hiter.
    overflow* [] * bmap
    oldoverflow* [] * bmap

    // nextOverflow holds a pointer to a free overflow bucket.
    nextOverflow* bmap
}
map-struct

相关文章:

  • 2021-09-11
  • 2021-09-03
  • 2022-12-23
  • 2022-12-23
  • 2021-10-11
  • 2021-11-04
  • 2021-09-17
  • 2022-12-23
猜你喜欢
  • 2021-09-13
  • 2021-11-06
  • 2021-09-15
  • 2021-06-21
  • 2021-10-25
  • 2021-05-31
  • 2022-12-23
相关资源
相似解决方案