Sobes.tech
Middle

Как работи Map в Go?

sobes.tech AI

Отговор от AI

Map в Go е реализиран като хеш таблица.

Основните компоненти на структурата map:

  • Хеш функция: Отразява ключовете към хеш стойности (цяли числа).
  • Масив от кофи (buckets): Набор от списъци или масиви, където се съхраняват двойки ключ-стойност. Индексът на кофата се определя от хеш стойността на ключа.
  • Обработка на колизии: При съвпадение на хешовете за различни ключове (колизия) елементите с тези ключове се съхраняват в една кофа, обикновено като свързан списък или преливане в съседна кофа.
  • Натоварващ фактор: Отношението между броя на елементите и броя на кофите. При превишаване на определен праг се извършва рехеширане – създаване на нов, по-голям масив от кофите и преместване на всички елементи от старите кофите в новите.

Структурата map в Go е представена чрез типа hmap:

type hmap struct {
    count     int // Брой елементи
    flags     uint8 // Флагове за състояние
    B         uint8 // log_2 на броя кофите (броят кофите е 2^B)
    noverflow uint16 // Брой прелели кофите (само за статистика)
    hash0     uint32 // Начална стойност на хеш функцията

    buckets    unsafe.Pointer // указател към масив от кофите (основен и прелели)
    oldbuckets unsafe.Pointer // указател към стария масив от кофите по време на миграция
    nevacuate  uintptr // Обозначава до кой стар кофа е завършена миграцията

    extra *mapextra // Допълнителна информация (по избор)
}

type mapextra struct {
    overflow    *[2]*[]*bmap // Указатели към масиви от прелели кофите
    oldoverflow *[2]*[]*bmap // Указатели към стари масиви от прелели кофите
    nextOverflow *bmap // Следващ свободен прелял кофа
}

type bmap struct {
    tophash [8]uint8 // Топ-хеш (горните бита на хеша) за ускоряване на търсенето в кофата
    // Следват ключове, стойности и указател към следващ bmap (ако кофата е преляла)
    // разположение на всички данни за hmap.buckets в един malloc блок
    // виж ../../runtime/map.go за подробности
}