package
0.0.0-20250107152505-2809300c68ba
Repository: https://github.com/triumphpc/go-study.git
Documentation: pkg.go.dev

# README

https://www.youtube.com/watch?v=P_SXTUiA-9Y

img_1.png

  • Набор в мапе делится на бакеты для поиска с постоянным временем

    • распределяется равномерно
    • постояннен в поиске
    • детерминированность - для этого и того же ключа один и тот же хеш
    • криптоустойчивость - наша хеш функция не должна позволять данным попадать в один и тот зе бакет
  • ключи, это хеш-функция

Сигнатура получения значения в GO для мапы

img.png

Но при работе с мапами, ни дженерики, ни интерфейсы не используются

Операции при работе с мапами

  • Все операции выполняются с помощью unsafe.pointers (ячейка памяти, на который указывает такой указатель может относиться к любому типу данных)
  • Но чтобы понять с чем мы работаем, используется type descriptor
  • type descriptor предоставляет операции hash, equal, copy (для разных типов хеш-функция будет отличаться, так же методы сравнения и копирования) img_2.png

Как скомпилируется

img_3.png Происходит разименование - сначала unsafe.Pointer приводится к искомому типу, и от него берется значение

Header в Map

img_5.png Количество бакетов в мапе хранится в хидере в виде логарифма. Hash seed для обеспечения условий крипто-безопасности, которые предъявляли ранее. LOB - указатель на младший бик хеша для каждой бакета.

Что такое Low bits pointer

img_6.png Есть ключ, к нему применяется хеш-функция, на выходе число Число может быть большим. Как понимать, в какой бакет положить данные? Делается остаток от деления на количество бакетов: img_7.png Все это вычисляется в двоичном виде. Чтобы тут получить остаток от деления,нам нужно log (который хранится в заголовке мапы) от количества бакетов: img_8.png img_27.png И остатку от деления будут соответствовать два бита младшего бакета: img_9.png После присвоения младшего бита (номера бакета) приравниваем его к LOB img_10.png

Структура бакета

В каждом бакете аналогичная структура. Состоит из двух частей:

  • 8 слотов для старших битов хеша. Процедура получения такая же как и для младших битов
  • если слот нашелся, то уже сравнивается каждый ключ img_11.png

В каждом бакете не может храниться более 8 значений Формат хранения ключей/значений оптимизировано для выравнивания типов: img_12.png

Получение битовой маски

img_13.png

Переполнение бакетов

img_14.png Нужно избегать переполнений, так как вычисления становятся сложнее. Алгоритм выделения новой памяти под бакеты определяется отдельным алгоритмом и в тот момент, когда процент заполнения 20% (loadFactory 6.5) При выделении памяти происходит эвакуация данных из бакетов img_15.png Операции работы с мапой будут работать медленнее, так как надо смотреть в нескольких местах

Поэтому нужно заранее аллоцировать память под нужный размер мапы

Почему нельзя взять указатель на значение мапы по ключу?

Потому что при переполнении мапы может произойти эвакуация данных из бакета и ссылка станет не актуальной.

Рандомный порядом обхода

При обходе значений мапы - получаем всегда рандомный порядок. Итератор ходит и по новым и по старым бакетам и если происходит эвакуация бакета, то порядом меняется. При каждом выводе мапы мы видим, что ключи отсортированы img_16.png Мапа сортируется в самой Println

Что такие хеш-таблицы

img_17.png Это получение id для ключа с помощью хеш-функции.

Стратегии решения коллизий

1.Метод открытой адресации 1.1. Множественное вычисление функции их полученного ключа. Линейное пробирование. Числа, которые мы получаем - последовательность проб. img_18.png

Минуст такого подхода, что при удалении полей, поиск по такой таблице будет работать медленно, потому что приходится пропускать много ячеек img_19.png Рехеширование помогает создавать новую тублицу, удаляя помеченные на удаление записи img_20.png

1.2. Квадратичное пробирование 1.3. Двойное хеширование

  1. Метод цепочек В таблицу сохраняется не сами значения, а ссылка на другую область памяти img_21.png

в случае коллизии мы не ищем новую ячейку, а ссылку на новую запись хранит сама маша: img_23.png При поиске переходим по ссылкам: img_24.png

img_25.png

Правила хеш-функции

img_26.png