GraphC/src/GraphModel/Graph.cpp

168 lines
4.4 KiB
C++

#include "GraphModel.hpp"
#include "../UsefulException.hpp"
#include "../format.hpp"
namespace GraphC::GraphModel {
Graph::Graph()
{}
Graph::Graph(RBTree<id_t, Node>&& _nodes, RBTree<id_t, Edge>&& _edges)
: nodes(_nodes), edges(_edges)
{}
const RBTree<id_t, Node>& Graph::getNodes() const {
return nodes;
}
Node* Graph::createNode(Node& n){
Node* result = nullptr;
useful_assert(nodes.tryAdd(n.id, n, &result),
format("can't create node with id %i", n.id));
return result;
}
Node* Graph::createNode(Node&& n){
return createNode(n);
}
bool Graph::tryGetNode(id_t node_id, Node** result) const {
return nodes.tryGet(node_id, result);
}
void Graph::deleteNode(Node& n){
for(const auto& attr_p : n.attributes)
deleteAttribute(*attr_p.value);
useful_assert(nodes.tryDelete(n.id),
format("can't delete node with id %i", n.id));
}
void Graph::deleteNode(Node&& n){
deleteNode(n);
}
bool Graph::tryDeleteNode(id_t node_id){
Node* n = nullptr;
if(!nodes.tryGet(node_id, &n))
return false;
deleteNode(*n);
return true;
}
const RBTree<id_t, Edge>& Graph::getEdges() const {
return edges;
}
Edge* Graph::createEdge(Attribute& from, Attribute& to){
id_t id = id_gen.getNext();
Edge* e = nullptr;
useful_assert(edges.tryAdd(id, Edge(id, from.id, to.id), &e),
format("can't create edge with id %i",id));
useful_assert(from.incoming_edges.tryAdd(id, e, nullptr),
format("edge with id %i already exists in Attribute::incoming_edges", id));
useful_assert(to.outgoing_edges.tryAdd(id, e, nullptr),
format("edge with id %i already exists in Attribute::outgoing_edges", id));
return e;
}
Edge* Graph::createEdge(Attribute&& from, Attribute&& to){
return createEdge(from, to);
}
bool Graph::tryCreateEdge(id_t from_attr_id, id_t to_attr_id, Edge** result){
Attribute* from;
if(!tryGetAttribute(from_attr_id, &from))
return false;
Attribute* to;
if(!tryGetAttribute(to_attr_id, &to))
return false;
Edge* e = createEdge(*from, *to);
if(result)
*result = e;
return true;
}
bool Graph::tryGetEdge(id_t edge_id, Edge** result) const {
return edges.tryGet(edge_id, result);
}
void Graph::deleteEdge(Edge& e){
Attribute* a = nullptr;
useful_assert(tryGetAttribute(e.from_attr_id, &a),
format("source attribute with id %i was not found in Graph::nodes", e.from_attr_id));
a->outgoing_edges.tryDelete(e.id);
useful_assert(tryGetAttribute(e.to_attr_id, &a),
format("destination attribute with id %i was not found in Graph::nodes", e.to_attr_id));
a->incoming_edges.tryDelete(e.id);
useful_assert(edges.tryDelete(e.id),
format("can't delete attribute with id %i", e.id));
}
void Graph::deleteEdge(Edge&& e){
deleteEdge(e);
}
bool Graph::tryDeleteEdge(id_t edge_id){
Edge* e;
if(!edges.tryGet(edge_id, &e))
return false;
deleteEdge(*e);
return true;
}
const RBTree<id_t, Attribute>& Graph::getAttributes() const {
return attributes;
}
bool Graph::tryGetAttribute(id_t attr_id, Attribute** result) const {
return attributes.tryGet(attr_id, result);
}
Attribute* Graph::createAttribute(Attribute& a){
Attribute* result = nullptr;
useful_assert(attributes.tryAdd(a.id, a, &result),
format("can't create attribute with id %i to Graph", a.id));
useful_assert(a.parent_node->attributes.tryAdd(a.id, result, nullptr),
format("can't add attribute with id %i to Node", a.id));
return result;
}
Attribute* Graph::createAttribute(Attribute&& a){
return createAttribute(a);
}
void Graph::deleteAttribute(Attribute& a){
for(const auto& edge_p : a.incoming_edges){
useful_assert(edges.tryDelete(edge_p.value->id),
format("can't find edge with id %i", edge_p.value->id));
}
for(const auto& edge_p : a.outgoing_edges){
useful_assert(edges.tryDelete(edge_p.value->id),
format("can't find edge with id %i", edge_p.value->id));
}
useful_assert(attributes.tryDelete(a.id),
format("can't delete attribute with id %i", a.id));
}
void Graph::deleteAttribute(Attribute&& a){
deleteAttribute(a);
}
bool Graph::tryDeleteAttribute(id_t attr_id){
Attribute* a;
if(!attributes.tryGet(attr_id, &a))
return false;
deleteAttribute(*a);
return true;
}
}