码迷,mamicode.com
首页 > 其他好文 > 详细

[go]map

时间:2020-01-14 09:27:56      阅读:87      评论:0      收藏:0      [点我收藏+]

标签:数据   返回   code   for   计算   info   种子   actor   poi   

map的实现细节

技术图片

//初始化: 最重要的肯定就是确定一开始要有多少个桶,初始化哈希种子等等

func makemap_small() *hmap {
    h := new(hmap)
    h.hash0 = fastrand()
    return h
}

// makemap implements Go map creation for make(map[k]v, hint).
func makemap(t *maptype, hint int, h *hmap) *hmap {
    .....

    // initialize Hmap
    if h == nil {
        h = (*hmap)(newobject(t.hmap))
    }
    h.hash0 = fastrand()

    // find size parameter which will hold the requested # of elements
    B := uint8(0)
    for overLoadFactor(hint, B) {
        B++
    }
    h.B = B
    
    ......
    return h
}
  • 存储逻辑结构
    技术图片

  • map数据结构

// A header for a Go map.
type hmap struct {
    count      int            // len()返回的map的大小 即有多少kv对
    flags      uint8
    B          uint8          // 表示hash table总共有2^B个buckets 
    hash0      uint32         // hash seed
    buckets    unsafe.Pointer // 按照low hash值可查找的连续分配的数组,初始时为16个Buckets. 当bucket(桶为0时)为nil
    oldbuckets unsafe.Pointer
    nevacuate  uintptr
    overflow   *[2]*[]*bmap //溢出链 当初始buckets都满了之后会使用overflow
}
// A bucket for a Go map.

type bmap struct {
    tophash [bucketCnt]uint8
    keys     [8]keytype    // 第二个是8个key、8个value
    values   [8]valuetype  
    pad      uintptr
    overflow uintptr      // 第三个是溢出时,下一个溢出桶的地址
}
// 注意: key、value、overflow字段都不显示定义,而是通过maptype计算偏移获取的。
注: 
    之所以把所有k1k2放一起而不是k1v1是因为key和value的数据类型内存大小可能差距很大,
    比如map[int64]int8,考虑到字节对齐,kv存在一起会浪费很多空间。

[go]map

标签:数据   返回   code   for   计算   info   种子   actor   poi   

原文地址:https://www.cnblogs.com/iiiiiher/p/12190108.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!