0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

一文了解go hashmap(数据结构、实现原理、读写操作)

454398 来源:itpub技术栈 作者:itpub技术栈 2020-09-30 16:19 次阅读

这是看着别人的文章结合源码来整理的自己一套理解

理解 Golang 哈希表 Map 的原理​draveness.me

通过数据结构、实现原理、读写操作来了解go hashmap

数据结构

hash有2个关键数据结构:hmapbmap

hmap:runtime/map.go

type hmap struct {
    count       int 
    flags       uint8
    B           uint8  
    noverflow   uint16 
    hash0       uint32 
    buckets     unsafe.Pointer 
    oldbuckets  unsafe.Pointer
    nevacuate   uintptr
    extra       *mapextra 
}

count元素数量

B2^B个buckets桶

noverflowbuckets溢出桶的数量,近似值

buckets桶

oldbuckets扩容时指向原buckets桶

bmap:runtime/map.gocmd/compile/internal/gc/reflect.go

type bmap struct {
    topbits     [8]uint8
    keys        [8]keytype
    elems       [8]elemtype
    pad         uintptr
    overflow    uintptr
}

哈希表中桶的真正结构其实是在编译期间运行的函数bmap中被『动态』创建的, 代码在cmd/compile/internal/gc/reflect.go

topbits存储hash值的高8位,通过比对高8位减少键值对访问次数以提高性能

keys/elems数组

pad内存对齐

overflow溢出桶,map存储数据过多时使用

实现原理

时间复杂度: O(1)

hash函数和hash冲突解决方法

hash函数

实现哈希表的关键点在于如何选择哈希函数,哈希函数的选择在很大程度上能够决定哈希表的读写性能,在理想情况下,哈希函数应该能够将不同键映射到不同的索引上,这要求哈希函数输出范围大于输入范围,但是由于键的数量会远远大于映射的范围,所以在实际使用时,这个理想的结果是不可能实现的。

hash冲突

开放寻址法:对数组中的元素依次比较键值对是否存在于数组

拉链法: 使用数组加上链表

读写操作

计算出key的hash

用最后的“B”位来确定在哪个桶(“B”就是前面说的那个,B为4,就有16个桶,0101用十进制表示为5,所以在5号桶)

根据key的前8位快速确定是在哪个格子(额外说明一下,在bmap中存放了每个key对应的tophash,是key的前8位)

最终还是需要比对key完整的hash是否匹配,如果匹配则获取对应value

如果都没有找到,就去下一个overflow找

通过key的后“B”位确定是哪一个桶

通过key的前8位快速确定是否已经存在

最终确定存放位置,如果8个格子已经满了,没地方放了,那么就重新创建一个bmap作为溢出桶连接在overflow

扩容

条件:

装载因子大于6.5

溢出桶 大于15个

func mapassign(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
    ...
    if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
        hashGrow(t, h)
        goto again
    }
    ...
}

方式:

等量扩容

翻倍扩容
编辑:hfy

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据结构
    +关注

    关注

    3

    文章

    573

    浏览量

    40124
  • 读写操作
    +关注

    关注

    0

    文章

    5

    浏览量

    7116
  • hashmap
    +关注

    关注

    0

    文章

    14

    浏览量

    2285
