Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> boost.serialization и отложенная иничиализация 
V
    Опции темы
boostcoder
Дата 1.4.2010, 07:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



всем доброго времени суток.

хочу сериализовать структуру каталогов ФС.
есть следующий тип:
Код

// первый параметр - буфер, второй - crc32
typedef std::pair<std::string, boost::uint32_t> piece_t; // одна из частей файла

// первый параметр - имя файла, второй - список частей
typedef std::pair<std::string, std::vector<piece_t> > file_t; // файл

// список файлов в каталоге
typedef std::vector<file_t> list_t;

// первый параметр - имя каталога, второй - список файлов в нем
typedef std::map<std::string, list_t> tree_t;

все работает, все хорошо. за исключением одного НО!
прежде чем сериализовать объект типа "tree_t", его нужно подготовить.
т.е. прочитать структуру каталога, прочитать каждый файл, разбить его на части, загрузить каждую часть в буфер, подсчитать crc32 для каждой части.
но этот вариант мне не нравится по нескольким причинам:
1. структура каталога, может занимать много гигов. соответственно, и объем занимаемой памяти требуется такой-же, плюс чуть-чуть.
2. как-то, этот подход, мне кажется "деревянным" и неправильным.

вот чего я хочу:
чтоб каждый элемент типа "file_t", инициализировался именно в момент его сериализации.
Код

tree_t tree;
...
// добавляю элементы, частично инициализировав их
tree["path"].push_back(std::make_pair("file_name", std::vector<piece_t>()));

в примере, я создаю структуру каталогов, добавляю в нее файлы, не обрабатывая их.

мне нужна возможность, "сообщить" boost.serialization, каким образом "обрабатывать" объекты некоторого типа.
в идеале, чтоб можно было "заставить" boost.serialization, выполнить operator() для объектов некоторого типа.

благодарен всем отозвавшимся.

Это сообщение отредактировал(а) boostcoder - 1.4.2010, 07:55
PM WWW   Вверх
W4FhLF
Дата 1.4.2010, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



Ну делай отложенную загрузку в методе serialize во время непосредственно сериализации.


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
boostcoder
Дата 1.4.2010, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



W4FhLF, в методе serialize(), инициализировать нет смысла. т.к. все вышеописанные недостатки останутся.
а же хочу инициализировать некоторые типы _непосредственно_при_сериализации_
допустим тип:
Код

// первый параметр - имя файла, второй - список частей
typedef std::pair<std::string, std::vector<piece_t> > file_t; // файл

PM WWW   Вверх
boostcoder
Дата 1.4.2010, 10:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



в данный момент, де/сериализация происходит следующим образом:
Код

struct any {
   tree_t tree;
   ...
   template<typename archive_type>
   void serialize(archive_type & ar, const unsigned int) {
      ar & tree;
   }
};

как вариант, tree_t разбить на отдельные подтипы. но как назначить для определенного подтипа, его, особенный сериализатор, я тоже не знаю.
нужно пробовать..
PM WWW   Вверх
W4FhLF
Дата 1.4.2010, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



Ленивых вычислений в С++ нет, поэтому напрямую это решить нельзя. 

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


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
boostcoder
Дата 1.4.2010, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



W4FhLF, я так же подумал.
за BOOST_SERIALIZATION_SPLIT_MEMBER() как-то сразу не вспомнил.
в общем пробую..
PM WWW   Вверх
boostcoder
Дата 1.4.2010, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



с записью архива разобрался. начать писать чтение, и споткнулся.
объясню в чем проблема...

в данный момент, сериализую такой тип:
Код

template<boost::uint32_t piece_size = 4096>
struct file_t {
   file_t() {}
   file_t(const std::string& fn, const std::string& rn):fname(fn),rname(rn) {}

private:
   template<typename archive_type>
   void save(archive_type& ar, const unsigned int) const {
      // вызывается в момент сериализации
      // т.к. имя файла я назначил в момент вставки в std::map<>
      // я его использую для открытия и обработки реального файла
      ...
      ar & fname; // сохраняю имя файла "в архиве"
   }
   template<typename archive_type>
   void load(archive_type& ar, const unsigned int) {
      // вызывается в момент ДЕсериализации
      // но откуда мне брать _значение_ключа_ при ДЕсериализации ?!
      ...
      ar & fname; // читаю имя файла "в архиве"
      // но для того чтоб ДЕсериализовать сам файл, его нужно
      // создать на ФС и записывать части. НО, для этого, мне нужно знать
      // каталог в котором создать файл. Как ?!
   }

private:
   std::string fname; // имя файла в архиве
   std::string rname; // реальное имя на ФС
};

