c ++ записывает данные с циклическими зависимостями в двоичный файл, используя плоские буферы

Я пытаюсь записать график в двоичный файл с помощью плоских буферов. Граф состоит из узлов и ребер. Каждый узел имеет хотя бы одно ребро, и каждое ребро состоит из двух узлов.

Выдержка из 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. Есть ли решение для такого рода циклических зависимостей между двумя типами.

1

Решение

Вы не можете хранить циклические структуры в FlatBuffer (он обеспечивает, что дети всегда идут перед родителями, используя смещения без знака).

Однако вы можете хранить DAG.

Чтобы закодировать циклическую структуру, вам придется использовать индексы для узлов или Edge-ссылок, например,

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

Это означает, что эти ссылки на узлы являются индексом allNodes,

Обратите внимание, что существует очень мало форматов сериализации, которые позволяют графы, например, Буферы протокола и JSON разрешают только деревья.

1

Другие решения

Это работает в 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

0

По вопросам рекламы [email protected]