收藏 人收藏

    评论

    相关推荐

    数据结构概述及线性表

    。    “数据结构”是计算机专业的门核心课程,是“编译原理”、“操作系统”、“数据库”等课程的基础,也是设计和实现
    发表于 12-05 21:20

    数据结构

    1.数据结构的概念 所谓数据结构是指由某一数据对象及该对象中所有数据成员之间的关系组成的集合。成员之间的关系有很多种,最常见的是前后件关系。 2.
    发表于 03-04 14:13

    常见的数据结构

    顺序表结构的底层实现借助的就是数组,因此对于初学者来说,可以把顺序表完全等价为数组,但实则不是这样。数据结构是研究数据存储方式的门学科,它
    发表于 05-10 07:58

    数据结构链表的基本操作

    嵌入式学习基础-数据结构链表的基本操作链表节点采用结构体的方式进行定义,下面是最基础的定义只有数据data,*pNext用于指向下
    发表于 12-22 08:05

    GPIB命令的数据结构

    针对GPIB命令的结构,提出种存储GPIB命令的数据结构。根据GPIB命令的层次关系的特点,选择数据结构中“树”的概念来存储GPIB命令结点;并考虑程序
    发表于 02-10 16:20 70次下载

    GPIB命令的数据结构

    针对GPIB命令的结构,提出种存储GPIB命令的数据结构。根据GPIB命令的层次关系的特点,选择数据结构中“树”的概念来存储GPIB命令结点;并考虑程序
    发表于 01-04 10:13 0次下载

    数据结构是什么_数据结构有什么用

    数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在种或多种特定关系的数据元素的集合。通常情况下,精心选择的
    发表于 11-17 14:45 1.6w次阅读
    <b class='flag-5'>数据结构</b>是什么_<b class='flag-5'>数据结构</b>有什么用

    什么是数据结构?为什么要学习数据结构数据结构的应用实例分析

    本文档的主要内容详细介绍的是什么是数据结构?为什么要学习数据结构数据结构的应用实例分析包括了:数据结构在串口通信当中的应用,数据结构在按键
    发表于 09-26 15:45 14次下载
    什么是<b class='flag-5'>数据结构</b>?为什么要学习<b class='flag-5'>数据结构</b>?<b class='flag-5'>数据结构</b>的应用实例分析

    算法和数据结构基础知识分享(上)

    有哪些常见的数据结构?基本操作是什么?常见的排序算法是如何实现的?各有什么优缺点?本文简要分享算法基础、常见的数据结构以及排序算法。
    的头像 发表于 04-06 16:48 795次阅读
    算法和<b class='flag-5'>数据结构</b>基础知识分享(上)

    算法和数据结构基础知识分享(中)

    有哪些常见的数据结构?基本操作是什么?常见的排序算法是如何实现的?各有什么优缺点?本文简要分享算法基础、常见的数据结构以及排序算法。
    的头像 发表于 04-06 16:48 598次阅读
    算法和<b class='flag-5'>数据结构</b>基础知识分享(中)

    算法和数据结构基础知识分享(下)

    有哪些常见的数据结构?基本操作是什么?常见的排序算法是如何实现的?各有什么优缺点?本文简要分享算法基础、常见的数据结构以及排序算法。
    的头像 发表于 04-06 16:48 743次阅读
    算法和<b class='flag-5'>数据结构</b>基础知识分享(下)

    NetApp的数据结构是如何演变的

    一数据跨分布式资源进行管理,以实现数据移动的致性和控制,安全、可见性、保护和访问。 本文定义了数据结构及其体系
    发表于 08-25 17:15 0次下载
    NetApp的<b class='flag-5'>数据结构</b>是如何演变的

    JDK中java.util.HashSet 类的介绍

    的效率。了解 HashMap 的具体实现后,我们再来介绍由 HashMap 作为底层数据结构实现
    的头像 发表于 10-09 10:50 592次阅读
    JDK中java.util.HashSet 类的介绍

    epoll的基础数据结构

    、epoll的基础数据结构 在开始研究源代码之前,我们先看下 epoll 中使用的数据结构,分别是 eventpoll、epitem 和 eppoll_entry。 1、event
    的头像 发表于 11-10 10:20 802次阅读
    epoll的基础<b class='flag-5'>数据结构</b>

    redis数据结构的底层实现

    Redis是种内存键值数据库,常用于缓存、消息队列、实时数据分析等场景。它的高性能得益于其精心设计的数据结构和底层实现。本文将详细介绍Re
    的头像 发表于 12-05 10:14 617次阅读