168 lines
4.4 KiB
C++
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.second);
|
|
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.second->id),
|
|
format("can't find edge with id %i", edge_p.second->id));
|
|
}
|
|
for(const auto& edge_p : a.outgoing_edges){
|
|
useful_assert(edges.tryDelete(edge_p.second->id),
|
|
format("can't find edge with id %i", edge_p.second->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;
|
|
}
|
|
|
|
} |