Robin Hood hashing
Jun. 25th, 2014 08:59 pmПоигрался на днях в Робин Гуда - это такой вариант open addressing hash table. Open addressing - это когда данные (пары ключ-значение) все хранятся в одном большом массиве, никаких связных списков. По ключу считаем хэш, его отображаем на пространство позиций в массиве, получаем стартовую позицию, от которой уже пляшем. В простейшем случае Linear Probing мы от стартовой позиции просто последовательно идем вправо, пока не найдем нужное значение. Если мы добавляем новое значение, то так же находим стартовую позицию, от нее движемся вправо, пока не найдем свободную ячейку, там и сохраняем. Robin Hood hashing обычно описывается так: он похож на Linear Probing, при добавлении нового элемента мы так же находим стартовую позицию и движемся последовательно вправо, но поглядываем на хэши тех значений, что нам встречаются на пути, и если находим богача - которому повезло иметь более короткий путь от его стартовой позиции до занимаемой - то раскулачиваем и меняемся с ним: на место богача записываем новое значение, после чего продолжаем процесс (последовательное движение вправо) уже с этим богачом в качестве вставляемого. Такое перераспределение богатств заметно снижает число "бедняков" - значений, оказавшихся очень далеко от своей стартовой позиции, а ведь чем дальше от стартовой позиции находится значение, тем дольше до него идти при поиске, и тем больше может потребоваться линий кэша загрузить из памяти.
Когда таблица у нас большая, а значений мало, и хорошая хэш-функция их так хорошо рассредоточила, что каждое значение живет там, куда указывает хэш (на своей стартовой позиции), то все тривиально, и никакой разницы между этими алгоритмами не чувствуется. Интересные вещи начинаются, когда у нескольких разных значений стартовые позиции совпадают (а это начинает происходить очень быстро - см. birthday problem), тогда возникают кластеры - группы подряд идущих занятых ячеек в таблице. Для простоты возьмем утрированный случай, который однако позволяет получить нужную интуицию. ( Read more... )
Когда таблица у нас большая, а значений мало, и хорошая хэш-функция их так хорошо рассредоточила, что каждое значение живет там, куда указывает хэш (на своей стартовой позиции), то все тривиально, и никакой разницы между этими алгоритмами не чувствуется. Интересные вещи начинаются, когда у нескольких разных значений стартовые позиции совпадают (а это начинает происходить очень быстро - см. birthday problem), тогда возникают кластеры - группы подряд идущих занятых ячеек в таблице. Для простоты возьмем утрированный случай, который однако позволяет получить нужную интуицию. ( Read more... )