Tokyo Cabinet和可变大小的C ++对象

时间:2009-08-19 21:06:24

标签: c++ serialization sizeof tokyo-cabinet

我正在构建一个使用C ++的系统,它使用Tokyo Cabinet(C中的原始API)。问题是我想存储一个类,如:

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

问题是矢量和字符串的长度可变。当我将void *(我的对象)传递给Tokyo Cabinet以便它可以存储它时,我还必须以字节为单位传递对象的大小。但这不能轻而易举地完成。

确定对象字节数的最佳方法是什么?或者在东京内阁中存储可变长度物体的最佳方法是什么。

我已经在考虑寻找序列化库。

由于

5 个答案:

答案 0 :(得分:9)

您不能将非POD C ++结构/类作为原始字节序列进行移植 - 这与指针或std::stringstd::vector的使用无关,尽管后者实际上保证它将会在实践中打破。您需要首先将对象序列化为一系列字符 - 我建议Boost.Serialization建立一个良好,灵活的跨平台序列化框架。

答案 1 :(得分:4)

我认为情况比这更糟糕。向量的实际存储不与对象的其余部分连续。您看到std::vector<>将其数据保存在堆上的单独分配中(因此,如果需要,可以扩展它们)。您需要一个能理解c ++和STL的API。

简而言之。 这不起作用。

答案 2 :(得分:0)

虽然我使用HDF5,但我遇到了类似的问题。在我的情况下,还有一个额外的要求,我可以读取对象的子部分,因此序列化不是一个真正的选项。

HDF非常像一个大型数组,其中索引用于访问数据。我使用的解决方案是在存储another_struct类型的表中添加“previous index”。

举个例子,如果'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 ]

然后,在主Entity表中,存储了最后添加的索引:

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

我对东京内阁的运作方式并不熟悉,所以尽管这种方法应该有效,但对于这种数据格式来说可能不是最佳选择。理想情况下,如果您可以指向真正的Tokyo Cabinet对象,那么您可以存储这些指针,而不是像我上面那样使用索引。

答案 3 :(得分:0)

是的,你最好使用boost序列化或protobuf对物体进行消毒并将其放入橱柜

答案 4 :(得分:0)

我使用Protocol Buffers将我的C ++对象存储为Tokyo Cabinet数据值。

在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非常快。