繁体   English   中英

C ++使用平面缓冲区在二进制文件中写入具有循环依赖性的数据

[英]c++ write data with cyclic dependencies in binary file using flatbuffers

我试图通过使用平面缓冲区将图写入二进制文件。 图由节点和边组成。 每个节点至少有一个边缘,每个边缘由两个节点组成。

摘自MyGraph.fbs:

namespace MyGraph;

table Node {
  edges:[Edge];
}

table Edge {
  startNode:Node;
  endNode:Node;
}

table Graph {
  allNodes:[Node];
}

root_type Graph;

现在,我想创建一个简单的图并将其写入字节文件:

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的edges-vector中。 是否有针对两种类型之间的这种循环依赖的解决方案。

您不能将循环结构存储在FlatBuffer中(它使用无符号偏移量强制子代始终位于父代之前)。

但是,您可以存储DAG。

要编码循环结构,您必须对节点或边缘引用使用索引,例如

table Edge {
  startNode:uint;
  endNode:uint;
}

这意味着这些节点引用是allNodes的索引。

请注意,几乎没有允许图的序列化格式,例如Protocol Buffers和JSON都只允许树。

这在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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM