golang sync map思考總結(jié)

一、核心結(jié)構(gòu)體先貼一下

type Map struct {
    mu Mutex    //互斥鎖,用于鎖定dirty map

    read atomic.Value //優(yōu)先讀map,支持原子操作,注釋中有readOnly不是說(shuō)read是只讀,而是它的結(jié)構(gòu)體。read實(shí)際上有寫的操作

    dirty map[interface{}]*entry // dirty是一個(gè)當(dāng)前最新的map,允許讀寫

    misses int // 主要記錄read讀取不到數(shù)據(jù)加鎖讀取read map以及dirty map的次數(shù),當(dāng)misses等于dirty的長(zhǎng)度時(shí),會(huì)將dirty復(fù)制到read
}

type readOnly struct {
    m       map[interface{}]*entry
    amended bool // true if the dirty map contains some key not in m. // key在dirty中,不在read中
}

dirty map[interface{}]*entry

type entry struct {
    // p points to the interface{} value stored for the entry.
    //
    // If p == nil, the entry has been deleted and m.dirty == nil.
    //
    // If p == expunged, the entry has been deleted, m.dirty != nil, and the entry
    // is missing from m.dirty.  // entry不存在 dirty中
    //
    // Otherwise, the entry is valid and recorded in m.read.m[key] and, if m.dirty
    // != nil, in m.dirty[key].
    //
    // An entry can be deleted by atomic replacement with nil: when m.dirty is
    // next created, it will atomically replace nil with expunged and leave
    // m.dirty[key] unset.
    //
    // An entry's associated value can be updated by atomic replacement, provided
    // p != expunged. If p == expunged, an entry's associated value can be updated
    // only after first setting m.dirty[key] = e so that lookups using the dirty
    // map find the entry.
    p unsafe.Pointer // *interface{}
}

二、思考總結(jié)

核心思想是用空間換時(shí)間,用兩個(gè)map來(lái)存儲(chǔ)數(shù)據(jù),readdirty,read支持原子操作,可以看作是dirty 的cache,dirty是更底層的數(shù)據(jù)存儲(chǔ)層
4種操作:讀key、增加key、更新key、刪除key的基本流程
讀key:先到read中讀取,如果有則直接返回結(jié)果,如果沒(méi)有或者是被刪除(有特殊value值可以判斷),則到dirty加鎖中讀取,如果有返回結(jié)果并更新miss數(shù)
增加key:直接增加到dirty中
更新key:先到read中看看有沒(méi)有,如果有直接更新key,如果沒(méi)有則到dirty中更新
刪除key:先到read中看看有沒(méi)有,如果有則直接更新為nil,如果沒(méi)有則到dirty中直接刪除

read的替換:當(dāng)read多次都沒(méi)有命中數(shù)據(jù),達(dá)到閾值,表示這個(gè)cache命中率太低,這時(shí)直接將整個(gè)readdirty替換掉,然后dirty又重新置為nil,下一次再添加一個(gè)新key的時(shí)候,會(huì)觸發(fā)一次readdirty的復(fù)制,這樣二者又保持了一致。

雖然readdirty有冗余,但這些map的value數(shù)據(jù)是通過(guò)指針指向同一個(gè)數(shù)據(jù),所以盡管實(shí)際的value會(huì)很大,但是冗余的空間占用還是有限的。

總結(jié),如果對(duì)map的讀操作遠(yuǎn)遠(yuǎn)多于寫操作(寫操作包括新增和刪除key),那么sync.Map是很合適,能夠大大提升性能

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容