Tokyo Cabinet и объекты C ++ переменного размера - PullRequest
2 голосов
/ 20 августа 2009

Я строю систему с C ++, которая использует Tokyo Cabinet (оригинальный API на C). Проблема в том, что я хочу сохранить класс, такой как:

    class Entity {
      public:
        string entityName;
        short type;
        vector<another_struct> x;
        vector<another_struct> y
        vector<string> z;
    };

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

Как лучше всего определить количество байтов объекта? Или как лучше всего хранить объекты переменной длины в Tokyo Cabinet.

Я уже думаю о поиске библиотек для сериализации.

Спасибо

Ответы [ 5 ]

9 голосов
/ 20 августа 2009

Нельзя переносить структуру / класс не-POD C ++ как необработанную последовательность байтов - это не зависит от использования указателей или std::string и std::vector, хотя последние практически гарантируют, что они будут ломаться на практике. Сначала нужно сериализовать объект в последовательность символов - я бы предложил Boost.Serialization для хорошей гибкой кросс-платформенной среды сериализации.

4 голосов
/ 20 августа 2009

Я думаю, что это хуже, чем это. Фактическое хранилище для векторов не является смежным с остальной частью объекта. Вы видите, что std::vector<> хранят свои данные в отдельном распределении в куче (чтобы они могли расширять их при необходимости). Вам понадобится API, который понимает c ++ и STL.

Короче. Это не сработает.

0 голосов
/ 31 декабря 2009

Я использую Буферы протокола для хранения моих объектов C ++ как значений данных Токийского Кабинета.

В Protocol Buffers вы указываете структуру, а затем генерируете код маршалинга / демаршаллинга для C ++, Python и Java. В вашем случае файл .proto будет выглядеть так:

message Entity {
    optional string entityName = 1;
    optional int32 type = 2; //protobuf has no short
    short type = 3;
    repeated AnotherStruct x = 4;
    repeated AnotherStruct y = 5;
    repeated string z = 6;
};

Особенно, если база данных существует в течение длительного промежутка времени, система, которая может быть обновлена, например, покрывать новые поля очень ценно. В отличие от XML и других, protobuf довольно быстрый.

0 голосов
/ 18 декабря 2009

да, вам лучше использовать сериализацию наддува или протобуф, чтобы стерилизовать объект и поместить его в кабинет

0 голосов
/ 20 августа 2009

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

HDF очень похож на большой массив, в котором для доступа к данным используется индекс. Решение, которое я использую, заключается в добавлении «предыдущего индекса» к таблице, в которой хранится тип another_struct.

Если взять ваш пример, если бы 'x' и 'y' имели по 3 и 2 элемента каждый, то данные будут сохранены следующим образом:

[ index ] [ another_struct data here ] [ previous_index ]
[   0   ] [       x data 0           ] [ -1 ]
[   1   ] [       x data 1           ] [  0 ]
[   2   ] [       x data 2           ] [  1 ]
[   3   ] [       y data 0           ] [ -1 ]
[   4   ] [       y data 1           ] [  3 ]

И затем в основной таблице сущностей сохраняется последний добавленный индекс:

[ index ] [ Entity data here ] [ x ] [  y ]
[   0   ] [        ...       ] [ 2 ] [  4 ]

Я не очень знаком с тем, как работает Токийский кабинет, поэтому, хотя этот подход должен работать, он не может быть оптимальным для этого формата данных. В идеале, если вы можете иметь указатели на реальные объекты Tokyo Cabinet, тогда вместо использования индексов, как я указал выше, вы можете хранить эти указатели.

...