Кукушка хеширование в C

У кого-нибудь есть реализация хеширование кукушки в C? Если бы был открытый исходный код, не версия GPL, это было бы идеально!

поскольку Адам упомянул об этом в своем комментарии, кто-нибудь знает, почему это не используется? Это просто вопрос реализации или хорошие теоретические свойства не материализуются на практике?

8 ответов



как указывали другие ответы, это правда, что самый простой хэш-таблица кукушки требует, чтобы таблица была наполовину пустой. Однако понятие было обобщено на d - Ары кукушка хеширование, в котором каждый ключ имеет d возможные места для гнезда, в отличие от 2 мест в простой версии.

приемлемый коэффициент нагрузки увеличивается быстро, как d увеличивается. Только для d=3, вы уже можете использовать около 75% полная таблица. Этот недостатком является то, что вам нужно d независимые хеш-функции. Я поклонник хэш-функций Боба Дженкинса для этой цели (см.http://burtleburtle.net/bob/c/lookup3.c), который вы можете найти полезным в реализации хэширования кукушки.


хеширование кукушки относительно не используется вне академических кругов (кроме аппаратных кэшей, которые иногда заимствуют идеи, но на самом деле не реализуют полностью). Это требует очень разреженной хэш-таблицы, чтобы получить хорошее время на вставках - вам действительно нужно иметь 51% вашей таблицы пустой для хорошей производительности. Таким образом, он либо быстрый и занимает много места, либо медленный и эффективно использует пространство - никогда не оба. Другие алгоритмы эффективны как во времени, так и в пространстве, хотя они хуже, чем cuckoo, когда учитывается только время или пространство.

здесь генератор кода для хеш-таблиц cuckoo. Проверьте лицензию генератора, чтобы убедиться, что выход не является GPL. Должно быть, но все равно проверь.

Адам


хотя это старый вопрос, кто-то еще может быть интересно :)

этой статье описывает реализацию параллельного хэша D-ary cuckoo на графических процессорах (CUDA / OpenCL). Он описан очень хорошо, и его реализация на основе описания довольно проста. Вообще стоит почитать, если вас интересует эта тема. (Вам понадобится ACM-логин.)


язык ввода-вывода имеет один, в PHash.c. Вы можете найти код для ввода-вывода на Github. IO имеет лицензию BSD.


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

насколько мне известно, возможными альтернативами хэш-таблицам для создания динамического словаря являются (сбалансированные) двоичные деревья и скиплисты. Просто для обсуждения давайте абстрагируемся от типов ключей и значений и предположим, что мы получим доступ к значениям через void *.

для двоичного дерева я бы есть:

struct node {
  void *key;
  void *value;
  struct node *left;
  struct node *right;
}

Итак, предполагая, что указатели имеют одинаковый размер s, в магазине n элементы, которые мне понадобятся 4 s байт.

Skiplists почти такие же, как среднее количество указателей в узле-2.

в хэш-таблице у меня было бы:

struct slot {
  void *key;
  void *value;
}

таким образом, каждый элемент будет только requre 2 s байты для хранения. Если коэффициент загрузки составляет 50%, хранить n детали мне будут нужны же 4 s байт, как деревья.

мне это не кажется слишком плохим: хэш-таблица cuckoo будет занимать более или менее тот же объем памяти, что и двоичное дерево, но даст мне O(1) время доступа, а не O(log n).

не считая сложности поддержания сбалансированности дерева и дополнительной информации, которая может потребоваться для хранения балансирующей информации в узле.

другие схемы хэширования могут достичь лучшего коэффициента нагрузки (скажем, 75% или 80%) с нет гарантии на худший случай времени доступа(это может быть даже O (n) ).

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


Я не могу говорить о программном обеспечении, но хеширование кукушки, безусловно, используется в аппаратном обеспечении и становится очень популярным. Основные поставщики сетевого оборудования изучают хеширование кукушки, а некоторые уже используют его. Притяжение к хешированию кукушки происходит от постоянного времени поиска, конечно, но также и от почти постоянного времени вставки.

хотя теоретически вставка может быть неограниченной, на практике она может быть ограничена O (log n) числа строк в таблице(таблицах) и когда измеренное время вставки составляет в среднем около 1,1*d доступа к памяти. Это всего на 10% больше абсолютного минимума! Доступ к памяти часто является ограничивающим фактором в сетевом оборудовании.

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


после комментария от "onebyone" я реализовал и протестировал несколько версий хеширования Cuckoo, чтобы определить реальное требование к памяти.

после некоторого эксперимента утверждение, что вам не нужно переназначать, пока таблица не будет заполнена почти на 50%, кажется верным, особенно если "притон" трюк реализуемых.

проблема в том, когда вы увеличиваете таблицу. Обычный подход-удвоить его размер, но это приводит к тому, что новая таблица будет только 25% используется!

на самом деле, предположим, что хэш-таблица имеет 16 слотов, когда я вставляю номер 8-го элемента, у меня закончатся хорошие слоты и придется переназначить. Я удвою его, и теперь таблица 32 слота с только 8 из них заняты, что является 75% отходов!

это цена, которую нужно заплатить, чтобы иметь "постоянное" время извлечения (с точки зрения верхней границы для числа доступа/сравнения).

Я разработал другую схему, хотя: начиная с мощности 2 больше 1, если таблица имеет N слотов и N-степень двух, добавьте N/2 слотов в противном случае добавьте n / 3 слотов:

+--+--+
|  |  |                             2 slots
+--+--+

+--+--+--+
|  |  |  |                          3 slots
+--+--+--+ 

+--+--+--+--+
|  |  |  |  |                       4 slots
+--+--+--+--+

+--+--+--+--+--+--+
|  |  |  |  |  |  |                 6 slots
+--+--+--+--+--+--+

+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |           8 slots
+--+--+--+--+--+--+--+--+

etc.

вместе с предположением, что переназначение будет происходить только тогда, когда таблица заполнена на 50%, это приводит к тому, что таблица будет только 66% пустой (1/3), а не 75% пустой (1/4) после reash (т. е. в худшем случае).

Я также выяснил (но мне все еще нужно проверить математику), что увеличение каждый раз на sqrt (n), потерянное пространство асимптотически приближается к 50%.

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

Я собираюсь исследовать дальше, если кто-то заинтересован.