]> gerrit.simantics Code Review - simantics/interop.git/blob - org.simantics.interop.mapping/src/org/simantics/interop/mapping/Mapper.java
refs #4298
[simantics/interop.git] / org.simantics.interop.mapping / src / org / simantics / interop / mapping / Mapper.java
1 package org.simantics.interop.mapping;\r
2 \r
3 import java.util.ArrayList;\r
4 import java.util.Collection;\r
5 import java.util.Iterator;\r
6 import java.util.List;\r
7 \r
8 import org.eclipse.core.runtime.IProgressMonitor;\r
9 import org.eclipse.core.runtime.NullProgressMonitor;\r
10 import org.simantics.db.ReadGraph;\r
11 import org.simantics.db.Resource;\r
12 import org.simantics.db.Session;\r
13 import org.simantics.db.VirtualGraph;\r
14 import org.simantics.db.WriteGraph;\r
15 import org.simantics.db.common.request.ReadRequest;\r
16 import org.simantics.db.common.request.WriteRequest;\r
17 import org.simantics.db.common.request.WriteResultRequest;\r
18 import org.simantics.db.common.utils.NameUtils;\r
19 import org.simantics.db.exception.DatabaseException;\r
20 import org.simantics.db.exception.ServiceException;\r
21 import org.simantics.db.layer0.util.SessionGarbageCollection;\r
22 import org.simantics.db.request.Read;\r
23 import org.simantics.interop.mapping.data.GraphNode;\r
24 import org.simantics.interop.mapping.data.Identifiable;\r
25 import org.simantics.interop.mapping.data.Link;\r
26 import org.simantics.interop.mapping.data.ResourceIdentifiable;\r
27 import org.simantics.ui.jobs.SessionGarbageCollectorJob;\r
28 import org.simantics.utils.datastructures.MapList;\r
29 import org.simantics.utils.datastructures.Pair;\r
30 \r
31 /**\r
32  * \r
33  * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
34  *\r
35  */\r
36 public class Mapper {\r
37         \r
38         public static final boolean USE_SPLIT_TRANSACTIONS = false; // Split transactions\r
39         public static int OBJECTS_PER_TRANSACTION = 5000;           // number of objects handled per transaction (split mode) \r
40         private static boolean SLEEP_BETWEEN_WRITES = false;        // sleep between transactions (split mode)     \r
41         private static int SLEEP_TIME = 10;                         // time to sleep (ms)\r
42         private static boolean COLLECT_BETWEEN_WRITES = false;      // Run SessionGC between split transactions\r
43         private static boolean COLLECT_WITHIN_TRANSACTIONS = true;  // Run Collect within transactions (both modes)\r
44         public static int OBJECTS_BEFORE_COLLECT = 5000;            // number of objects that are handled before collect (non-split mode)\r
45         \r
46         private List<InitializedRule> initializedRules = new ArrayList<InitializedRule>();\r
47         private List<Pair<IdentificationRule, Pair<Integer,GenerationRule>>> generationRules;\r
48         private List<List<ModificationRule>> globalModificationRules;\r
49         private List<List<Pair<IdentificationRule, ModificationRule>>> modificationRules;\r
50         private List<Pair<ConnectionIdentificationRule, ConnectionGenerationRule>> connectionRules;\r
51 \r
52         int maxGenPass = 0;\r
53         \r
54         public Mapper() {\r
55                 long maxMemory = Runtime.getRuntime().maxMemory();\r
56                 maxMemory /= (1024*1024);                            // Convert to MB;\r
57                 int use = 290;                                       // Estimated memory usage of the system\r
58                 int freeMem = (int)maxMemory-use;                                        // Free memory for mappings    \r
59                 OBJECTS_BEFORE_COLLECT = (freeMem * freeMem) / 1000; //600M heap -> 84, 3000M heap -> 5645\r
60                 if (OBJECTS_BEFORE_COLLECT < 2)\r
61                         OBJECTS_BEFORE_COLLECT = 2;\r
62                 OBJECTS_PER_TRANSACTION = OBJECTS_BEFORE_COLLECT;\r
63                 \r
64                 \r
65                 generationRules = new ArrayList<Pair<IdentificationRule,Pair<Integer,GenerationRule>>>();\r
66                 modificationRules = new ArrayList<List<Pair<IdentificationRule,ModificationRule>>>();\r
67                 globalModificationRules = new ArrayList<List<ModificationRule>>();\r
68                 connectionRules = new ArrayList<Pair<ConnectionIdentificationRule, ConnectionGenerationRule>>();\r
69         }\r
70         \r
71         public void addRule(int pass, IdentificationRule idRule, GenerationRule genRule) {\r
72                 if (idRule == null || genRule == null) throw new NullPointerException();\r
73                 generationRules.add(new Pair<IdentificationRule, Pair<Integer,GenerationRule>>(idRule, new Pair<Integer,GenerationRule>(pass,genRule)));\r
74                 maxGenPass = Math.max(maxGenPass, pass);\r
75                 if (genRule instanceof InitializedRule)\r
76                         initializedRules.add((InitializedRule)genRule);\r
77         }\r
78         \r
79         public void addRule(IdentificationRule idRule, MappingRule mappingRule) {\r
80                 addRule(0,idRule,mappingRule);\r
81         }\r
82         \r
83         public void addRule(IdentificationRule idRule, MappingRule... mappingRules) {\r
84                 for (MappingRule mappingRule : mappingRules)\r
85                         addRule(0,idRule,mappingRule);\r
86         }\r
87         \r
88         public void addRule(int pass, IdentificationRule idRule, MappingRule mappingRule) {\r
89                 if (idRule == null || mappingRule == null) throw new NullPointerException();\r
90                 if (mappingRule instanceof ModificationRule) {\r
91                         while (pass >= modificationRules.size()) {\r
92                                 modificationRules.add(new ArrayList<Pair<IdentificationRule,ModificationRule>>());\r
93                         }\r
94                         List<Pair<IdentificationRule,ModificationRule>> priList = modificationRules.get(pass);\r
95                         priList.add(new Pair<IdentificationRule, ModificationRule>(idRule, (ModificationRule)mappingRule));\r
96                 }\r
97                 if (mappingRule instanceof GenerationRule)\r
98                         generationRules.add(new Pair<IdentificationRule, Pair<Integer,GenerationRule>>(idRule, new Pair<Integer,GenerationRule>(pass,(GenerationRule)mappingRule)));\r
99                 if (mappingRule instanceof InitializedRule)\r
100                         initializedRules.add((InitializedRule)mappingRule);\r
101         }\r
102         \r
103         public void addRule(int pass, IdentificationRule idRule, MappingRule... mappingRules) {\r
104                 for (MappingRule mappingRule : mappingRules)\r
105                         addRule(pass,idRule,mappingRule);\r
106         }\r
107         \r
108         public void addRule(IdentificationRule idRule, ModificationRule... modRules) {\r
109                 addRule(0, idRule, modRules);\r
110         }\r
111 \r
112         public void addRule(int pass, IdentificationRule idRule, ModificationRule... modRules) {\r
113                 if (idRule == null) throw new NullPointerException();\r
114                 \r
115                 while (pass >= modificationRules.size()) {\r
116                         modificationRules.add(new ArrayList<Pair<IdentificationRule,ModificationRule>>());\r
117                 }\r
118                 List<Pair<IdentificationRule,ModificationRule>> priList = modificationRules.get(pass);\r
119                 \r
120                 for (ModificationRule modRule : modRules){\r
121                         if (modRule == null) throw new NullPointerException();  \r
122                         priList.add(new Pair<IdentificationRule, ModificationRule>(idRule, modRule));\r
123                         if (modRule instanceof InitializedRule)\r
124                                 initializedRules.add((InitializedRule)modRule);\r
125                 }\r
126         }\r
127         public void addRule(ModificationRule modRule) {\r
128                 addRule(0, modRule);\r
129         }\r
130         \r
131         public void addRule(InitializedRule initRule) {\r
132                 initializedRules.add(initRule);\r
133         }\r
134         \r
135         public void addRule(int pass, ModificationRule modRule) {\r
136                 if (modRule == null) throw new NullPointerException();\r
137                 while (pass >= globalModificationRules.size()) {\r
138                         globalModificationRules.add(new ArrayList<ModificationRule>());\r
139                 }\r
140                 List<ModificationRule> priList = globalModificationRules.get(pass);\r
141                 priList.add(modRule);\r
142                 if (modRule instanceof InitializedRule)\r
143                         initializedRules.add((InitializedRule)modRule);\r
144         }\r
145         \r
146         public void addRule(ConnectionIdentificationRule idRule, ConnectionGenerationRule genRule) {\r
147                 if (idRule == null || genRule == null) throw new NullPointerException();\r
148                 connectionRules.add(new Pair<ConnectionIdentificationRule, ConnectionGenerationRule>(idRule, genRule));\r
149                 if (genRule instanceof InitializedRule)\r
150                         initializedRules.add((InitializedRule)genRule);\r
151         }\r
152         \r
153         /**\r
154          * Runs the mapping procedure. Disposes nodes after mapping is done.\r
155          * @param g\r
156          * @param model\r
157          * @param nodes\r
158          * @param monitor\r
159          * @throws Exception\r
160          */\r
161         public void map(WriteGraph g, Resource model, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {\r
162                 startMapping(null);\r
163                 try {\r
164                         if (monitor == null)\r
165                                 monitor = new NullProgressMonitor();\r
166                         \r
167                         for (InitializedRule rule : initializedRules)\r
168                                 rule.initialize(g, model);\r
169                         \r
170                         applyModifications(g, nodes, monitor);\r
171                         monitor.worked(1);\r
172                         applyGenerations(g,nodes,monitor);\r
173                         monitor.worked(1);\r
174                         applyConnections(g,nodes,monitor);\r
175                         monitor.worked(1);\r
176                 } finally {\r
177                         MappingTools.disposeNodes(nodes);\r
178                         endMapping();\r
179                 }\r
180                 \r
181         }\r
182         \r
183         /**\r
184          * Runs the mapping procedure. Disposes nodes after mapping is done.\r
185          * @param session\r
186          * @param model\r
187          * @param nodes\r
188          * @param monitor\r
189          * @throws Exception\r
190          */\r
191         public void map(Session session, Resource model, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {\r
192                 map(session, model, null, nodes, monitor);\r
193         }\r
194         \r
195         /**\r
196          * Runs the mapping procedure. Disposes nodes after mapping is done.\r
197          * @param session\r
198          * @param model\r
199          * @param vg\r
200          * @param nodes\r
201          * @param monitor\r
202          * @throws Exception\r
203          */\r
204         public void map(Session session, Resource model, VirtualGraph vg, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {\r
205                 startMapping(vg);\r
206                 try {\r
207                         long time = System.currentTimeMillis();\r
208                         if (monitor == null)\r
209                                 monitor = new NullProgressMonitor();\r
210                         \r
211                         initializeRules(session, vg, model);\r
212                         if (USE_SPLIT_TRANSACTIONS) {\r
213                                 applyModifications(session, nodes, monitor);\r
214                                 monitor.worked(1);\r
215                                 applyGenerations(session, vg, nodes, monitor);\r
216                                 monitor.worked(1);\r
217                                 applyConnections(session, vg, nodes, monitor);\r
218                                 monitor.worked(1);\r
219                         } else {\r
220                                 applyModifications2(session, nodes, monitor);\r
221                                 monitor.worked(1);\r
222                                 applyGenerations2(session, vg, nodes, monitor);\r
223                                 monitor.worked(1);\r
224                                 applyConnections2(session, vg, nodes, monitor);\r
225                                 monitor.worked(1);\r
226                         }\r
227                         long time2 = System.currentTimeMillis();\r
228                         System.out.println("Mapping took " + ((time2-time)/1000) + " seconds");\r
229                 } finally {\r
230                         MappingTools.disposeNodes(nodes);\r
231                         if (COLLECT_BETWEEN_WRITES) {\r
232 \r
233                                 SessionGarbageCollection.gc(null, session, true, null);\r
234                         }\r
235                         endMapping();\r
236                 }\r
237                 \r
238         }\r
239         \r
240         \r
241         //private boolean autosaveEndabled = false;\r
242         private VirtualGraph vg;\r
243         \r
244         protected void startMapping(VirtualGraph vg) {\r
245                  SessionGarbageCollectorJob.getInstance().setEnabled(false);\r
246                  //autosaveEndabled = AutosaveCommands.getInstance().isEnabled();\r
247                  //AutosaveCommands.getInstance().setEnabled(false);\r
248                  this.vg = vg;\r
249         }\r
250         \r
251         protected void endMapping() {\r
252                  SessionGarbageCollectorJob.getInstance().setEnabled(true).scheduleAfterQuietTime();\r
253                 // AutosaveCommands.getInstance().setEnabled(autosaveEndabled);\r
254                  vg = null;\r
255         }\r
256         \r
257         private void applyModifications(ReadGraph g, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {\r
258                 \r
259                 // Apply global modification rules first\r
260                 \r
261                 int passCount = Math.max(globalModificationRules.size(),modificationRules.size());\r
262 \r
263                 for (int pass = 0; pass < passCount; pass++) {\r
264                         if (globalModificationRules.size() > pass) {\r
265                                 int count = 0;\r
266                                 List<ModificationRule> modRules = globalModificationRules.get(pass);\r
267                                 int size = modRules.size();\r
268                                 monitor.subTask("Running global modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");\r
269                                 for (ModificationRule r : modRules) {\r
270                                         Collection<GraphNode<Identifiable>> ruleModified = r.modify(g, nodes);\r
271                                         if (ruleModified == null)\r
272                                                 continue;\r
273                                         for (GraphNode<Identifiable> m : ruleModified) {\r
274                                                 if (m.isDisposed()) {\r
275                                                         nodes.remove(m);\r
276                                                 }\r
277                                                 else if (!nodes.contains(m)) {\r
278                                                         nodes.add(m);\r
279                                                 }\r
280                                         }\r
281                                         monitor.subTask("Running global modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");\r
282                                         if(monitor.isCanceled()) {\r
283                                                 throw new CancelException("Cancel requested.");\r
284                                         }\r
285                                         if (COLLECT_WITHIN_TRANSACTIONS)\r
286                                                 collect(g);\r
287                                 }\r
288                         } if (modificationRules.size() > pass) {\r
289                                 int count = 0;\r
290                                 List<Pair<IdentificationRule, ModificationRule>> modRules = modificationRules.get(pass);\r
291                                 int size = modRules.size();\r
292                                 monitor.subTask("Running object modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");\r
293                                 // Apply per object modification rules \r
294                                 for (Pair<IdentificationRule, ModificationRule> modRule : modRules) {\r
295                                         Collection<GraphNode<Identifiable>> ruleModified = new ArrayList<GraphNode<Identifiable>>();\r
296                                         for (GraphNode<Identifiable> n : nodes) {\r
297                                                 applyModifications(g, n, modRule, ruleModified);\r
298                                                 if (COLLECT_WITHIN_TRANSACTIONS)\r
299                                                         collect2(g);\r
300                                         }\r
301                                         \r
302                                         for (GraphNode<Identifiable> m : ruleModified) {\r
303                                                 if (m.isDisposed()) {\r
304                                                         nodes.remove(m);\r
305                                                 }\r
306                                                 else if (!nodes.contains(m)) {\r
307                                                         nodes.add(m);\r
308                                                 }\r
309                                         }\r
310                                         monitor.subTask("Running object modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");\r
311                                         if(monitor.isCanceled()) {\r
312                                                 throw new CancelException("Cancel requested.");\r
313                                         }\r
314                                         \r
315                                 }\r
316                         }\r
317                 }\r
318                 \r
319         }\r
320         \r
321         \r
322         \r
323         private void applyGenerations(WriteGraph graph, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {\r
324                 \r
325                 int size = nodes.size();\r
326                 int count = 0;\r
327                 monitor.subTask("Assigning generation rules ("+ count + "/" + size + ")");\r
328                 // populate generation rules\r
329                 for (GraphNode<Identifiable> n : nodes) {\r
330                         \r
331                         for (Pair<IdentificationRule,Pair<Integer,GenerationRule>> r : generationRules) {\r
332                                 if (r.first.matches(graph, n)) {\r
333                                         MappingTools.assignGenerationRule(n, r.second.first,r.second.second);\r
334                                 }\r
335                         }\r
336                         monitor.subTask("Assigning generation rules ("+ (++count) + "/" + size + ")");\r
337                         if(monitor.isCanceled()) {\r
338                                 throw new CancelException("Cancel requested.");\r
339                         }\r
340                         if (COLLECT_WITHIN_TRANSACTIONS)\r
341                                 collect2(graph);\r
342                 }\r
343                 \r
344                 count = 0;\r
345                 monitor.subTask("Generating objects ("+ count + "/" + size + ")");\r
346                 \r
347                 // apply generation rules.\r
348                 //WriteWrapper g  = new WriteWrapper(graph);\r
349                 \r
350                 //Collection<GenerationRule> usedRules = new ArrayList<GenerationRule>();\r
351                 for (int stage = 0; stage <= maxGenPass; stage++) {\r
352                         count = 0;\r
353                         for (GraphNode<Identifiable> n : nodes) {\r
354 \r
355                                 MapList<Integer,GenerationRule> priRules = n.getHint(MappingHints.KEY_GENERATION_RULES);\r
356                                 List<GenerationRule> rules = priRules.getValues(stage);\r
357                                 for (GenerationRule r : rules) {\r
358                                         r.generate(graph, n);\r
359                                 }\r
360 \r
361                                 monitor.subTask("Generating objects, stage " + stage + " :  ("+ (++count) + "/" + size + ")");\r
362                                 if(monitor.isCanceled()) {\r
363                                         throw new CancelException("Cancel requested.");\r
364                                 }\r
365                                 if (COLLECT_WITHIN_TRANSACTIONS)\r
366                                         collect2(graph);\r
367                         }\r
368                 }\r
369         }\r
370         \r
371         private void applyConnections(WriteGraph g, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {\r
372                 int size = nodes.size();\r
373                 int count = 0;\r
374                 \r
375                 monitor.subTask("Generating connections ("+ count + "/" + size + ")");\r
376                 \r
377                 for (GraphNode<Identifiable> node : nodes) {\r
378                         applyConnections(g, node);\r
379                         monitor.subTask("Generating connections ("+ (++count) + "/" + size + ")");\r
380                         if(monitor.isCanceled()) {\r
381                                 throw new CancelException("Cancel requested.");\r
382                         }\r
383                         if (COLLECT_WITHIN_TRANSACTIONS)\r
384                                 collect2(g);\r
385                 }\r
386         }\r
387         \r
388         \r
389         \r
390         protected String getName(ReadGraph g, Identifiable res) throws DatabaseException {\r
391                 if (res instanceof ResourceIdentifiable)\r
392                         return NameUtils.getSafeName(g, ((ResourceIdentifiable)res).getResource());\r
393                 else\r
394                         return res.toString();\r
395         }\r
396         \r
397         public class WriteWrapper extends WriteGraphProxy {\r
398                 \r
399                 \r
400                 private Collection<Resource> createdResources = new ArrayList<Resource>();\r
401                 \r
402                 public WriteWrapper(WriteGraph graph) {\r
403                         super(graph);\r
404                 }\r
405                 \r
406                 public Collection<Resource> getCreatedResources() {\r
407                         return createdResources;\r
408                 }\r
409                 \r
410                 public void clearCreated() {\r
411                         createdResources = new ArrayList<Resource>();\r
412                 }\r
413                 \r
414                 @Override\r
415                 public Resource newResource() throws ServiceException {\r
416                         Resource res = graph.newResource();\r
417                         createdResources.add(res);\r
418                         return res;\r
419                 }\r
420                 \r
421                 @Override\r
422                 public Resource newResource(long clusterId) throws ServiceException {\r
423                         Resource res = graph.newResource(clusterId);\r
424                         createdResources.add(res);\r
425                         return res;\r
426                 }\r
427                 \r
428                 \r
429         }\r
430         \r
431         private void initializeRules(Session session, VirtualGraph vg, final Resource model ) throws DatabaseException{\r
432                 session.syncRequest(new WriteRequest(vg) {\r
433                         @Override\r
434                         public void perform(WriteGraph g) throws DatabaseException {\r
435                                 for (InitializedRule rule : initializedRules)\r
436                                         rule.initialize(g, model);\r
437                                 \r
438                         }\r
439                 });\r
440                 \r
441         }\r
442                 \r
443         private void collect(ReadGraph g) throws DatabaseException {\r
444                 if (vg != null)\r
445                         return;\r
446                 SessionGarbageCollection.gc(g, 0, -1);\r
447         }\r
448         \r
449         int collect = 0;\r
450         \r
451         private void collect2(ReadGraph g) throws DatabaseException {\r
452                 if (vg != null)\r
453                         return;\r
454                 \r
455                 if (collect == OBJECTS_BEFORE_COLLECT) {\r
456                         SessionGarbageCollection.gc(g, 0, -1);\r
457                         collect = 0;\r
458                 } else {\r
459                         collect++;\r
460                 }\r
461         }\r
462         \r
463         private void applyModifications(Session session, final Collection<GraphNode<Identifiable>> nodes, final IProgressMonitor monitor) throws Exception {\r
464                 \r
465                 \r
466                 \r
467                 int passCount = Math.max(globalModificationRules.size(),modificationRules.size());\r
468                 \r
469                 for (int pass = 0; pass <passCount; pass++) {\r
470                         // Apply global modification rules first\r
471                         if (globalModificationRules.size() > pass) {\r
472                                 int count = 0;\r
473                                 List<ModificationRule> modRules = globalModificationRules.get(pass);\r
474                                 int size = modRules.size();\r
475                                 monitor.subTask("Running global modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");\r
476                                 for (final ModificationRule r : modRules) {\r
477                                         session.syncRequest(new ReadRequest() {\r
478                                                 \r
479                                                 @Override\r
480                                                 public void run(ReadGraph g) throws DatabaseException {\r
481                                                         try {\r
482                                                                 Collection<GraphNode<Identifiable>> ruleModified = r.modify(g, nodes);\r
483                                                                 \r
484                                                                 if (ruleModified == null)\r
485                                                                         return;\r
486                                                                 for (GraphNode<Identifiable> m : ruleModified) {\r
487                                                                         if (m.isDisposed()) {\r
488                                                                                 nodes.remove(m);\r
489                                                                         }\r
490                                                                         else if (!nodes.contains(m)) {\r
491                                                                                 nodes.add(m);\r
492                                                                         }\r
493                                                                 }\r
494                                                                 if (COLLECT_WITHIN_TRANSACTIONS)\r
495                                                                         collect(g);\r
496                                                         } catch (Exception e) {\r
497                                                                 throw new DatabaseException(e);\r
498                                                         }\r
499                                                         \r
500                                                 }\r
501                                         });\r
502                                         //SessionGarbageCollection.gc(null, session, true, null);\r
503                                         monitor.subTask("Running global modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");\r
504                                         if(monitor.isCanceled()) {\r
505                                                 throw new CancelException("Cancel requested.");\r
506                                         }\r
507                                 }\r
508                         }\r
509                         if (modificationRules.size() > pass) {\r
510                                 int count = 0;\r
511                                 List<Pair<IdentificationRule, ModificationRule>> modRules = modificationRules.get(pass);\r
512                                 int size = modRules.size();\r
513                                 monitor.subTask("Running object modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");\r
514                                 \r
515                                 // Apply per object modification rules \r
516                                 for (final Pair<IdentificationRule, ModificationRule> modRule : modRules) {\r
517                                         final Iterator<GraphNode<Identifiable>> iter = nodes.iterator();\r
518                                         final Collection<GraphNode<Identifiable>> ruleModified = new ArrayList<GraphNode<Identifiable>>();\r
519                                         while (iter.hasNext()) {\r
520                                                 session.syncRequest(new ReadRequest() {\r
521                                                         \r
522                                                         @Override\r
523                                                         public void run(ReadGraph g) throws DatabaseException {\r
524                                                                 try {\r
525                                                                         \r
526                                                                         int j = 0; \r
527                                                                         //for (GraphNode<Identifiable> n : nodes) {\r
528                                                                         while (iter.hasNext() && j < OBJECTS_PER_TRANSACTION) {\r
529                                                                                 GraphNode<Identifiable> n = iter.next();\r
530                                                                                 applyModifications(g, n, modRule, ruleModified);\r
531                                                                                 j++;\r
532                                                                         }\r
533                                                                         if (COLLECT_WITHIN_TRANSACTIONS)\r
534                                                                                 collect(g);\r
535                                                                         \r
536                                                                 } catch (Exception e) {\r
537                                                                         throw new DatabaseException(e);\r
538                                                                 }\r
539                                                                 \r
540                                                         }\r
541                                                 });\r
542                                         }\r
543                                         for (GraphNode<Identifiable> m : ruleModified) {\r
544                                                 if (m.isDisposed()) {\r
545                                                         nodes.remove(m);\r
546                                                 }\r
547                                                 else if (!nodes.contains(m)) {\r
548                                                         nodes.add(m);\r
549                                                 }\r
550                                         }\r
551                                         ruleModified.clear();\r
552                                         \r
553                                         //SessionGarbageCollection.gc(null, session, true, null);\r
554                                         monitor.subTask("Running object modification rules: pass (" + (pass+1) + "/" + passCount + "), rule ("+ (++count) + "/" + size + ")");\r
555                                         if(monitor.isCanceled()) {\r
556                                                 throw new CancelException("Cancel requested.");\r
557                                         }\r
558                                 }\r
559                         }       \r
560                 }\r
561                 \r
562         }\r
563         \r
564         private void applyModifications2(Session session, final Collection<GraphNode<Identifiable>> nodes, final IProgressMonitor monitor) throws Exception {\r
565                 session.syncRequest(new ReadRequest() {\r
566                         \r
567                         @Override\r
568                         public void run(ReadGraph g) throws DatabaseException {\r
569                                 try {\r
570                                         applyModifications(g, nodes, monitor);\r
571                                 } catch (Exception e) {\r
572                                         throw new DatabaseException(e);\r
573                                 }\r
574                                 \r
575                         }\r
576                 });\r
577         }\r
578         \r
579         private void applyGenerations(Session session, VirtualGraph vg, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {\r
580                 \r
581                 int size = nodes.size();\r
582                 int count = 0;\r
583                 monitor.subTask("Assigning generation rules ("+ count + "/" + size + ")");\r
584                 // populate generation rules\r
585 \r
586                 {\r
587                         final Iterator<GraphNode<Identifiable>> iter = nodes.iterator();\r
588                         while (iter.hasNext()) {\r
589                                 int c = session.syncRequest(new Read<Integer>() {\r
590                                         \r
591                                         @Override\r
592                                         public Integer perform(ReadGraph graph)\r
593                                                         throws DatabaseException {\r
594                                                 int j = 0;\r
595                                                 while (iter.hasNext() && j < OBJECTS_PER_TRANSACTION) {\r
596                                                         GraphNode<Identifiable> n = iter.next();\r
597                                                         for (Pair<IdentificationRule,Pair<Integer,GenerationRule>> r : generationRules) {\r
598                                                                 if (r.first.matches(graph, n)) {\r
599                                                                         MapList<Integer,GenerationRule> rules = n.getHint(MappingHints.KEY_GENERATION_RULES);\r
600                                                                         if (rules == null) {\r
601                                                                                 rules = new MapList<Integer,GenerationRule>();  \r
602                                                                         }\r
603                                                                         rules.add(r.second.first,r.second.second);\r
604                                                                         n.setHint(MappingHints.KEY_GENERATION_RULES, rules);\r
605                                                                 }\r
606                                                         }\r
607                                                         j++;\r
608                                                 }\r
609                                                 if (COLLECT_WITHIN_TRANSACTIONS)\r
610                                                         collect(graph);\r
611                                                 return j;\r
612                                                 \r
613                                         }\r
614                                 });\r
615                                 collect(session);\r
616                                 monitor.subTask("Assigning generation rules ("+ (count+=c) + "/" + size + ")");\r
617                                 if(monitor.isCanceled()) {\r
618                                         throw new CancelException("Cancel requested.");\r
619                                 }\r
620                                 sleep();\r
621                         }\r
622                 }\r
623                 \r
624                 count = 0;\r
625                 monitor.subTask("Generating objects ("+ (count) + "/" + size + ")");\r
626                 \r
627                 // apply generation rules.\r
628                 \r
629                 {\r
630                         for (int stage = 0; stage <= maxGenPass; stage++) {\r
631                                 final int fStage = stage;\r
632                                 count = 0;\r
633                                 final Iterator<GraphNode<Identifiable>> iter = nodes.iterator();\r
634                                 while (iter.hasNext()) {\r
635                                         int c = session.syncRequest(new WriteResultRequest<Integer>(vg) {\r
636                                                 \r
637                                                 @Override\r
638                                                 public Integer perform(WriteGraph graph) throws DatabaseException {\r
639                                                         int j = 0;\r
640                                                         try {\r
641                                                                 while (iter.hasNext() && j < OBJECTS_PER_TRANSACTION) {\r
642                                                                         GraphNode<Identifiable> n = iter.next();\r
643                                                                         \r
644                                                                         MapList<Integer,GenerationRule> priRules = n.getHint(MappingHints.KEY_GENERATION_RULES);\r
645                                                                         if (priRules == null) {\r
646                                                                                 j++;\r
647                                                                                 continue;\r
648                                                                         }\r
649                                                                         final List<GenerationRule> rules = priRules.getValues(fStage);\r
650                                                                         \r
651                                                                         if (fStage == 0 && rules.size() == 0)\r
652                                                                                 System.out.println();\r
653                                                                         for (GenerationRule r : rules) {\r
654                                                                                 r.generate(graph, n);\r
655 \r
656                                                                         }\r
657 \r
658                                                                                 \r
659                                                                         j++;\r
660                                                                         \r
661                                                                 }\r
662                                                                 if (COLLECT_WITHIN_TRANSACTIONS)\r
663                                                                         collect(graph);\r
664                                                                 return j;\r
665                                                         \r
666                                                 } catch (Exception e) {\r
667                                                         throw new DatabaseException(e);\r
668                                                 }\r
669                                         }});\r
670                                         collect(session);\r
671                                         monitor.subTask("Generating objects, stage " + stage + " :  ("+ (count+=c) + "/" + size + ")");\r
672                                         if(monitor.isCanceled()) {\r
673                                                 throw new CancelException("Cancel requested.");\r
674                                         }\r
675                                         sleep();\r
676                                 }\r
677                         }\r
678                 }\r
679         }\r
680         \r
681         private void applyGenerations2(Session session, VirtualGraph vg, final Collection<GraphNode<Identifiable>> nodes, final IProgressMonitor monitor) throws Exception {\r
682                 session.syncRequest(new WriteRequest(vg) {\r
683                         \r
684                         @Override\r
685                         public void perform(WriteGraph graph) throws DatabaseException {\r
686                                 try {\r
687                                         applyGenerations(graph, nodes, monitor);\r
688                                 } catch (Exception e) {\r
689                                         throw new DatabaseException(e);\r
690                                 }\r
691                                 \r
692                         }\r
693                 });\r
694         }\r
695         \r
696         private void collect(Session session) {\r
697                 if (COLLECT_BETWEEN_WRITES)\r
698                         SessionGarbageCollection.gc(null, session, true, null);\r
699         }\r
700         \r
701         \r
702         private void sleep() {\r
703                 if (SLEEP_BETWEEN_WRITES) {\r
704                         try {\r
705                                 Thread.sleep(SLEEP_TIME);\r
706                         } catch (InterruptedException e) {\r
707                                 \r
708                         }\r
709                 }\r
710         }\r
711         \r
712         private void applyConnections(Session session, VirtualGraph vg, Collection<GraphNode<Identifiable>> nodes, IProgressMonitor monitor) throws Exception {\r
713                 int size = nodes.size();\r
714                 int count = 0;\r
715                 \r
716                 monitor.subTask("Generating connections ("+ count + "/" + size + ")");\r
717                 \r
718                 final Iterator<GraphNode<Identifiable>> iter = nodes.iterator();\r
719                 while (iter.hasNext()) {\r
720                         int c = session.syncRequest(new WriteResultRequest<Integer>(vg) {\r
721                                 \r
722                                 @Override\r
723                                 public Integer perform(WriteGraph g) throws DatabaseException {\r
724                                         int j = 0;\r
725                                         try {\r
726                                                 while (iter.hasNext() && j < OBJECTS_PER_TRANSACTION) {\r
727                                                         GraphNode<Identifiable> node = iter.next();\r
728                                                         applyConnections(g, node);\r
729                                                         j++;\r
730                                                 }\r
731                                                 if (COLLECT_WITHIN_TRANSACTIONS)\r
732                                                         collect(g);\r
733                                                 return j;\r
734                                                 \r
735                                         } catch (Exception e) {\r
736                                                 throw new DatabaseException(e);\r
737                                         }       \r
738                                 }       \r
739                         });\r
740                         collect(session);\r
741                         monitor.subTask("Generating connections ("+ (count+=c) + "/" + size + ")");\r
742                         if(monitor.isCanceled()) {\r
743                                 throw new CancelException("Cancel requested.");\r
744                         }\r
745                         sleep();\r
746                 }\r
747         }\r
748         \r
749         private void applyConnections2(Session session, VirtualGraph vg, final Collection<GraphNode<Identifiable>> nodes, final IProgressMonitor monitor) throws Exception {\r
750                 session.syncRequest(new WriteRequest(vg) {\r
751                         \r
752                         @Override\r
753                         public void perform(WriteGraph graph) throws DatabaseException {\r
754                                 try {\r
755                                         applyConnections(graph, nodes, monitor);\r
756                                 } catch (Exception e) {\r
757                                         throw new DatabaseException(e);\r
758                                 }\r
759                                 \r
760                         }\r
761                 });\r
762         }\r
763 \r
764         private void applyModifications(ReadGraph g, GraphNode<Identifiable> n, Pair<IdentificationRule, ModificationRule> modRule, Collection<GraphNode<Identifiable>> ruleModified) throws Exception {\r
765                 if (!n.isDisposed() && modRule.first.matches(g, n)) { // we have to check \r
766                         Collection<GraphNode<Identifiable>> perRule = new ArrayList<GraphNode<Identifiable>>();\r
767                         perRule.add(n);\r
768                         ruleModified.addAll(modRule.second.modify(g, perRule));\r
769                 }\r
770         }\r
771         \r
772         private void applyConnections(WriteGraph g, GraphNode<Identifiable> node) throws Exception {\r
773                 for (Link<Identifiable> link : node.getLinks()) {\r
774                         if (link.isMain()) {\r
775                                 \r
776                                 for (Pair<ConnectionIdentificationRule, ConnectionGenerationRule> r : connectionRules) {\r
777                                         if (r.first.mathces(g, node, link.to(), link)) {\r
778                                                 Logger.defaultLogInfo("Connecting " +  getName(g, node.getData()) + " to " + getName(g, link.to().getData()) + " " + link.getName() + "/"+link.getInverseName());\r
779                                                 r.second.generate(g, node, link.to(), link);\r
780                                                 break;\r
781                                         }\r
782                                 }\r
783                         }\r
784                 }\r
785         }\r
786 }\r