#include "GraphModel.hpp" #include "../UsefulException.hpp" #include "../format.hpp" namespace GraphC::GraphModel { Graph::Graph() {} Graph::Graph(RBTree&& _nodes, RBTree&& _edges) : nodes(_nodes), edges(_edges) {} const RBTree& 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& 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& 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; } }