Я пытаюсь разобраться с деталями HAMT. Я бы реализовал сам в Java, чтобы понять. Я знаком с Tries, и я думаю, что получаю основную концепцию HAMT.
В принципе,
Два типа узлов:
Key/Value
Key Value Node:
K key
V value
Индекс
Index Node:
int bitmap (32 bits)
Node[] table (max length of 32)
- Сгенерировать 32-битный хэш для объекта.
- Шаг через хэш 5-бит за раз.
(0-4, 5-9, 10-14, 15-19, 20-24, 25-29, 30-31)
Примечание: последний шаг (7-й) - всего 2 бита. - На каждом шаге найдите позицию этого 5-битного целого в растровом изображении. например
integer==5 bitmap==00001
- Если бит равен 1, то эта часть хэша существует.
- Если бит равен 0, ключ не существует.
- Если ключ существует, найдите его индекс в таблице, посчитав число 1 в битовой карте между 0 и позицией. например
integer==6 bitmap==0101010101 index==3
- Если таблица указывает на ключ/значение node, то сравните ключи.
- Если таблица указывает на индекс node, перейдите к следующему шагу.
Часть, которую я не совсем понимаю, - это обнаружение и смягчение конфликтов. В связанной статье он ссылается на него:
Существующий ключ затем вставляется в новую таблицу подшахе и добавлен новый ключ. Каждый раз, когда используется 5 бит хэша, вероятность столкновения уменьшается в 1/32 раза. Время от времени может быть использован весь 32-битный хеш, и должен быть вычислен новый чтобы установить два ключа.
Если бы я должен был вычислить "новый" хеш и сохранить объект в этом новом хеше; как бы вы могли найти объект в структуре? Когда вы выполняете поиск, не генерирует ли он "начальный" хеш, а не "пересчитанный хеш".
Мне что-то не хватает.....
BTW: HAMT работает достаточно хорошо, он сидит между картой хэша и картой дерева в моих тестах.
Data Structure Add time Remove time Sorted add time Sorted remove time Lookup time Size
Java Hash Map 38.67 ms 18 ms 30 ms 15 ms 16.33 ms 8.19 MB
HAMT 68.67 ms 30 ms 57.33 ms 35.33 ms 33 ms 10.18 MB
Java Tree Map 86.33 ms 78 ms 75 ms 39.33 ms 76 ms 8.79 MB
Java Skip List Map 111.33 ms 106 ms 72 ms 41 ms 72.33 ms 9.19 MB