【问题标题】:c++ write data with cyclic dependencies in binary file using flatbuffersc ++使用flatbuffers在二进制文件中写入具有循环依赖关系的数据
【发布时间】:2015-12-03 14:42:25
【问题描述】:

我正在尝试使用 flatbuffers 将 Graph 写入二进制文件。图由节点和边组成。每个节点至少有一条边,每条边由两个节点组成。

摘自 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);

问题是,在创建节点后,我无法将边添加到节点 1 和节点 2 的边向量中。有没有办法解决两种类型之间的那种循环依赖关系。

【问题讨论】:

    标签: c++ flatbuffers


    【解决方案1】:

    您不能将循环结构存储在 FlatBuffer 中(它强制孩子总是在父母之前,使用无符号偏移量)。

    不过,您可以存储 DAG。

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

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

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

    请注意,允许图形的序列化格式很少,例如Protocol Buffers 和 JSON 都只允许树。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2020-11-22
        • 2021-12-26
        • 1970-01-01
        • 1970-01-01
        • 2012-01-24
        • 1970-01-01
        • 2014-09-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多