从源码理解Go:map
2016-11-15
map的内部结构 #
Go中的map使用哈希表实现的,在源码go runtime/hashmap.go中可以看到对应实现。
1// A header for a Go map.
2type hmap struct {
3 // Note: the format of the Hmap is encoded in ../../cmd/internal/gc/reflect.go and
4 // ../reflect/type.go. Don't change this structure without also changing that code!
5 count int // # live cells == size of map. Must be first (used by len() builtin)
6 flags uint8
7 B uint8 // log_2 of # of buckets (can hold up to loadFactor * 2^B items)
8 noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for details
9 hash0 uint32 // hash seed
10
11 buckets unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
12 oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
13 nevacuate uintptr // progress counter for evacuation (buckets less than this have been evacuated)
14
15 // If both key and value do not contain pointers and are inline, then we mark bucket
16 // type as containing no pointers. This avoids scanning such maps.
17 // However, bmap.overflow is a pointer. In order to keep overflow buckets
18 // alive, we store pointers to all overflow buckets in hmap.overflow.
19 // Overflow is used only if key and value do not contain pointers.
20 // overflow[0] contains overflow buckets for hmap.buckets.
21 // overflow[1] contains overflow buckets for hmap.oldbuckets.
22 // The first indirection allows us to reduce static size of hmap.
23 // The second indirection allows to store a pointer to the slice in hiter.
24 overflow *[2]*[]*bmap
25}
26
27// A bucket for a Go map.
28type bmap struct {
29 // tophash generally contains the top byte of the hash value
30 // for each key in this bucket. If tophash[0] < minTopHash,
31 // tophash[0] is a bucket evacuation state instead.
32 tophash [bucketCnt]uint8
33 // Followed by bucketCnt keys and then bucketCnt values.
34 // NOTE: packing all the keys together and then all the values together makes the
35 // code a bit more complicated than alternating key/value/key/value/... but it allows
36 // us to eliminate padding which would be needed for, e.g., map[int64]int8.
37 // Followed by an overflow pointer.
38}
先删掉代码原有注释,以便于查看:
...