Tulip  6.0.0
Large graphs analysis and drawing
GraphUpdatesRecorder.h
1 /*
2  *
3  * This file is part of Tulip (https://tulip.labri.fr)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux
7  *
8  * Tulip is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * Tulip is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  */
19 ///@cond DOXYGEN_HIDDEN
20 
21 #ifndef TLPGRAPHRECORDER_H
22 #define TLPGRAPHRECORDER_H
23 
24 #include <string>
25 #include <set>
26 #include <unordered_set>
27 #include <vector>
28 
29 #include <tulip/Graph.h>
30 #include <tulip/MutableContainer.h>
31 #include <tulip/tuliphash.h>
32 
33 namespace std {
34 template <>
35 struct less<tlp::Graph *> {
36  size_t operator()(const tlp::Graph *g1, const tlp::Graph *g2) const {
37  // the id order corresponds to the creation order
38  // so when dealing with a set<Graph*> this will ensure that
39  // we encounter a supergraph before its subgraphs
40  return g1->getId() < g2->getId();
41  }
42 };
43 } // namespace std
44 
45 namespace tlp {
46 class GraphImpl;
47 class GraphStorageIdsMemento;
48 
49 class GraphUpdatesRecorder : public Observable {
50  friend class GraphImpl;
51 //
52 #if !defined(NDEBUG)
53  bool recordingStopped;
54 #endif
55  bool updatesReverted;
56  bool restartAllowed;
57  bool newValuesRecorded;
58  const bool oldIdsStateRecorded;
59 
60  // one 'set' of added nodes per graph
61  tlp_hash_map<Graph *, std::unordered_set<node>> graphAddedNodes;
62  // the whole 'set' of added nodes
63  std::unordered_set<node> addedNodes;
64  // one 'set' of deleted nodes per graph
65  tlp_hash_map<Graph *, std::unordered_set<node>> graphDeletedNodes;
66  // one 'set' of added edges per graph
67  std::map<Graph *, std::unordered_set<edge>> graphAddedEdges;
68  // ends of all added edges
69  tlp_hash_map<edge, std::pair<node, node>> addedEdgesEnds;
70  // one 'set' of deleted edges per graph
71  std::map<Graph *, std::unordered_set<edge>> graphDeletedEdges;
72  // ends of all deleted edges
73  tlp_hash_map<edge, std::pair<node, node>> deletedEdgesEnds;
74  // one set of reverted edges
75  std::unordered_set<edge> revertedEdges;
76  // source + target per updated edge
77  tlp_hash_map<edge, std::pair<node, node>> oldEdgesEnds;
78  // source + target per updated edge
79  tlp_hash_map<edge, std::pair<node, node>> newEdgesEnds;
80  // one 'set' for old edge containers
81  tlp_hash_map<node, std::vector<edge>> oldContainers;
82  // one 'set' for new edge containers
83  tlp_hash_map<node, std::vector<edge>> newContainers;
84 
85  // copy of nodes/edges id manager state at start time
86  const GraphStorageIdsMemento *oldIdsState;
87  // copy of nodes/edges id manager state at stop time
88  const GraphStorageIdsMemento *newIdsState;
89 
90  // one list of (parent graph, added subgraph)
91  std::list<std::pair<Graph *, Graph *>> addedSubGraphs;
92  // one list of (parent graph, deleted subgraph)
93  std::list<std::pair<Graph *, Graph *>> deletedSubGraphs;
94 
95  // one set of added properties per graph
96  tlp_hash_map<Graph *, std::set<PropertyInterface *>> addedProperties;
97  // one set of deleted properties per graph
98  tlp_hash_map<Graph *, std::set<PropertyInterface *>> deletedProperties;
99  // one set of old attribute values per graph
100  tlp_hash_map<Graph *, DataSet> oldAttributeValues;
101  // one set of new attribute values per graph
102  tlp_hash_map<Graph *, DataSet> newAttributeValues;
103 
104  // one set of updated addNodes per property
105  tlp_hash_map<PropertyInterface *, std::set<node>> updatedPropsAddedNodes;
106 
107  // one set of updated addEdges per property
108  tlp_hash_map<PropertyInterface *, std::set<edge>> updatedPropsAddedEdges;
109 
110  // the old default node value for each updated property
111  tlp_hash_map<PropertyInterface *, DataMem *> oldNodeDefaultValues;
112  // the new default node value for each updated property
113  tlp_hash_map<PropertyInterface *, DataMem *> newNodeDefaultValues;
114  // the old default edge value for each updated property
115  tlp_hash_map<PropertyInterface *, DataMem *> oldEdgeDefaultValues;
116  // the new default edge value for each updated property
117  tlp_hash_map<PropertyInterface *, DataMem *> newEdgeDefaultValues;
118  // the old name for each renamed property
119  tlp_hash_map<PropertyInterface *, std::string> renamedProperties;
120 
121  struct RecordedValues {
122  PropertyInterface *values;
123  MutableContainer<bool> *recordedNodes;
124  MutableContainer<bool> *recordedEdges;
125 
126  RecordedValues(PropertyInterface *prop = nullptr, MutableContainer<bool> *rn = nullptr,
127  MutableContainer<bool> *re = nullptr)
128  : values(prop), recordedNodes(rn), recordedEdges(re) {}
129  };
130 
131  // the old nodes/edges values for each updated property
132  tlp_hash_map<PropertyInterface *, RecordedValues> oldValues;
133  // the new node value for each updated property
134  tlp_hash_map<PropertyInterface *, RecordedValues> newValues;
135 
136  // real deletion of deleted objects (properties, sub graphs)
137  // during the recording of updates these objects are removed from graph
138  // structures but not really 'deleted'
139  void deleteDeletedObjects();
140  // deletion of recorded values
141  void deleteValues(tlp_hash_map<PropertyInterface *, RecordedValues> &values);
142  // deletion of DataMem default values
143  void deleteDefaultValues(tlp_hash_map<PropertyInterface *, DataMem *> &values);
144  // record of a node's edges container before/after modification
145  void recordEdgeContainer(tlp_hash_map<node, std::vector<edge>> &, GraphImpl *, node,
146  edge e = edge(), bool loop = false);
147  void recordEdgeContainer(tlp_hash_map<node, std::vector<edge>> &, GraphImpl *, node,
148  const std::vector<edge> &, unsigned int);
149  // remove an edge from a node's edges container
150  void removeFromEdgeContainer(tlp_hash_map<node, std::vector<edge>> &containers, edge e, node n);
151 
152  void removeGraphData(Graph *);
153 
154  // record new values for all updated properties
155  // restartAllowed must be true
156  void recordNewValues(GraphImpl *);
157  void recordNewNodeValues(PropertyInterface *p);
158  void recordNewEdgeValues(PropertyInterface *p);
159 
160  // start of recording (push)
161  void startRecording(GraphImpl *);
162  // end of recording
163  // push an other recorder or pop this one
164  void stopRecording(Graph *);
165  // restart of recording (unpop)
166  void restartRecording(Graph *);
167  // perform undo/redo updates
168  void doUpdates(GraphImpl *, bool undo);
169  // check for recorded updates
170  bool hasUpdates();
171  // remove a property from the observed ones
172  // only if nothing is yet recorded for that property
173  bool dontObserveProperty(PropertyInterface *);
174  // check if the property is newly added or deleted
175  bool isAddedOrDeletedProperty(Graph *, PropertyInterface *);
176 
177 public:
178  GraphUpdatesRecorder(bool allowRestart = true,
179  const GraphStorageIdsMemento *prevIdsMemento = nullptr);
180  ~GraphUpdatesRecorder() override;
181 
182  // old GraphObserver interface
183  // graphAddedNodes
184  void addNode(Graph *g, const node n);
185 
186  // graphAddedEdges
187  void addEdge(Graph *g, const edge e);
188 
189  void addEdges(Graph *g, unsigned int nbAddedEdges);
190 
191  // graphDeletedNodes
192  void delNode(Graph *g, const node n);
193 
194  // graphDeletedEdges
195  void delEdge(Graph *g, const edge e);
196 
197  // revertedEdges
198  void reverseEdge(Graph *g, const edge e);
199 
200  // oldEdgesEnds
201  void beforeSetEnds(Graph *g, const edge e);
202 
203  // newEdgesEnds
204  void afterSetEnds(Graph *g, const edge e);
205 
206  // addedSubGraphs
207  void addSubGraph(Graph *g, Graph *sg);
208 
209  // deletedSubGraphs
210  void delSubGraph(Graph *g, Graph *sg);
211 
212  // addedProperties
213  void addLocalProperty(Graph *g, const std::string &name);
214 
215  // deletedProperties
216  void delLocalProperty(Graph *g, const std::string &name);
217 
218  // beforeSetAttribute
219  void beforeSetAttribute(Graph *g, const std::string &name);
220 
221  // removeAttribute
222  void removeAttribute(Graph *g, const std::string &name);
223 
224  // old PropertyObserver Interface
225  // oldValues
226  void beforeSetNodeValue(PropertyInterface *p, const node n);
227 
228  // oldNodeDefaultValues
229  void beforeSetAllNodeValue(PropertyInterface *p);
230 
231  // oldValues
232  void beforeSetEdgeValue(PropertyInterface *p, const edge e);
233 
234  // oldEdgeDefaultValues
235  void beforeSetAllEdgeValue(PropertyInterface *p);
236 
237  // renamedProperties
238  void propertyRenamed(PropertyInterface *p);
239 
240 protected:
241  // override Observable::treatEvent
242  void treatEvent(const Event &ev) override;
243 };
244 } // namespace tlp
245 
246 #endif // TLPGRAPHRECORDER_H
247 
248 ///@endcond
unsigned int getId() const
Gets the unique identifier of the graph.
Definition: Graph.h:1082