Sobes.tech
Middle

Hogyan működik a Map a Go-ban?

sobes.tech MI

Válasz az MI-től

A Go-ban a térkép egy hash-táblaként van megvalósítva.

A map szerkezet fő összetevői:

  • Hash függvény: A kulcsokat hash értékekre (egész számokra) térképezi.
  • Bucket tömb: Lista vagy tömbök halmaza, ahol a kulcs-érték párok tárolódnak. A bucket indexe a kulcs hash értékétől függ.
  • Ütközések kezelése: Amikor különböző kulcsok ugyanazt a hash értéket kapják (ütközés), ezek az elemek ugyanabba a bucketbe kerülnek, általában láncolt lista vagy túlcsordulási bucket formájában.
  • Terhelési tényező: Az elemek száma és a bucketek száma közötti arány. Amikor ez egy küszöböt meghalad, újrahash-elés történik: egy nagyobb bucket tömböt hoznak létre, és az összes régi bucket elemeit átmozgatják az újakba.

A Go-ban a map szerkezetet az hmap típus reprezentálja:

 type hmap struct {
    count     int // Elemek száma
    flags     uint8 // Állapot zászlók
    B         uint8 // log_2 a bucketek számáról (2^B a bucketek száma)
    noverflow uint16 // Túlsúlyos bucketek száma (csak statisztikára)
    hash0     uint32 // A hash függvény kezdőértéke

    buckets    unsafe.Pointer // Mutató a bucket tömbre
    oldbuckets unsafe.Pointer // Mutató a régi bucket tömbre migráció közben
    nevacuate  uintptr // Megmutatja, hogy melyik régi bucketnél fejeződött be a migráció

    extra *mapextra // További információk
}

 type mapextra struct {
    overflow    *[2]*[]*bmap // Túlsúlyos bucket tömbök mutatói
    oldoverflow *[2]*[]*bmap // Régi túlsúlyos bucket tömbök mutatói
    nextOverflow *bmap // Következő szabad túlsúlyos bucket
}

 type bmap struct {
    tophash [8]uint8 // Top hash (hash felső bitei) a keresés gyorsítására
    // Ezután jönnek a kulcsok, értékek és mutatók a következő bmap-re (ha a bucket tele van)
    // Az összes adat elrendezése az hmap.buckets-ben egyetlen malloc blokkban
    // részletekért lásd a ../../runtime/map.go-t
}

Műveletek:

  • Beszúrás/Frissítés: A kulcs hash értékét számítja ki, meghatározza a bucketet. Ha a kulcs már létezik, az érték frissül. Egyébként a kulcs-érték pár hozzáadódik a buckethez. Túlsúly vagy Load Factor túllépése esetén rehash történhet.
  • Keresés: A kulcs hash értékét számítja ki, meghatározza a bucketet. A bucket elemeit a top-hash szerint ellenőrzi, majd a teljes kulcsokat összehasonlítja. Az érték és a létezés flag-je visszaadásra kerül.
  • Törlés: A kulcs hash értékét számítja ki, meghatározza a bucketet. A kiválasztott elem megjelölésre kerül töröltként (de nem törlődik azonnal a memóriából). A törlés későbbi műveletek vagy rehash során történik.

A Go-ban a térkép nincs szinkronizálva, és több goroutine által biztonságosan nem használható külső szinkronizáció nélkül.