Как сохранить хеш-таблицу в файле?

Как я могу сохранить хеш-таблицу с отдельной цепочкой в ​​файле на диске?

Генерация данных, хранящихся в хеш-таблице во время выполнения, обходится дорого, было бы быстрее просто загрузить HT с диска... если бы я только мог понять, как это сделать.

Изменить: поиск выполняется с загруженным в память HT. Мне нужно найти способ сохранить хеш-таблицу (в памяти) в файл в каком-то двоичном формате. Так что в следующий раз, когда программа запустится, она может просто загрузить HT с диска в оперативную память.

Я использую С++.


person Girish    schedule 07.02.2009    source источник
comment
Будете ли вы выполнять поиск с диска или вам нужно только сохранить хэш-таблицу?   -  person Hank    schedule 07.02.2009
comment
Хэнк, поиск выполняется с загруженным в память HT. Да, мне просто нужно сохранить хеш-таблицу.   -  person Girish    schedule 07.02.2009
comment
пожалуйста, предоставьте более подробную информацию - язык, система и т. д.   -  person Eli Bendersky    schedule 07.02.2009
comment
Я добавил теги: сериализация c++.   -  person jfs    schedule 08.02.2009


Ответы (6)


Какой язык вы используете? Обычный метод - выполнить какую-то двоичную сериализацию.

Хорошо, я вижу, вы отредактировали, чтобы добавить язык. Для С++ есть несколько вариантов. Я считаю, что механизм сериализации Boost довольно хорош. Кроме того, на странице библиотеки сериализации Boost также описаны альтернативы. Ссылка здесь:

http://www.boost.org/doc/libs/1_37_0/libs/serialization/doc/index.html

person BobbyShaftoe    schedule 07.02.2009
comment
› Какой язык вы используете? Я использую С++. › Обычный метод — выполнить некоторую двоичную сериализацию. Не могли бы вы уточнить это? Я не знаю о двоичной сериализации. Я хотел бы добавить, что это также учебное упражнение для меня, поэтому я хотел бы сделать все это вручную. :) - person Girish; 07.02.2009

Предполагая C/C++: используйте индексы массива и структуры фиксированного размера вместо указателей и распределения переменной длины. Вы должны иметь возможность напрямую писать() структуры данных в файл для последующего чтения().

Для чего-либо более высокого уровня: многие API-интерфейсы более высокого уровня имеют средства сериализации. И в Java, и в Qt/C++ есть методы, которые сразу приходят на ум, поэтому я знаю, что и у других они тоже есть.

person Ryan Graham    schedule 07.02.2009

Вы можете просто записать всю структуру данных непосредственно на диск, используя сериализацию (например, в Java). Однако вам может потребоваться прочитать весь объект обратно в память, чтобы получить доступ к его элементам. Если это нецелесообразно, вы можете рассмотреть возможность использования файла произвольного доступа для хранения элементов хэш-таблица. Вместо того, чтобы использовать указатель для представления следующего элемента в цепочке, вы просто использовали бы позицию байта в файле.

person Zach Scrivena    schedule 07.02.2009
comment
Зак, «несвязанный вопрос» Я все еще новичок в переполнении стека, как я могу отвечать на отдельные сообщения? Можно/желательно ли сделать пост так, чтобы он появлялся вместе с постами других людей(ответ) или нужно просто отвечать на отдельные посты через комментарии(добавить комментарий)? - person Girish; 07.02.2009
comment
@Girish: Добро пожаловать в сообщество =) Если ваш ответ краток и специфичен для поста, просто добавьте комментарий. Более длинные ответы, которые могут быть полезны другим, должны быть в исходном вопросе (нажмите изменить). Никогда не публикуйте ответ или дополнительную информацию в качестве нового ответа (потому что это не так). - person Zach Scrivena; 07.02.2009
comment
Понял, спасибо. Под файлом с произвольным доступом вы подразумеваете fseek() для файла? ... Точно сказать не могу. - person Girish; 07.02.2009

Откажитесь от указателей на индексы.

Это немного похоже на создание на диске DAWG, что я сделал некоторое время назад. Что сделало это таким приятным, так это то, что его можно было загрузить напрямую с помощью mmap вместо чтения файла. Если хеш-пространство управляемо, скажем, 216 или 224 записей, то я думаю, что сделал бы что-то вроде этого:

  • Держите список бесплатных индексов. (если таблица пуста, каждый индекс цепочки будет указывать на следующий индекс.)
  • Когда требуется цепочка, используйте свободное место в таблице.
  • Если вам нужно поместить что-то в индекс, который занят скваттером (переполнение из другого места):
  • запишите индекс (назовем его N)
  • поменять местами новый элемент и скваттер
  • поместите скваттер в новый свободный индекс (F).
  • следуйте по цепочке хэш-индекса скваттера, чтобы заменить N на F.
  • Если у вас полностью закончились свободные индексы, вам, вероятно, понадобится таблица большего размера, но вы можете справиться немного дольше, используя mremap для создания дополнительного места после таблицы.

Это должно позволить вам отображать и использовать таблицу напрямую, без изменений. (страшно быстро, если в кеше ОС!) но вам нужно работать с индексами вместо указателей. Довольно пугающе иметь мегабайты, доступные во время syscall-round-trip-time, и при этом занимать меньше, чем в физической памяти, из-за подкачки.

person Anders Eurenius    schedule 07.02.2009
comment
Фиксированная ссылка... или это была en.wikipedia.org/wiki/Suffix_automaton? Теперь я не уверен. - person Andrew; 25.06.2020

Возможно, вам будет полезна DBM.

person Eli Bendersky    schedule 07.02.2009
comment
Вы проверили лицензию на это? Либо вы делаете свое приложение с открытым исходным кодом, либо платите Sleepycat довольно высокую (для всех, кроме очень крупной корпорации) лицензионную плату. - person Ryan Graham; 09.02.2009

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

person Pete Kirkham    schedule 07.02.2009