Постоянство надстройки multi_index_container, хранящегося в файле

Могу ли я рассчитывать на повышение multi_index_container, размещенное в файле отображения памяти? Будет ли эта «база данных» переносимой между компьютерами с одинаковым порядком байтов?

2

Решение

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

Отображенный файл памяти Boost занимает hint, но это только намек.

Таким образом, при первом вызове память может находиться в 0xBAADF00D, На втором вызове это может быть расположено в 0xF00DBAAD, Указатели внутри структуры больше не будут действительными, так как они будут указывать на память вокруг 0xBAADF00D а не вокруг 0xF00DBAAD,

Как серьезная проблема, это может обычно работать в тестировании, как hint обычно можно повиноваться — но иногда по этому адресу памяти уже будет что-то hint придется игнорировать.

(Существуют и другие части, которые делают это действительно сложно — но вышеизложенное делает это довольно неосуществимым).

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

2

Другие решения

Если вы хотите перевезти multi_index с одного компьютера на другой лучше всего использовать Boost.Serialization, который работает из коробки:

http://www.boost.org/doc/libs/1_60_0/libs/multi_index/doc/tutorial/creation.html#serialization

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <fstream>
...
void save(const employee_set& es)
{
std::ofstream ofs("data");
boost::archive::text_oarchive oa(ofs);
oa<<es;
}

void load(employee_set& es)
{
std::ifstream ifs("data");
boost::archive::text_iarchive ia(ifs);
ia>>es;
}
...
employee_set es; // a multi_index type
... // fill it with data
save(es);
...
employee_set restored_es;
load(restored_es);
0

С помощью Файлы, отображаемые в памяти Boost.Interprocess и немного заботы, вы можете сохраняться multi_index_containers; проблема сопоставления расположений по разным адресам может быть решена с помощью смещения а не указатели, и Boost.MultiIndex готов обработать это: см. этот пример где реализована своего рода упрощенная база данных с доступом к нескольким процессам одновременно.

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

  • машинная архитектура
  • версия операционной системы
  • версия компилятора
  • параметры компиляции (например, которые могут повлиять на заполнение)
  • версия всех соответствующих используемых библиотек (включая Boost), поскольку ABI могут меняться в зависимости от версии
  • некоторые другие аспекты, о которых я забыл 🙂

Учитывая все вышесказанное, использование Boost.Serialization, предложенное @alfC, вероятно, является лучшим решением для портативный постоянство в разных средах. Если вы беспокоитесь о скорости, может подойти такой смешанный подход:

  • Находясь в сеансе и в контексте нескольких процессов (в идеале, из одного исполняемого файла), использующих одну и ту же структуру на одном и том же компьютере, карта памяти отображает контейнер.
  • После завершения сеанса (или время от времени для защиты от сбоев и т. Д.) Сохраняйте переносимость с помощью Boost.Serialization.
0