import java.util.List;
import java.util.Map.Entry;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
import org.simantics.Simantics;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
* @throws DatabaseException
*/
public void setInput(Resource oldModel, Resource newModel, Resource originalModel, boolean newDistinct) throws DatabaseException{
+ this.setInput(oldModel, newModel, originalModel, newDistinct, null);
+ }
+ public void setInput(Resource oldModel, Resource newModel, Resource originalModel, boolean newDistinct, IProgressMonitor monitor) throws DatabaseException{
+
this.oldModel = oldModel;
this.newModel = newModel;
this.originalModel = originalModel;
+
+ if (monitor == null)
+ monitor = new NullProgressMonitor();
// addFilters(filters);
if (originalModel != null) {
// tree way comparison
GraphComparator comparator2 = result2.first;
if (result2.second != null)
showWarning(result2.second);
- comparator2.test(getSession());
+ comparator2.test(getSession(), monitor);
changes2 = comparator2.getChanges();
+ if (monitor.isCanceled())
+ return;
changes2 = getSession().syncRequest(createFilterRead(changes2, filters));
- Pair<UpdateTree, UpdateList> chg2 = createChangeObjects(changes2);
+ Pair<UpdateTree, UpdateList> chg2 = createChangeObjects(changes2, null);
updateTree2 = chg2.first;
updateList2 = chg2.second;
GraphComparator comparator3 = result3.first;
if (result3.second != null)
showWarning(result3.second);
- comparator3.test(getSession());
+ comparator3.test(getSession(), monitor);
changes3 = comparator3.getChanges();
changes3 = getSession().syncRequest(createFilterRead(changes3, filters));
}
+ if (monitor.isCanceled())
+ return;
Pair<GraphComparator,String> result = getChanges(oldModel,newModel);
GraphComparator comparator = result.first;
}
}
}
- comparator.test(getSession());
+ if (monitor.isCanceled())
+ return;
+ comparator.test(getSession(), monitor);
+ monitor.setTaskName("Processing changes...");
+ monitor.subTask("");
changes = comparator.getChanges();
changes = getSession().syncRequest(createFilterRead(changes, filters));
- Pair<UpdateTree, UpdateList> chg = createChangeObjects(changes);
+ Pair<UpdateTree, UpdateList> chg = createChangeObjects(changes, monitor);
updateTree = chg.first;
updateList = chg.second;
if (userFilters.size() != 0) {
if (originalModel != null) {
defaultSelections();
}
-
init = true;
}
protected abstract Pair<GraphComparator,String> getChanges(Resource r1, Resource r2) throws DatabaseException;
- protected Pair<UpdateTree, UpdateList> createChangeObjects(GraphChanges changes) throws DatabaseException{
- UpdateTree updateTree = getUpdateTree(changes);
+ protected Pair<UpdateTree, UpdateList> createChangeObjects(GraphChanges changes, IProgressMonitor monitor) throws DatabaseException{
+ if (monitor != null)
+ monitor.subTask("Processing structural changes");
+ UpdateTree updateTree = getUpdateTree(changes);
+ if (monitor != null)
+ monitor.subTask("Processing property changes");
UpdateList updateList = getUpdateList(changes);
+ if (monitor != null)
+ monitor.subTask("Postprocessing changes");
postProcess(updateTree, updateList);
return new Pair<UpdateTree, UpdateList>(updateTree, updateList);
}
public UpdateTree getUpdateTree3() throws DatabaseException{
if (updateTree3 == null && changes3 != null) {
- Pair<UpdateTree, UpdateList> chg3 = createChangeObjects(changes3);
+ Pair<UpdateTree, UpdateList> chg3 = createChangeObjects(changes3, null);
updateTree3 = chg3.first;
updateList3 = chg3.second;
}
}
public UpdateList getUpdateList3() throws DatabaseException {
if (updateList3 == null && changes3 != null) {
- Pair<UpdateTree, UpdateList> chg3 = createChangeObjects(changes3);
+ Pair<UpdateTree, UpdateList> chg3 = createChangeObjects(changes3, null);
updateTree3 = chg3.first;
updateList3 = chg3.second;
}
import java.util.Set;
import java.util.Stack;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
import org.simantics.databoard.Bindings;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
private Set<Resource> nonMatchedLeft = new HashSet<Resource>();
private Set<Resource> nonMatchedRight = new HashSet<Resource>();
+ private long iter = 0;
+ private long maxIter = -1;
+
// runtime attributes
private ReadGraph g;
nonMatchedRight.add(r);
}
+ public long getMaxIter() {
+ return maxIter;
+ }
+
+ /**
+ * Sets maximum iteration done on a single DB transaction. Affects only test(Session) methods.
+ * Default value is -1, which disables iteration limit.
+ * Note that using iteration limit causes comparison to repeat some work, thus total execution time will increase.
+ *
+ * @param maxIter
+ */
+ public void setMaxIter(long maxIter) {
+ this.maxIter = maxIter;
+ }
+
+ public void clear() {
+ changes1.clear();
+ changes1Set.clear();
+ changes2.clear();
+ changes2Set.clear();
+ comparableResources.clear();
+ comparableStatements.clear();
+ modifications.clear();
+ modificationsSet.clear();
+ processedResources.clear();
+ }
+
public void test(ReadGraph g) throws DatabaseException {
+ test(g,null);
+ }
+
+ public void test(ReadGraph g, IProgressMonitor monitor) throws DatabaseException {
this.g = g;
this.b = Layer0.getInstance(g);
comparator.setComparator(this);
comparator.initialize(g, r1, r2);
+ if (monitor == null)
+ monitor = new NullProgressMonitor();
+
Stack<Resource> objectsLeft = new Stack<Resource>();
Stack<Resource> objectsRight = new Stack<Resource>();
objectsLeft.push(r1);
while (true) {
if (objectsLeft.isEmpty() && !changed)
break;
+ if (monitor.isCanceled()) {
+ clear();
+ return;
+ }
+ monitor.subTask(monitorTaskName(objectsLeft, objectsRight, unreliableLeft, unreliableRight));
changed = false;
// process compares objects that are identified and searches for more resources to process.
- changed |= process(objectsLeft, objectsRight, unreliableLeft, unreliableRight);
- // process unreliable handles cases where unidentified statements subject and object have been identified
- changed |= processUnreliable(unreliableLeft, unreliableRight);
- // process unreliable handles cases where unidentified resources have path of length one to identified resource
- changed |= processUnreliable(unreliableLeft, unreliableRight,objectsLeft,objectsRight);
- if (objectsLeft.isEmpty() && unreliableLeft.size() > 0 && unreliableRight.size() > 0) {
- changed |= processUnreliable2(unreliableLeft, unreliableRight,objectsLeft,objectsRight);
- }
- if (objectsLeft.isEmpty() && unreliableLeft.size() > 0 && unreliableRight.size() > 0) {
- // comparison is ending, but we have still unprocessed unidentified resources left.
- // These cases have longer path than one to identified objects.
- changed |= processUnreliableDeep(unreliableLeft, unreliableRight, objectsLeft, objectsRight);
- }
+ changed = compareIter(g, objectsLeft, objectsRight, unreliableLeft, unreliableRight);
+ monitor.worked(1);
}
for (Statement s : unreliableLeft) {
addAddition(s);
}
}
+ monitor.subTask(monitorTaskName(objectsLeft, objectsRight, unreliableLeft, unreliableRight) + " done.");
+ //printStats();
}
public void test(Session session) throws DatabaseException {
- test(session, r1, r2);
+ test(session, r1, r2, null);
+ }
+
+ public void test(Session session, IProgressMonitor monitor) throws DatabaseException {
+ test(session, r1, r2, monitor);
}
public void test(Session session, Resource r1, Resource r2) throws DatabaseException {
+ test(session, r1, r2, null);
+ }
+
+ public void test(Session session, Resource r1, Resource r2, IProgressMonitor monitor) throws DatabaseException {
comparator.setComparator(this);
+ if (monitor == null)
+ monitor = new NullProgressMonitor();
+
session.syncRequest(new ReadRequest() {
@Override
while (true) {
if (objectsLeft.isEmpty() && !changed)
break;
+ if (monitor.isCanceled()) {
+ clear();
+ return;
+ }
+ monitor.subTask(monitorTaskName(objectsLeft, objectsRight, unreliableLeft, unreliableRight));
changed = session.syncRequest(new Read<Boolean>() {
@Override
public Boolean perform(ReadGraph graph) throws DatabaseException {
+ //System.out.println("Iter " + monitorTaskName(objectsLeft, objectsRight, unreliableLeft, unreliableRight));
g = graph;
b = Layer0.getInstance(graph);
- // process compares objects that are identified and searches for more resources to process.
- boolean c = process(objectsLeft, objectsRight, unreliableLeft, unreliableRight);
- // process unreliable handles cases where unidentified statements subject and object have been identified
- c |= processUnreliable(unreliableLeft, unreliableRight);
- // process unreliable handles cases where unidentified resources have path of length one to identified resource
- c |= processUnreliable(unreliableLeft, unreliableRight,objectsLeft,objectsRight);
- if (objectsLeft.isEmpty() && unreliableLeft.size() > 0 && unreliableRight.size() > 0) {
- c |= processUnreliable2(unreliableLeft, unreliableRight,objectsLeft,objectsRight);
- }
- if (objectsLeft.isEmpty() && unreliableLeft.size() > 0 && unreliableRight.size() > 0) {
- // comparison is ending, but we have still unprocessed unidentified resources left.
- // These cases have longer path than one to identified objects.
- c |= processUnreliableDeep(unreliableLeft, unreliableRight, objectsLeft, objectsRight);
- }
- if (objectsLeft.isEmpty() && unreliableLeft.size() > 0 && unreliableRight.size() > 0) {
- // comparison is ending, but we have still unprocessed unidentified resources left.
- // These cases have longer path than one to identified objects.
- c |= processUnreliableDeep(unreliableLeft, unreliableRight, objectsLeft, objectsRight);
- }
- return c;
+ return compareIter(graph, objectsLeft, objectsRight, unreliableLeft, unreliableRight);
}
});
-
+ monitor.worked(1);
}
if (!comparableStatements.containsRight(s))
addAddition(s);
}
+ unreliableLeft.clear();
+ unreliableRight.clear();
-
+ monitor.subTask(monitorTaskName(objectsLeft, objectsRight, unreliableLeft, unreliableRight) + " done.");
+ //printStats();
}
+ private boolean compareIter(ReadGraph graph, Stack<Resource> objectsLeft, Stack<Resource> objectsRight, Set<Statement> unreliableLeft, Set<Statement> unreliableRight) throws DatabaseException {
+ // process compares objects that are identified and searches for more resources to process.
+ iter = 0;
+ boolean c = process(objectsLeft, objectsRight, unreliableLeft, unreliableRight);
+ if (objectsLeft.isEmpty()) {
+ // process unreliable handles cases where unidentified statements subject and object have been identified
+ c |= processUnreliable(unreliableLeft, unreliableRight);
+ // process unreliable handles cases where unidentified resources have path of length one to identified resource
+ if (!c) {
+ c |= processUnreliable(unreliableLeft, unreliableRight,objectsLeft,objectsRight);
+ if (!c && objectsLeft.isEmpty() && unreliableLeft.size() > 0 && unreliableRight.size() > 0) {
+ c |= processUnreliable2(unreliableLeft, unreliableRight,objectsLeft,objectsRight);
+ }
+ if (!c && objectsLeft.isEmpty() && unreliableLeft.size() > 0 && unreliableRight.size() > 0) {
+ // comparison is ending, but we have still unprocessed unidentified resources left.
+ // These cases have longer path than one to identified objects.
+ c |= processUnreliableDeep(unreliableLeft, unreliableRight, objectsLeft, objectsRight);
+ }
+ if (!c && objectsLeft.isEmpty() && unreliableLeft.size() > 0 && unreliableRight.size() > 0) {
+ // comparison is ending, but we have still unprocessed unidentified resources left.
+ // These cases have longer path than one to identified objects.
+ c |= processUnreliableDeep(unreliableLeft, unreliableRight, objectsLeft, objectsRight);
+ }
+ }
+ }
+ return c;
+
+ }
+
+ private String monitorTaskName(Stack<Resource> objectsLeft, Stack<Resource> objectsRight, Set<Statement> unreliableLeft, Set<Statement> unreliableRight) {
+ int cr = comparableResources.size();
+ int ch = Math.max(changes1.size(), changes2.size());
+ return "Graph compare " + (cr + ch) + " / " + (cr+ch+(Math.max(objectsLeft.size(), objectsRight.size())+Math.max(unreliableLeft.size(), unreliableRight.size())));
+ }
+
private boolean process(Stack<Resource> objectsLeft, Stack<Resource> objectsRight, Set<Statement> unreliableLeft, Set<Statement> unreliableRight) throws DatabaseException {
List<Statement> ss1 = new ArrayList<Statement>();
List<Statement> ss2 = new ArrayList<Statement>();
boolean didSomething = false;
- while (!objectsLeft.isEmpty()) {
+ while (!objectsLeft.isEmpty()&& (maxIter < 0 || iter < maxIter)) {
Resource r1 = objectsLeft.pop();
Resource r2 = objectsRight.pop();
ss2.clear();
}
+ iter++;
}
return didSomething;
}
}
for (Resource left : subjectLeft.getKeys()) {
+ if (maxIter > 0 && iter > maxIter)
+ break;
Resource right = comparableResources.getRight(left);
if (right == null)
continue;
unreliableRight.remove(rightS);
addComparable(leftS, rightS);
didSomething = true;
+ iter++;
}
}
}
subjectRight.add(s.getSubject(),s);
objectRight.add(s.getObject(),s);
}
-
for (Resource ol : objectLeft.getKeys()) {
+ if (maxIter > 0 && iter > maxIter)
+ break;
// all statements to the left side object
List<Statement> left = objectLeft.getValues(ol);
// all subjects that have statements to the left side object (ol)
unreliableLeft.remove(sl);
unreliableRight.remove(sr);
}
+ iter++;
} else {
subjectRight.add(s.getSubject(),s);
objectRight.add(s.getObject(),s);
}
-
for (Resource ol : objectLeft.getKeys()) {
+ if (maxIter > 0 && iter > maxIter)
+ break;
// all statements to the left side object
List<Statement> left = objectLeft.getValues(ol);
// all subjects that have statements to the left side object (ol)
for (Entry<Statement, Statement> entry : comparableStatements.getEntries()) {
unreliableLeft.remove(entry.getKey());
unreliableRight.remove(entry.getValue());
+ iter++;
}
}
}
objectRight.add(s.getObject(),s);
}
for (Resource ol : objectLeft.getKeys()) {
+ if (maxIter > 0 && iter > maxIter)
+ break;
Set<Path> pathsLeft = new HashSet<Path>();
for (Resource rel : traversed) {
pathsLeft.addAll(Path.create(g.getStatements(ol, rel)));
Path right = map.getRight(left);
for (int i = 0; i < left.getLength(); i++) {
addComparable(left.getStatements().get(i),right.getStatements().get(i));
+ iter++;
}
}
+ iter++;
}
}
}
} else {
if (DEBUG) System.out.println(left + " = " + right);
comparableResources.map(left, right);
+
+// if (comparableResources.size() % 1000 == 0)
+// printStats();
}
}
}
+ public void printStats() {
+ System.out.println("Comp " + comparableResources.size() + " L " + changes1.size() + " R " + changes2.size() + " M " + modifications.size() + " P " + processedResources.size());
+ }
+
public List<Statement> filterAsserted(Resource r, Collection<Statement> in) throws DatabaseException {
List<Statement> out = new ArrayList<Statement>();
for (Statement s : in) {