我试图使用flatbuffers将Graph写入二进制文件。图由节点和边组成。每个节点至少有一个边,每个边包含两个节点。
摘自MyGraph.fbs:
namespace MyGraph;
table Node {
edges:[Edge];
}
table Edge {
startNode:Node;
endNode:Node;
}
table Graph {
allNodes:[Node];
}
root_type Graph;
现在我想创建一个简单的图并将其写入bytefile:
FlatBufferBuilder fbb;
// create first node
auto node1mloc = DG::CreateNode(fbb, 0, 0);
// create second node
auto node2mloc = DG::CreateNode(fbb, 0, 0);
// create edge between first and second node
auto edgeloc = DG::CreateEdge(fbb, node1mloc, node2mloc);
// ???
// store the edge in the edges-vector of node1 and node2
// ???
// store nodes in graph
flatbuffers::Offset<Node> nodes[] = {node1mloc, node2mloc};
auto allNodes = fbb.CreateVector(nodes, 2);
auto graphloc = DG::CreateGraph(fbb, allNodes);
DG::FinishGraphBuffer(fbb, graphloc);
// write graph into file
auto buffer_pointer = fbb.GetBufferPointer();
SaveFile("myfile2.bin", reinterpret_cast<const char *>(buffer_pointer), fbb.GetSize(), true);
// load graph from file
string binData;
LoadFile("myfile2.bin", true, &binData);
auto graph = DG::GetGraph(binData.data());
cout << graph->allNodes()->size() << endl;
assert(graph->allNodes()->size() == 2);
问题是,在创建节点之后,我无法将边缘添加到node1和node2的edge-vector。是否存在两种类型之间的那种循环依赖关系的解决方案。
答案 0 :(得分:1)
你不能在FlatBuffer中存储循环结构(它强制孩子总是在父母之前,使用无符号偏移)。
但是,您可以存储DAG。
要对循环结构进行编码,您必须使用索引进行节点或边缘引用,例如
table Edge {
startNode:uint;
endNode:uint;
}
这意味着这些节点引用是allNodes
的索引。
请注意,很少有允许图表的序列化格式,例如Protocol Buffers和JSON都只允许树。
答案 1 :(得分:0)
这适用于FlatBuffersSwift,但在官方FlatBuffers实现中不受支持。
//: Playground - noun: a place where people can play
import Foundation
var str = "Hello, playground"
let (f1, f2, f3, f4) = (Friend(), Friend(), Friend(), Friend())
f1.name = "Maxim"
f2.name = "Leo"
f3.name = "Boris"
f4.name = "Marc"
let f5 = Friend()
f5.name = "Daria"
f1.friends = [f1, f2, f3, f4]
f2.friends = [f1, f4]
f3.friends = [f2, f4]
f1.lover = Female(ref: f5)
f5.lover = Male(ref: f1)
f1.father = Friend()
f1.father?.name = "Issai"
f1.mother = Friend()
f1.mother?.name = "Margo"
let data = f1.toByteArray()
let f = Friend.fromByteArray(UnsafeBufferPointer(start:UnsafePointer<UInt8>(data), count: data.count))
print(f.friends[2]?.friends[0]?.friends[0]?.name)
print(((f.lover as? Female)?.ref?.lover as? Male)?.ref?.name)
let lazyF = Friend.Fast(data)
let girlFriend = (lazyF.lover as! Female.Fast).ref
let boyFriend = (girlFriend?.lover as! Male.Fast).ref
lazyF == boyFriend
我在google群组中询问是否对主要项目感兴趣。 似乎不会很快发生。
https://groups.google.com/forum/#!topic/flatbuffers/Y9K9wRKSHxg