0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取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中被『動態(tài)』創(chuàng)建的, 代碼在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個格子已經滿了,沒地方放了,那么就重新創(chuàng)建一個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

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯系本站處理。 舉報投訴
  • 數據結構
    +關注

    關注

    3

    文章

    568

    瀏覽量

    40030
  • 讀寫操作
    +關注

    關注

    0

    文章

    5

    瀏覽量

    7108
  • hashmap
    +關注

    關注

    0

    文章

    14

    瀏覽量

    2263
收藏 人收藏

    評論

    相關推薦

    數據結構概述及線性表

    。    “數據結構”是計算機專業(yè)的門核心課程,是“編譯原理”、“操作系統(tǒng)”、“數據庫”等課程的基礎,也是設計和實現
    發(fā)表于 12-05 21:20

    數據結構

    1.數據結構的概念 所謂數據結構是指由某一數據對象及該對象中所有數據成員之間的關系組成的集合。成員之間的關系有很多種,最常見的是前后件關系。 2.
    發(fā)表于 03-04 14:13

    常見的數據結構

    順序表結構的底層實現借助的就是數組,因此對于初學者來說,可以把順序表完全等價為數組,但實則不是這樣。數據結構是研究數據存儲方式的門學科,它
    發(fā)表于 05-10 07:58

    數據結構鏈表的基本操作

    嵌入式學習基礎-數據結構鏈表的基本操作鏈表節(jié)點采用結構體的方式進行定義,下面是最基礎的定義只有數據data,*pNext用于指向下
    發(fā)表于 12-22 08:05

    GPIB命令的數據結構

    針對GPIB命令的結構,提出種存儲GPIB命令的數據結構。根據GPIB命令的層次關系的特點,選擇數據結構中“樹”的概念來存儲GPIB命令結點;并考慮程序
    發(fā)表于 02-10 16:20 ?70次下載

    GPIB命令的數據結構

    針對GPIB命令的結構,提出種存儲GPIB命令的數據結構。根據GPIB命令的層次關系的特點,選擇數據結構中“樹”的概念來存儲GPIB命令結點;并考慮程序
    發(fā)表于 01-04 10:13 ?0次下載

    數據結構是什么_數據結構有什么用

    數據結構是計算機存儲、組織數據的方式。數據結構是指相互之間存在種或多種特定關系的數據元素的集合。通常情況下,精心選擇的
    發(fā)表于 11-17 14:45 ?1.6w次閱讀
    <b class='flag-5'>數據結構</b>是什么_<b class='flag-5'>數據結構</b>有什么用

    什么是數據結構?為什么要學習數據結構?數據結構的應用實例分析

    本文檔的主要內容詳細介紹的是什么是數據結構?為什么要學習數據結構?數據結構的應用實例分析包括了:數據結構在串口通信當中的應用,數據結構在按鍵
    發(fā)表于 09-26 15:45 ?14次下載
    什么是<b class='flag-5'>數據結構</b>?為什么要學習<b class='flag-5'>數據結構</b>?<b class='flag-5'>數據結構</b>的應用實例分析

    算法和數據結構基礎知識分享(上)

    有哪些常見的數據結構?基本操作是什么?常見的排序算法是如何實現的?各有什么優(yōu)缺點?本文簡要分享算法基礎、常見的數據結構以及排序算法。
    的頭像 發(fā)表于 04-06 16:48 ?712次閱讀
    算法和<b class='flag-5'>數據結構</b>基礎知識分享(上)

    算法和數據結構基礎知識分享(中)

    有哪些常見的數據結構?基本操作是什么?常見的排序算法是如何實現的?各有什么優(yōu)缺點?本文簡要分享算法基礎、常見的數據結構以及排序算法。
    的頭像 發(fā)表于 04-06 16:48 ?514次閱讀
    算法和<b class='flag-5'>數據結構</b>基礎知識分享(中)

    算法和數據結構基礎知識分享(下)

    有哪些常見的數據結構?基本操作是什么?常見的排序算法是如何實現的?各有什么優(yōu)缺點?本文簡要分享算法基礎、常見的數據結構以及排序算法。
    的頭像 發(fā)表于 04-06 16:48 ?660次閱讀
    算法和<b class='flag-5'>數據結構</b>基礎知識分享(下)

    NetApp的數據結構是如何演變的

    統(tǒng)一數據跨分布式資源進行管理,以實現數據移動的致性和控制,安全、可見性、保護和訪問。 本文定義了數據結構及其體系
    發(fā)表于 08-25 17:15 ?0次下載
    NetApp的<b class='flag-5'>數據結構</b>是如何演變的

    JDK中java.util.HashSet 類的介紹

    的效率。了解 HashMap 的具體實現后,我們再來介紹由 HashMap 作為底層數據結構實現
    的頭像 發(fā)表于 10-09 10:50 ?474次閱讀
    JDK中java.util.HashSet 類的介紹

    epoll的基礎數據結構

    、epoll的基礎數據結構 在開始研究源代碼之前,我們先看下 epoll 中使用的數據結構,分別是 eventpoll、epitem 和 eppoll_entry。 1、event
    的頭像 發(fā)表于 11-10 10:20 ?631次閱讀
    epoll的基礎<b class='flag-5'>數據結構</b>

    redis數據結構的底層實現

    Redis是種內存鍵值數據庫,常用于緩存、消息隊列、實時數據分析等場景。它的高性能得益于其精心設計的數據結構和底層實現。本文將詳細介紹Re
    的頭像 發(fā)表于 12-05 10:14 ?521次閱讀