X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.interop%2Fsrc%2Forg%2Fsimantics%2Finterop%2Ftest%2FGraphComparator.java;h=6f8c4d1b15e13d10a652dac5551abbb7d0a329e1;hb=7bd962c96d0a43bbc0fca67e87a1bc877a451fe0;hp=aa2ddee72f84c3cd23dbb25cdc32768deb8852a3;hpb=97c68766209d534318dfc146727eb5670fca848e;p=simantics%2Finterop.git diff --git a/org.simantics.interop/src/org/simantics/interop/test/GraphComparator.java b/org.simantics.interop/src/org/simantics/interop/test/GraphComparator.java index aa2ddee..6f8c4d1 100644 --- a/org.simantics.interop/src/org/simantics/interop/test/GraphComparator.java +++ b/org.simantics.interop/src/org/simantics/interop/test/GraphComparator.java @@ -20,9 +20,11 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.Stack; +import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.Session; @@ -30,6 +32,7 @@ import org.simantics.db.Statement; import org.simantics.db.common.request.ReadRequest; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; +import org.simantics.interop.test.GraphChanges.Modification; import org.simantics.layer0.Layer0; import org.simantics.utils.datastructures.BijectionMap; import org.simantics.utils.datastructures.MapList; @@ -53,21 +56,21 @@ public class GraphComparator { private Resource r1; private Resource r2; - private Set strong = new HashSet(); // List of relations that identify object, if subject is already identified. - private List traversed = new ArrayList(); // list of relations that are traversed (and tested) - private List tested = new ArrayList(); // list of relations that are tested, but not traversed - private List nonTraversed = new ArrayList(); // list of relations that are not traversed - private List nonTested = new ArrayList(); // list of relations that are not tested - - private List changes1 = new ArrayList(); - private List changes2 = new ArrayList(); - private List> modifications = new ArrayList>(); - private Set changes1Set = new HashSet(); - private Set changes2Set = new HashSet(); - private Set> modificationsSet = new HashSet>(); + private Set strong = new HashSet<>(); // List of relations that identify object, if subject is already identified. + private List traversed = new ArrayList<>(); // list of relations that are traversed (and tested) + private List tested = new ArrayList<>(); // list of relations that are tested, but not traversed + private List nonTraversed = new ArrayList<>(); // list of relations that are not traversed + private List nonTested = new ArrayList<>(); // list of relations that are not tested + + private List changes1 = new ArrayList<>(); + private List changes2 = new ArrayList<>(); + private List modifications = new ArrayList<>(); + private Set changes1Set = new HashSet<>(); + private Set changes2Set = new HashSet<>(); + private Set modificationsSet = new HashSet<>(); - private BijectionMap comparableStatements = new BijectionMap(); - private BijectionMap comparableResources = new BijectionMap(); + private BijectionMap comparableStatements = new BijectionMap<>(); + private BijectionMap comparableResources = new BijectionMap<>(); private Set processedResources = new HashSet(); @@ -149,10 +152,16 @@ public class GraphComparator { } public void addComparableResources(Resource r1, Resource r2) { + if (DEBUG) + System.out.println("Preset " + r1 + " = " + r2); comparableResources.map(r1, r2); } public void addComparableResources(BijectionMap matching) { + if (DEBUG) { + for (Entry entry : matching.getEntries()) + System.out.println("Preset " + entry.getKey() + " = " + entry.getValue()); + } comparableResources.addAll(matching); } @@ -176,6 +185,7 @@ public class GraphComparator { this.g = g; this.b = Layer0.getInstance(g); comparator.setComparator(this); + comparator.initialize(g, r1, r2); Stack objectsLeft = new Stack(); Stack objectsRight = new Stack(); @@ -196,6 +206,9 @@ public class GraphComparator { processUnreliable(unreliableLeft, unreliableRight); // process unreliable handles cases where unidentified resources have path of length one to identified resource processUnreliable(unreliableLeft, unreliableRight,objectsLeft,objectsRight); + if (objectsLeft.isEmpty() && unreliableLeft.size() > 0 && unreliableRight.size() > 0) { + 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. @@ -211,8 +224,6 @@ public class GraphComparator { if (!comparableStatements.containsRight(s)) addAddition(s); } - - } public void test(Session session) throws DatabaseException { @@ -223,7 +234,15 @@ public class GraphComparator { comparator.setComparator(this); - addComparable(r1, r2, false); + session.syncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + comparator.initialize(graph, r1, r2); + } + }); + + addComparable(r1, r2); final Stack objectsLeft = new Stack(); final Stack objectsRight = new Stack(); @@ -248,6 +267,14 @@ public class GraphComparator { processUnreliable(unreliableLeft, unreliableRight); // process unreliable handles cases where unidentified resources have path of length one to identified resource processUnreliable(unreliableLeft, unreliableRight,objectsLeft,objectsRight); + if (objectsLeft.isEmpty() && unreliableLeft.size() > 0 && unreliableRight.size() > 0) { + 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. + 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. @@ -281,7 +308,6 @@ public class GraphComparator { if (r1.equals(r2)) continue; - if (processedResources.contains(r1)) continue; processedResources.add(r1); @@ -290,7 +316,7 @@ public class GraphComparator { if((comparableResources.containsLeft(r1)||comparableResources.containsRight(r2)) && !comparableResources.contains(r1, r2)) { throw new DatabaseException("Comparator error: Trying to map " + r1 + " to " + r2 + " while mappings " + r1 + " to " + comparableResources.getRight(r1) + " and " + comparableResources.getLeft(r2) + " to " + r2 + " exist."); } - addComparable(r1, r2, false); + addComparable(r1, r2); //System.out.println("test " + NameUtils.getSafeName(g, r1) + " " + NameUtils.getSafeName(g, r2)); compareProps(r1, r2); @@ -342,16 +368,16 @@ public class GraphComparator { } for (Resource left : subjectLeft.getKeys()) { - if (!comparableResources.containsLeft(left)) - continue; Resource right = comparableResources.getRight(left); + if (right == null) + continue; for (Statement leftS : subjectLeft.getValues(left)) { Resource leftO = leftS.getObject(); - if (!comparableResources.containsLeft(leftO)) - continue; if (!unreliableLeft.contains(leftS)) continue; Resource rightO = comparableResources.getRight(leftO); + if (rightO == null) + continue; for (Statement rightS : subjectRight.getValues(right)) { if (!rightS.getObject().equals(rightO)) continue; @@ -361,7 +387,7 @@ public class GraphComparator { comparableResources.contains(leftS.getPredicate(), rightS.getPredicate())) { unreliableLeft.remove(leftS); unreliableRight.remove(rightS); - addComparable(leftS, rightS, false); + addComparable(leftS, rightS); } } } @@ -407,6 +433,8 @@ public class GraphComparator { } } + compareStatements(ss1, ss2, objectsLeft, objectsRight,unreliableLeft,unreliableRight); + for (Resource similarOl : comparableOLeft.getKeys()) { List similarLeft = comparableOLeft.getValues(similarOl); if (similarLeft.size() == left.size()) { @@ -420,12 +448,18 @@ public class GraphComparator { for (int j = 0; j < left.size(); j++) { if (useSL[j]) continue; + // compare predicates Resource pl = left.get(i).getPredicate(); Resource psl = similarLeft.get(j).getPredicate(); if (pl.equals(psl)) { - useL[i] = true; - useSL[j] = true; - break; + // compare objects (unreliable result is interpreted as positive match) + + int comp = comparator.compare(g, left.get(i).getObject(), similarLeft.get(j).getObject(), true); + if (comp >= 0 && comp < Integer.MAX_VALUE) { + useL[i] = true; + useSL[j] = true; + break; + } } } } @@ -483,8 +517,13 @@ public class GraphComparator { if (!comparableResources.contains(ls.getSubject(), rs.getSubject())) continue; if (rcomp.compare(ls.getPredicate(),rs.getPredicate()) == 0) { - iLeft[l] = r; - iRight[r] = l; + // compare objects (unreliable result is not accepted) + int comp = comparator.compare(g, ls.getObject(), rs.getObject()); + if (comp > 0 && comp < Integer.MAX_VALUE) { + iLeft[l] = r; + iRight[r] = l; + break; + } break; } } @@ -516,16 +555,18 @@ public class GraphComparator { objectsLeft.add(ol); objectsRight.add(or); - addComparable(ol, or, false); + addComparable(ol, or); for (int l = 0; l < left.size(); l++) { int r = indices.first[l]; Statement sl = left.get(l); Statement sr = right.get(r); - addComparable(sl, sr, true); + addComparable(sl, sr); unreliableLeft.remove(sl); unreliableRight.remove(sr); } + } else { + } } @@ -533,6 +574,49 @@ public class GraphComparator { } + private void processUnreliable2(Set unreliableLeft, Set unreliableRight, Stack objectsLeft, Stack objectsRight) throws DatabaseException { + MapList subjectLeft = new MapList(); + MapList subjectRight = new MapList(); + MapList objectLeft = new MapList(); + MapList objectRight = new MapList(); + + for (Statement s : unreliableLeft) { + subjectLeft.add(s.getSubject(),s); + objectLeft.add(s.getObject(),s); + } + for (Statement s : unreliableRight) { + subjectRight.add(s.getSubject(),s); + objectRight.add(s.getObject(),s); + } + + for (Resource ol : objectLeft.getKeys()) { + // all statements to the left side object + List left = objectLeft.getValues(ol); + // all subjects that have statements to the left side object (ol) + Set sLeft = new HashSet(); + // all matching subjects on the right side + Set sRight = new HashSet(); + for (Statement s : left) { + sLeft.add(s.getSubject()); + sRight.add(comparableResources.getRight(s.getSubject())); + } + + if (sLeft.size() == 1 && sRight.size() == 1) { + List ss1 = new ArrayList(subjectLeft.getValues(sLeft.iterator().next())); + List ss2 = new ArrayList(subjectRight.getValues(sRight.iterator().next())); + + int count = comparableStatements.size(); + compareStatements(ss1, ss2, objectsLeft, objectsRight,unreliableLeft,unreliableRight); + if (comparableStatements.size() > count) { + for (Entry entry : comparableStatements.getEntries()) { + unreliableLeft.remove(entry.getKey()); + unreliableRight.remove(entry.getValue()); + } + } + } + } + } + private void processUnreliableDeep(Set unreliableLeft, Set unreliableRight, Stack objectsLeft, Stack objectsRight) throws DatabaseException { MapList subjectLeft = new MapList(); MapList subjectRight = new MapList(); @@ -591,7 +675,7 @@ public class GraphComparator { objectsLeft.add(ol); objectsRight.add(or); - addComparable(ol, or, false); + addComparable(ol, or); Collection statementsLeft = objectLeft.getValues(ol); Collection statementsRight = objectRight.getValues(or); unreliableLeft.removeAll(statementsLeft); @@ -600,7 +684,7 @@ public class GraphComparator { for (Path left : map.getLeftSet()) { Path right = map.getRight(left); for (int i = 0; i < left.getLength(); i++) { - addComparable(left.getStatements().get(i),right.getStatements().get(i),false); + addComparable(left.getStatements().get(i),right.getStatements().get(i)); } } } @@ -627,8 +711,19 @@ public class GraphComparator { if (leftPath.getLength() != rightPath.getLength()) continue; if (comparableResources.contains(leftPath.getEnd(), rightPath.getEnd())) { - map.map(leftPath, rightPath); - break; + boolean preds = true; + for (int i = 0; i < leftPath.getLength(); i++) { + Statement sl = leftPath.getStatements().get(i); + Statement sr = rightPath.getStatements().get(i); + if (!sl.getPredicate().equals(sr.getPredicate()) && !comparableResources.contains(sl.getPredicate(), sr.getPredicate())) { + preds = false; + break; + } + } + if (preds) { + map.map(leftPath, rightPath); + break; + } } } } @@ -691,19 +786,19 @@ public class GraphComparator { return new GraphChanges(r1,r2,changes1,changes2,modifications,comparableResources); } - private void addComparable(Statement left, Statement right, boolean process) throws DatabaseException { - addComparable(left.getObject(), right.getObject(), process); + private void addComparable(Statement left, Statement right) throws DatabaseException { + addComparable(left.getObject(), right.getObject()); comparableStatements.map(left, right); //comparableResources.map(left.getObject(), right.getObject()); } - private void addComparable(Resource left, Resource right, boolean process) throws DatabaseException { + private void addComparable(Resource left, Resource right) throws DatabaseException { if(!comparableResources.contains(left, right)) { if (comparableResources.containsLeft(left)||comparableResources.containsRight(right)) { throw new DatabaseException("Comparator error: Trying to map " + left + " to " + right + " while mappings " + left + " to " + comparableResources.getRight(left) + " and " + comparableResources.getLeft(right) + " to " + right + " exist."); } else { if (DEBUG) System.out.println(left + " = " + right); - comparableResources.map(left, right); + comparableResources.map(left, right); } } @@ -719,6 +814,31 @@ public class GraphComparator { return out; } + public List filterAssertedDuplicates(Resource r, List in) throws DatabaseException { + List out = new ArrayList(); + for (int i = 0; i < in.size(); i++) { + Statement s = in.get(i); + if (!s.isAsserted(r)) + out.add(s); + else { + boolean has = false; + if (i > 1 && in.get(i-1).getPredicate().equals(s.getPredicate())) + has = true; + else if (i < in.size()-1 && in.get(i+1).getPredicate().equals(s.getPredicate())) + has = true; + if (!has) + out.add(s); + } + + } + for (Statement s : in) { + if (!s.isAsserted(r)) + out.add(s); + + } + return out; + } + private String printStatement(ReadGraph graph, Statement s) throws DatabaseException { @@ -772,8 +892,8 @@ public class GraphComparator { } } - private void addModification(Statement s1, Statement s2) { - Pair mod = new Pair(s1,s2); + private void addModification(Resource sub1, Statement s1, Resource sub2, Statement s2) { + Modification mod = new Modification(sub1, sub2, s1, s2); if (!modificationsSet.contains(mod)) { modificationsSet.add(mod); modifications.add(mod); @@ -1009,7 +1129,7 @@ public class GraphComparator { objectsLeft.add(s1.getObject()); objectsRight.add(s2.getObject()); } - addComparable(s1, s2, true); + addComparable(s1, s2); break; } } @@ -1085,6 +1205,9 @@ public class GraphComparator { ss1 = filterNonTested(ss1); ss2 = filterNonTested(ss2); sortStatement(ss1, ss2); + // getStatements(r1, b.HasProperty) returns both instance and asserted statements for the same property relation. + ss1 = filterAssertedDuplicates(r1, ss1); + ss2 = filterAssertedDuplicates(r2, ss2); int i1 = 0; int i2 = 0; @@ -1095,16 +1218,20 @@ public class GraphComparator { break; else { while (i2 < ss2.size()) { - if (DEBUG) System.out.println("Compare Prop diff2 " + printStatement(g,ss2.get(i2))); - addAddition(ss2.get(i2)); + Statement s = ss2.get(i2); + if (DEBUG) System.out.println("Compare Prop diff2 " + printStatement(g,s)); + if (!s.isAsserted(r2)) + addAddition(s); i2++; } break; } } else if (i2 >= ss2.size()) { while (i1 < ss1.size()) { - if (DEBUG) System.out.println("Compare Prop diff1 " + printStatement(g,ss1.get(i1))); - addDeletion(ss1.get(i1)); + Statement s = ss1.get(i1); + if (DEBUG) System.out.println("Compare Prop diff1 " + printStatement(g,s)); + if (!s.isAsserted(r1)) + addDeletion(s); i1++; } break; @@ -1123,20 +1250,23 @@ public class GraphComparator { boolean b2 = g.hasValue(s2.getObject()); if (b1 == b2) { if (b1) { - Object v1 = g.getValue(s1.getObject()); - Object v2 = g.getValue(s2.getObject()); - boolean eq = compareValue(v1, v2); +// Object v1 = g.getValue(s1.getObject()); +// Object v2 = g.getValue(s2.getObject()); +// boolean eq = compareValue(v1, v2); + boolean eq = compareValue(g,b,s1.getObject(), s2.getObject()); if (!eq) { - addModification(s1, s2); - addComparable(s1, s2, false); + addModification(r1,s1,r2,s2); + if (!s1.isAsserted(r1) && !s2.isAsserted(r2)) + addComparable(s1, s2); } } else { if (!s1.getObject().equals(s1.getSubject()) && !s2.getObject().equals(s2.getSubject())) compareProps(s1.getObject(), s2.getObject()); } } else { - addModification(s1, s2); - addComparable(s1, s2, false); + addModification(r1,s1,r2,s2); + if (!s1.isAsserted(r1) && !s2.isAsserted(r2)) + addComparable(s1, s2); } i1++; i2++; @@ -1164,6 +1294,75 @@ public class GraphComparator { } + public static boolean compareValue(ReadGraph g, Layer0 b, Resource r1, Resource r2) throws DatabaseException { + Resource t1 = g.getSingleType(r1); + Resource t2 = g.getSingleType(r2); + if (!t1.equals(t2)) + return false; + if (t1.equals(b.Integer)) { + int v1 = g.getValue(r1, Bindings.INTEGER); + int v2 = g.getValue(r2, Bindings.INTEGER); + return v1 == v2; + } else if (t1.equals(b.Float)) { + float v1 = g.getValue(r1, Bindings.FLOAT); + float v2 = g.getValue(r2, Bindings.FLOAT); + return v1 == v2; + } else if (t1.equals(b.Double)) { + double v1 = g.getValue(r1, Bindings.DOUBLE); + double v2 = g.getValue(r2, Bindings.DOUBLE); + return v1 == v2; + } else if (t1.equals(b.String)) { + String v1 = g.getValue(r1, Bindings.STRING); + String v2 = g.getValue(r2, Bindings.STRING); + return v1.equals(v2); + } else if (t1.equals(b.Boolean)) { + boolean v1 = g.getValue(r1, Bindings.BOOLEAN); + boolean v2 = g.getValue(r2, Bindings.BOOLEAN); + return v1 == v2; + } else if (t1.equals(b.Byte)) { + byte v1 = g.getValue(r1, Bindings.BYTE); + byte v2 = g.getValue(r2, Bindings.BYTE); + return v1 == v2; + } else if (t1.equals(b.Long)) { + long v1 = g.getValue(r1, Bindings.LONG); + long v2 = g.getValue(r2, Bindings.LONG); + return v1 == v2; + } else if (t1.equals(b.IntegerArray)) { + int[] v1 = g.getValue(r1, Bindings.INT_ARRAY); + int[] v2 = g.getValue(r2, Bindings.INT_ARRAY); + return Arrays.equals(v1,v2); + } else if (t1.equals(b.FloatArray)) { + float[] v1 = g.getValue(r1, Bindings.FLOAT_ARRAY); + float[] v2 = g.getValue(r2, Bindings.FLOAT_ARRAY); + return Arrays.equals(v1,v2); + } else if (t1.equals(b.DoubleArray)) { + double[] v1 = g.getValue(r1, Bindings.DOUBLE_ARRAY); + double[] v2 = g.getValue(r2, Bindings.DOUBLE_ARRAY); + return Arrays.equals(v1,v2); + } else if (t1.equals(b.StringArray)) { + String[] v1 = g.getValue(r1, Bindings.STRING_ARRAY); + String[] v2 = g.getValue(r2, Bindings.STRING_ARRAY); + return Arrays.equals(v1,v2); + } else if (t1.equals(b.BooleanArray)) { + boolean[] v1 = g.getValue(r1, Bindings.BOOLEAN_ARRAY); + boolean[] v2 = g.getValue(r2, Bindings.BOOLEAN_ARRAY); + return Arrays.equals(v1,v2); + } else if (t1.equals(b.ByteArray)) { + byte[] v1 = g.getValue(r1, Bindings.BYTE_ARRAY); + byte[] v2 = g.getValue(r2, Bindings.BYTE_ARRAY); + return Arrays.equals(v1,v2); + } else if (t1.equals(b.LongArray)) { + long[] v1 = g.getValue(r1, Bindings.LONG_ARRAY); + long[] v2 = g.getValue(r2, Bindings.LONG_ARRAY); + return Arrays.equals(v1,v2); + } else { + Object v1 = g.getValue(r1); + Object v2 = g.getValue(r2); + return compareValue(v1, v2); + } + + } + public static boolean compareValue(Object v1, Object v2) { if (v1 instanceof Object[] && v2 instanceof Object[]) return Arrays.deepEquals((Object[])v1, (Object[])v2);