typedef std::vector<file_t<> > list_t;
typedef std::map<std::string, list_t> tree_t;

struct compressor {
...
   tree_t tree;

   // вставляю элементы, которым указываю только имя файла
   // обрабатывается файл в момент сериализации.
   tree["path"].push_back(file_t<piece_size>("file_name", "real_file_name"));

...
   archive << tree; // сериализую
...
   archive >> tree; // ДЕсериализую

private:
   template<typename archive_type>
   void save(archive_type & ar, const unsigned int) const {
      // собственно сериализует.
      // записывает ключи/значения и
      // вызывает file_t::save() для каждого элемента
      ar & tree;
   }

   template<typename archive_type>
   void load(archive_type & ar, const unsigned int) {
      // собственно ДЕсериализует.
      // читает ключи/значения и
      // вызывает file_t::load() для каждого элемента
      // НО, как мне узнать _значение_ключа_ в момент
      // вызова file_t::load() ?!
      ar & tree;
   }
};


Добавлено через 7 минут и 29 секунд
наверное, этот тип:
Код

typedef std::map<std::string, list_t> tree_t;

так же, придется заменить своим классом....если вариантов других не окажется.

Это сообщение отредактировал(а) boostcoder - 1.4.2010, 15:20
PM WWW   Вверх
W4FhLF
Дата 1.4.2010, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



Так значения ключей у тебя записываются при save в архив. В чём именно затык? У буста есть serializers для стандартных типов, он записывает ключи и значения сам в нужном порядке. При чтении грузит их в обратном порядке сам. 


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
boostcoder
Дата 1.4.2010, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(W4FhLF @  1.4.2010,  15:24 Найти цитируемый пост)
В чём именно затык?

в том, что когда он сериализует тип tree_t, значения ключей в нем уже есть. и сохраняет он значения ключей, сам, без моего вмешательства.
но в обратном порядке, мне _нужно_получить_значение_ключа_ до_ вызова file_t::load()


Это сообщение отредактировал(а) boostcoder - 1.4.2010, 15:37
PM WWW   Вверх
W4FhLF
Дата 1.4.2010, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



А зачем тебе его нужно получать до вызова? Я так понял ты хотел сделать отложенную инициализацию при сохранении. А при загрузке тебе оно зачем? Это всё равно, что взять и расчитать всё заново. Смысл тогда хранить всё это на винте?

Добавлено через 1 минуту и 36 секунд
Сохраняй и загружай тогда только ключи, а их значения расчитывай перед сохранеием и после загрузки. Но я не понимаю зачем тогда сохранять значения, если при загрузке ты их всё равно собрался расчитывать. 


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
boostcoder
Дата 1.4.2010, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



наверное я неточно выражаюсь..

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

наверное так будет точнее.
PM WWW   Вверх
W4FhLF
Дата 1.4.2010, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



А зачем тебе получать ключ до вызова file_t::load? 


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
boostcoder
Дата 1.4.2010, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



потому что ключ - это имя каталога в котором необходимо создать файл, для его десериализации.
PM WWW   Вверх
W4FhLF
Дата 1.4.2010, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



boostcoder, тогда надо хранить структуру каталогов и имён файлов отдельно от их содержимого.

Это сообщение отредактировал(а) W4FhLF - 1.4.2010, 16:37


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
boostcoder
Дата 1.4.2010, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(W4FhLF @  1.4.2010,  16:37 Найти цитируемый пост)
тогда надо хранить структуру каталогов и имён файлов отдельно от их содержимого.

пришло понимание.
собственно я так и предположил:
Цитата(boostcoder @  1.4.2010,  15:14 Найти цитируемый пост)
наверное, этот тип:
typedef std::map<std::string, list_t> tree_t;
так же, придется заменить своим классом....если вариантов других не окажется.


значит придется заменить.

сильно благодарен.
вопрос закрыт.
PM WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0710 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.