*******************************************************************************/\r
package org.simantics.interop.test;\r
\r
+import java.math.MathContext;\r
import java.util.ArrayList;\r
import java.util.Arrays;\r
import java.util.Collection;\r
import java.util.Collections;\r
import java.util.Comparator;\r
+import java.util.HashMap;\r
import java.util.HashSet;\r
import java.util.List;\r
+import java.util.Map;\r
import java.util.Set;\r
import java.util.Stack;\r
\r
private BijectionMap<Resource, Resource> comparableResources = new BijectionMap<Resource, Resource>();\r
\r
\r
- private ObjectComparator comparator;\r
+ private ResourceComparator comparator;\r
\r
private Comparator<Statement> scomp = new PredicateComparator();\r
- private Comparator<Resource> rcomp = new ResourceComparator();\r
+ private Comparator<Resource> rcomp = new ResComparator();\r
\r
// runtime attributes\r
\r
comparator = new TypeComparator();\r
}\r
\r
- public GraphComparator(Resource r1, Resource r2, ObjectComparator comparator) {\r
+ public GraphComparator(Resource r1, Resource r2, ResourceComparator comparator) {\r
this.r1 = r1;\r
this.r2 = r2;\r
this.comparator = comparator;\r
this.b = Layer0.getInstance(g);\r
comparator.setComparator(this);\r
\r
- Stack<Resource> stack1 = new Stack<Resource>();\r
- Stack<Resource> stack2 = new Stack<Resource>();\r
- stack1.push(r1);\r
- stack2.push(r2);\r
+ Stack<Resource> objectsLeft = new Stack<Resource>();\r
+ Stack<Resource> objectsRight = new Stack<Resource>();\r
+ objectsLeft.push(r1);\r
+ objectsRight.push(r2);\r
\r
\r
List<Statement> ss1 = new ArrayList<Statement>();\r
List<Statement> ss2 = new ArrayList<Statement>();\r
\r
- while (!stack1.isEmpty()) {\r
- Resource r1 = stack1.pop();\r
- Resource r2 = stack2.pop();\r
+ Stack<Statement> unreliableLeft = new Stack<Statement>();\r
+ Stack<Statement> unreliableRight = new Stack<Statement>();\r
+ \r
+ while (!objectsLeft.isEmpty()) {\r
+ Resource r1 = objectsLeft.pop();\r
+ Resource r2 = objectsRight.pop();\r
\r
if (comparableResources.contains(r1, r2)) {\r
//System.out.println("already tested " + NameUtils.getSafeName(g, r1) + " " + NameUtils.getSafeName(g, r2));\r
ss1 = filterNonTested(ss1);\r
ss2 = filterNonTested(ss2);\r
\r
- compareStatements(ss1, ss2, null, null);\r
+ compareStatements(ss1, ss2, null, null,null,null);\r
ss1.clear();\r
ss2.clear();\r
}\r
ss2.addAll(g.getStatements(r2, rel));\r
ss1 = filterAsserted(r1, ss1);\r
ss2 = filterAsserted(r2, ss2);\r
- compareStatements(ss1, ss2, stack1, stack2);\r
+ compareStatements(ss1, ss2, objectsLeft, objectsRight,unreliableLeft,unreliableRight);\r
ss1.clear();\r
ss2.clear();\r
+ \r
}\r
}\r
+ MapList<Resource,Statement> subjectLeft = new MapList<Resource, Statement>();\r
+ MapList<Resource,Statement> subjectRight = new MapList<Resource, Statement>();\r
+ MapList<Resource,Statement> objectLeft = new MapList<Resource, Statement>();\r
+ MapList<Resource,Statement> objectRight = new MapList<Resource, Statement>();\r
+ \r
+ for (Statement s : unreliableLeft) {\r
+ subjectLeft.add(s.getSubject(),s);\r
+ objectLeft.add(s.getObject(),s);\r
+ }\r
+ for (Statement s : unreliableRight) {\r
+ subjectRight.add(s.getSubject(),s);\r
+ objectRight.add(s.getObject(),s);\r
+ }\r
+ \r
+ for (Resource ol : objectLeft.getKeys()) {\r
+\r
+ // all statements to the left side object\r
+ List<Statement> left = objectLeft.getValues(ol);\r
+ // all subjects that have statements to the left side object (ol)\r
+ Set<Resource> sLeft = new HashSet<Resource>();\r
+ // all matching subjects on the right side\r
+ Set<Resource> sRight = new HashSet<Resource>();\r
+ for (Statement s : left) {\r
+ sLeft.add(s.getSubject());\r
+ sRight.add(comparableResources.getRight(s.getSubject()));\r
+ }\r
+ // all objects that subjects on the right side point to. Object left has its matching resource among these, if it has matching resource\r
+ MapList<Resource,Statement> possibleOR = new MapList<Resource, Statement>();\r
+ for (Resource sr : sRight) {\r
+ for (Statement s : subjectRight.getValues(sr))\r
+ possibleOR.add(s.getObject(),s);\r
+ }\r
+ \r
+ // filter possible right side objects to those that have same amount of statements as the left side object\r
+ for (Resource or : possibleOR.getKeys().toArray(new Resource[possibleOR.getKeys().size()])) {\r
+ List<Statement> right = possibleOR.getValues(or);\r
+ if (right.size() != left.size())\r
+ possibleOR.remove(or);\r
+ \r
+ }\r
+ \r
+ // check for matching statements (comparable subjects, matching predicates)\r
+ MapList<Resource,Statement> matchingOR = new MapList<Resource, Statement>(); // list of objects that have matching statements\r
+ Map<Resource,Pair<int[], int[]>> matchingStatements = new HashMap<Resource, Pair<int[], int[]>>(); // matching statements\r
+ for (Resource or : possibleOR.getKeys()) {\r
+ List<Statement> right = possibleOR.getValues(or);\r
+ int iLeft[] = new int[left.size()];\r
+ int iRight[] = new int[right.size()];\r
+ \r
+ for (int i = 0; i < left.size(); i++) {\r
+ iLeft[i] = -1;\r
+ iRight[i] = -1;\r
+ }\r
+ \r
+ for (int l = 0; l < left.size(); l++) {\r
+ Statement ls = left.get(l);\r
+ for (int r = 0; r < right.size(); r++) {\r
+ if (iRight[r] >= 0)\r
+ continue;\r
+ Statement rs = right.get(r);\r
+ if (!comparableResources.contains(ls.getSubject(), rs.getSubject()))\r
+ continue;\r
+ if (rcomp.compare(ls.getPredicate(),rs.getPredicate()) == 0) {\r
+ iLeft[l] = r;\r
+ iRight[r] = l;\r
+ break;\r
+ }\r
+ }\r
+ \r
+ }\r
+ boolean success = true;\r
+ for (int i = 0; i < left.size(); i++) {\r
+ if (iLeft[i] < 0) {\r
+ success = false;\r
+ break;\r
+ }\r
+ if (iRight[i] < 0) {\r
+ success = false;\r
+ break;\r
+ }\r
+ \r
+ }\r
+ if (success) {\r
+ for (Statement s : right) \r
+ matchingOR.add(or,s);\r
+ matchingStatements.put(or, new Pair<int[], int[]>(iLeft, iRight));\r
+ }\r
+ }\r
+ // if there is only one matching right side object, we have found a match \r
+ if (matchingOR.getKeySize() == 1) {\r
+ Resource or = matchingOR.getKeys().iterator().next();\r
+ List<Statement> right = matchingOR.getValues(or);\r
+ Pair<int[], int[]> indices = matchingStatements.get(or);\r
+ \r
+ comparableResources.map(ol, or);\r
+ for (int l = 0; l < left.size(); l++) {\r
+ int r = indices.first[l];\r
+ comparableStatements.map(left.get(l), right.get(r));\r
+ }\r
+ \r
+ }\r
+\r
+ }\r
+ \r
+ for (Statement s : unreliableLeft) {\r
+ if (!comparableStatements.containsLeft(s))\r
+ addDeletion(s);\r
+ }\r
+ for (Statement s : unreliableRight) {\r
+ if (!comparableStatements.containsRight(s))\r
+ addAddition(s);\r
+ }\r
+ \r
+ \r
}\r
\r
\r
}\r
\r
public void sortStatement(List<Statement> list1, List<Statement> list2) {\r
+ sortStatement(list1, list2, scomp);\r
+ }\r
+ \r
+ public void sortStatement(List<Statement> list1, List<Statement> list2, Comparator<Statement> scomp) {\r
Collections.sort(list1,scomp);\r
Collections.sort(list2,scomp);\r
\r
}\r
}\r
\r
- private void compareStatements(List<Statement> ss1, List<Statement> ss2, Stack<Resource> stack1, Stack<Resource> stack2) throws DatabaseException {\r
+ private void compareStatements(List<Statement> ss1, List<Statement> ss2, Stack<Resource> objectsLeft, Stack<Resource> objectsRight,Stack<Statement> unreliableLeft, Stack<Statement> unreliableRight) throws DatabaseException {\r
sortStatement(ss1, ss2);\r
-// Collections.sort(ss1, scomp);\r
-// Collections.sort(ss2, scomp);\r
\r
int i1 = 0;\r
int i2 = 0;\r
int same2 = sameRel(ss2, i2);\r
int c = rcomp.compare(ss1.get(i1).getPredicate(),ss2.get(i2).getPredicate());\r
if (c == 0) {\r
- compareStatements(ss1, i1, same1, ss2, i2, same2,stack1,stack2);\r
+ compareStatements(ss1, i1, same1, ss2, i2, same2,objectsLeft,objectsRight,unreliableLeft,unreliableRight);\r
+ i1+=same1;\r
+ i2+=same2;\r
+ } else if (c < 0) {\r
+ for (int i = 0; i < same1; i++) {\r
+ System.out.println("Compare Statements diff1 " + printStatement(g,ss1.get(i+i1)));\r
+ addDeletion(ss1.get(i+i1));\r
+ }\r
+ i1 += same1;\r
+ } else {\r
+ for (int i = 0; i < same2; i++) {\r
+ System.out.println("Compare Statements diff2 " + printStatement(g,ss2.get(i+i2)));\r
+ addAddition(ss2.get(i+i2));\r
+ }\r
+ \r
+ i2 += same2;\r
+ }\r
+ \r
+ }\r
+ }\r
+ \r
+ private void compareUnreliableStatements(List<Statement> ss1, List<Statement> ss2) throws DatabaseException {\r
+ sortStatement(ss1, ss2);\r
+ \r
+ int i1 = 0;\r
+ int i2 = 0;\r
+ \r
+ while (true) {\r
+ if (i1 >= ss1.size()) {\r
+ if (i2 >= ss2.size()) {\r
+ break;\r
+ } else {\r
+ while (i2 < ss2.size()) {\r
+ System.out.println("Compare Statements diff2 " + printStatement(g,ss2.get(i2)));\r
+ \r
+ addAddition(ss2.get(i2));\r
+ i2++;\r
+ }\r
+ break;\r
+ }\r
+ } else if (i2 >= ss2.size()) {\r
+ while (i1 < ss1.size()) {\r
+ System.out.println("Compare Statements diff1 " + printStatement(g,ss1.get(i1)));\r
+ addDeletion(ss1.get(i1));\r
+ i1++;\r
+ }\r
+ break;\r
+ }\r
+ int same1 = sameRel(ss1, i1);\r
+ int same2 = sameRel(ss2, i2);\r
+ int c = rcomp.compare(ss1.get(i1).getPredicate(),ss2.get(i2).getPredicate());\r
+ if (c == 0) {\r
+ compareStatements(ss1, i1, same1, ss2, i2, same2,null, null, null, null);\r
i1+=same1;\r
i2+=same2;\r
} else if (c < 0) {\r
private int compareObject(Resource o1, Resource o2) throws DatabaseException {\r
if (comparableResources.contains(o1, o2))\r
return (-1);\r
+ if (comparableResources.containsLeft(o1))\r
+ return Integer.MAX_VALUE;\r
+ if (comparableResources.containsRight(o2))\r
+ return Integer.MAX_VALUE;\r
return comparator.compare(g, o1, o2);\r
}\r
\r
- private void compareStatements(List<Statement> ss1, int off1, int len1, List<Statement> ss2, int off2, int len2, Stack<Resource> stack1, Stack<Resource> stack2) throws DatabaseException {\r
+ private void compareStatements(List<Statement> ss1, int off1, int len1, List<Statement> ss2, int off2, int len2, Stack<Resource> objectsLeft, Stack<Resource> objectsRight, Stack<Statement> unreliableLeft, Stack<Statement> unreliableRight) throws DatabaseException {\r
boolean[] used1 = new boolean[len1];\r
for (int i = 0; i < used1.length; i++) {\r
used1[i] = false;\r
List<Integer> diff = new ArrayList<Integer>();\r
for (int i2 = off2; i2 < off2 + len2; i2++) {\r
Statement s2 = ss2.get(i2);\r
- diff.add(compareObject(s1.getObject(), s2.getObject()));\r
+ int d = compareObject(s1.getObject(), s2.getObject());\r
+ diff.add(d);\r
}\r
differences.add(diff);\r
}\r
Arrays.sort(pris);\r
\r
for (Integer pri : pris) {\r
- if (pri == Integer.MAX_VALUE)\r
+ if (pri == Integer.MAX_VALUE) {\r
+\r
+ } else if (pri == 0) {\r
+ Set<Statement> s1s = new HashSet<Statement>();\r
+ Set<Statement> s2s = new HashSet<Statement>();\r
+ List<Integer> i1s = priorities.getValues(pri);\r
+ for (Integer i1 : i1s) {\r
+\r
+ List<Integer> i2diff = differences.get(i1);\r
+ for (int i2 = 0; i2 < i2diff.size(); i2++) {\r
+ if (i2diff.get(i2) == pri) {\r
+ used1[i1] = true;\r
+ used2[i2] = true;\r
+ Statement s1 = ss1.get(i1+off1);\r
+ Statement s2 = ss2.get(i2+off2);\r
+ s1s.add(s1);\r
+ s2s.add(s2);\r
+ }\r
+ }\r
+ }\r
+ if (unreliableLeft != null) {\r
+ unreliableLeft.addAll(s1s);\r
+ unreliableRight.addAll(s2s);\r
+ }\r
continue;\r
- List<Integer> i1s = priorities.getValues(pri);\r
- for (Integer i1 : i1s) {\r
- if (used1[i1])\r
- continue;\r
- List<Integer> i2diff = differences.get(i1);\r
- for (int i2 = 0; i2 < i2diff.size(); i2++) {\r
- if (i2diff.get(i2) == pri) {\r
- if (used2[i2])\r
- continue;\r
- used1[i1] = true;\r
- used2[i2] = true;\r
- Statement s1 = ss1.get(i1+off1);\r
- Statement s2 = ss2.get(i2+off2);\r
- \r
- if (stack1 != null) {\r
- \r
- stack1.add(s1.getObject());\r
- stack2.add(s2.getObject());\r
- \r
- } else {\r
- // TODO : how should we report non traversed differences\r
- // using compareProps assumes that referenced objects are the same (references are not different)\r
- // using propsDiffCount assumes that objects are different, and cannot report changes in referred object.\r
- \r
+ } else {\r
+ List<Integer> i1s = priorities.getValues(pri);\r
+ for (Integer i1 : i1s) {\r
+ if (used1[i1])\r
+ continue;\r
+ List<Integer> i2diff = differences.get(i1);\r
+ for (int i2 = 0; i2 < i2diff.size(); i2++) {\r
+ if (i2diff.get(i2) == pri) {\r
+ if (used2[i2])\r
+ continue;\r
+ used1[i1] = true;\r
+ used2[i2] = true;\r
+ Statement s1 = ss1.get(i1+off1);\r
+ Statement s2 = ss2.get(i2+off2);\r
\r
-// int diff = propsDiffCount(ss1.get(i1+off1).getObject(), ss2.get(i2+off2).getObject());\r
-// if (diff != 0) {\r
-// //changes1.add(ss1.get(i1+off1));\r
-// //changes2.add(ss2.get(i2+off2));\r
-// modifies.add(new Pair<Statement, Statement>(ss1.get(i1+off1), ss2.get(i2+off2)));\r
-// }\r
+ if (objectsLeft != null) {\r
+ \r
+ objectsLeft.add(s1.getObject());\r
+ objectsRight.add(s2.getObject());\r
+ \r
+ } \r
+ comparableStatements.map(s1, s2);\r
+ //comparableResources.map(s1.getObject(), s2.getObject());\r
+ break;\r
}\r
- comparableStatements.map(s1, s2);\r
- //comparableResources.map(s1.getObject(), s2.getObject());\r
- break;\r
}\r
}\r
}\r
}\r
}\r
\r
+ public class SubjectComparator implements Comparator<Statement> {\r
+ @Override\r
+ public int compare(Statement o1, Statement o2) {\r
+ if (comparableResources.contains(o1.getSubject(), o2.getSubject()))\r
+ return 0;\r
+ if (o1.getSubject().getResourceId() < o2.getSubject().getResourceId())\r
+ return -1;\r
+ if (o1.getSubject().getResourceId() > o2.getSubject().getResourceId())\r
+ return 1;\r
+ return 0;\r
+ }\r
+ }\r
+ \r
+ public class ObjectComparator implements Comparator<Statement> {\r
+ @Override\r
+ public int compare(Statement o1, Statement o2) {\r
+ if (comparableResources.contains(o1.getObject(), o2.getObject()))\r
+ return 0;\r
+ if (o1.getObject().getResourceId() < o2.getObject().getResourceId())\r
+ return -1;\r
+ if (o1.getObject().getResourceId() > o2.getObject().getResourceId())\r
+ return 1;\r
+ return 0;\r
+ }\r
+ }\r
+ \r
public static class FullStatementComparator implements Comparator<Statement> {\r
@Override\r
public int compare(Statement o1, Statement o2) {\r
\r
\r
\r
- public class ResourceComparator implements Comparator<Resource> {\r
+ public class ResComparator implements Comparator<Resource> {\r
@Override\r
public int compare(Resource o1, Resource o2) {\r
if (comparableResources.contains(o1, o2))\r