【发布时间】:2017-06-26 08:11:03
【问题描述】:
我正在尝试使用 boost 序列化库序列化一个大型(几何)图形结构。
我把我的图存储为邻接表,也就是我的结构如下:
class Node {
double x,y;
std::vector<Node*> adjacent_nodes;
...
}
class Graph {
std::vector<Node*> nodes;
...
}
现在有 > 10k 个节点,我的问题是,当我开始序列化(保存)我的图时,它会在返回之前递归调用所有这些节点的序列化,因为图是连接的。
更准确地说,在序列化 Graph 时,它会从序列化“nodes”向量中的第一个节点开始。这样做时,它需要序列化第一个节点的“adjacent_nodes”,例如包含第二个节点。
因此需要先序列化第二个节点,然后再返回第一个节点的序列化,以此类推。
我发现 this thread 从 2010 年开始,有人解释了完全相同的问题。但是,他们没有找到可行的解决方案。
任何帮助将不胜感激。
我的结构更详细:
class Node {
double x,y;
std::vector<Node*> adjacent_nodes;
public:
inline double get_x() const { return x; }
inline double get_y() const { return y; }
inline std::vector<Node*> const& get_adjacent_nodes() const { return adjacent_nodes; }
Node (double x, double y):x(x),y(y) {}
void add_adjacent(Node* other) {
adjacent_nodes.push_back(other);
}
private:
Node() {}
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive &ar, const unsigned int) {
ar & x;
ar & y;
ar & adjacent_nodes;
}
};
class Simple_graph {
std::vector<Node*> nodes;
void add_edge(int firstIndex, int secondIndex) {
nodes[firstIndex]->add_adjacent(nodes[secondIndex]);
nodes[secondIndex]->add_adjacent(nodes[firstIndex]);
}
public:
/* methods to get the distance of points, to read in the nodes, and to generate edges */
~Simple_graph() {
for (auto node: nodes) {
delete node;
}
}
private:
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive &ar, const unsigned int) {
ar & nodes;
}
};
编辑:添加在上述线程中提出的一些建议,引用 Dominique Devienne:
1) 在第一遍保存所有节点没有它们的拓扑信息 向量,从而为它们记录所有“跟踪”的指针,然后 为每个写拓扑信息,从那时起你不“递归”,你 仅将“ref”写入已序列化的指针。
2) 可以将“弱引用”写入指针, 它仅将指针添加到带有特殊标志的“跟踪”地图 说它还没有“真正”写出来,所以写拓扑 尚未写入的节点类似于“前向引用” 那些相邻的节点。要么节点真的稍后再写 开,否则永远不会,我想序列化应该处理 优雅地。
#1 不需要更改 boost 序列化,但将责任放在客户端代码上。特别是因为你必须“外部”保存 邻居,所以不再封装好,写一个子集 表面的节点变得更加复杂。
#2 需要在遇到前向引用时提前读取实际对象,此外还需要一个单独的映射到 知道在哪里寻找它。这可能与boost不兼容 序列化(我承认我对此一无所知)。
现在可以实施这些提案吗?
【问题讨论】:
标签: c++ serialization boost graph stack-overflow