Go将键值对存储在一个桶列表中,每个桶将保存8个键值对,当map耗尽容量时,散列桶将加倍扩容。下面一张图粗略的表示了四个桶:
map的buckets列表
我们将在下一篇文章中介绍存储桶中的键值对是如何存放的。如果map容量增加,桶的数量将翻倍至8个、16个等等。
当一个key/value对存入map当中,将根据key的散列值分配到对于的桶里。
当key/value对赋值到map时,Go将基于key值生成一个hash值。我们以插入"foo=1"键值对为例,生成的hash值可能为15491954468309821754,将该值用于一个位操作,其掩码等于桶的数量值减1。在下图中给出了桶数为4的例子,可以得到掩码3,然后执行按位与操作:
value在桶中的分配
散列值不仅用于分配桶的值,还会有其他的操作。根据散列值的高8位,可以确认一个桶内的数组存储value的位置。如下图:
桶中的top hash table
因为桶内存在这个表,Go能够快速访问和比较key对于的value值。
根据程序中map的使用,Go需要一种可扩容的机制来存放更多的key/value值。
如果桶需要存储一个key/value,将为存储在内部可用的8个桶对于的槽内。如果没有桶可用的话,一个溢出桶会被创建并链接到当前桶中,并链接到当前桶上。
溢出桶
这种溢出的特性概括了桶的内部结构。然而增加溢出桶会降低map的性能。为了解决性能问题,Go将分配新的桶(当前数量的两倍)将在旧的桶和新桶之间建立连接。
Go使用它的负载系数来知道何时应该开始分配新桶和这个疏散过程。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。