提升序列化:使用根内存管理序列化树

时间:2015-10-11 18:27:25

标签: c++ serialization boost tree

我有一个自定义树数据结构,我决定进行以下设置。我有一个Tree类,左边,右边和上面(父)的普通指针,然后我有一个继承自Root的{​​{1}}类;根类处理所有内存管理。 (树需要很快,所以我买不起共享指针)。树中的每个节点都存在于根的内存池中(因此Tree将指向内存池),每个指针指向一些left()

Data

如果我想拆分节点,class Root; class Tree { public: inline Tree() : mLeft(nullptr), mRight(nullptr), mParent(nullptr), mRoot(nullptr), mData(nullptr) {} inline Tree *left() { return mLeft; } inline Tree *right() { return mRight; } inline Tree *parent() { return mParent; } inline Root *root() { return mRoot; } inline Data *data() { return mData; } inline bool isLeaf() { return mData == nullptr; } ... protected: inline Tree(Tree *parent, Root *root) : mLeft(nullptr), mRight(nullptr), mParent(parent), mRoot(root), mData(nullptr) {} Tree *mLeft; Tree *mRight; Tree *mParent; Root *mRoot; Data *mData; }; class Root : public Tree { friend class Tree; public: inline Root() : Tree(nullptr, this) {} private: MemoryPool<Data> mDataSpace; // behaves like std::set for the purposes of this example MemoryPool<Tree> mNodeSpace; }; 类使用其Tree引用来分配新的子节点。

我现在想要序列化树。 Boost提供了一个非常好的序列化库,但我不确定如何将它放入我当前的设置中。理想情况下我想写:

mRoot

我很确定这可以在保存时正常工作,但是加载呢?在成为某个其他节点的子节点之前,需要在template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & mParent; ar & mRoot; if (!isLeaf()) { left()->serialize(ar, version); ar & mLeft; ar & mRight; ar & mData; right()->serialize(ar, version); } } 中分配每个节点。那么父节点呢?我不认为Boost的序列化能够很聪明地实现这些细节,而不需要先做一些额外的工作,对吗?

为了使事情进一步复杂化,结构mDataSpace是不可变的,我不能为它编写侵入式序列化。要序列化,我可以使用Data,但要反序列化,我需要编写ar & data.x()

我假设我必须为data = Data(x);编写某种特殊的构造函数,它在根节点的内存容器中为Tree成员Tree等分配一些空间?

也许Boost序列化不是这里的理想选择?感谢您的任何指导或提示!

1 个答案:

答案 0 :(得分:1)

是的,你正走在正确的轨道上。要使Boost Serialization实例化动态对象(节点/数据),您将实现

  • save_construct_data
  • load_construct_data

您可以在Data类的上下文中阅读此内容,这些类不是默认构造http://www.boost.org/doc/libs/1_59_0/libs/serialization/doc/serialization.html#constructors

现在,对于集中分配,可以使用相同的内容。但是,我建议简单地序列化mDataSpacemNodeSpace容器,并将索引序列化为它们而不是使用boost来序列化所有跟踪的对象引用可能要容易得多。

这将不那么棘手且效率更高,因为Boost序列化不必执行Object Tracking。更重要的是,你必须确保在任何节点之前将Root序列化,你就可以了。

开箱即用:

开箱即用,我已经实现了同样的功能,但是使用Boost Intrusive来实际为我做树算法。 Boost Intrusive容器实际上并不拥有它们的元素,树根的表示方式与您在此处的方式非常相似。因此,您可以拥有node-storage +侵入式容器的元组,并免费获得所有实现细节。