+ boolean matchFail = priorityMatching(ss1, off1, len1, ss2, off2, len2, pris, differences, priorities, used1, used2, objectsLeft, objectsRight, false);
+ if (matchFail)
+ matchFail = priorityMatching(ss1, off1, len1, ss2, off2, len2, pris, differences, priorities, used1, used2, objectsLeft, objectsRight, objectsLeft == null);
+ if (unreliableLeft != null) {
+ if (matchFail) {
+ // With match failure, statement matching was aborted. We must move all unmatched statements to unreliable.
+ for (Integer pri : pris) {
+ if (pri == 0 || pri == Integer.MAX_VALUE)
+ continue;
+ priorityProcessUnmatched(ss1, off1, len1, ss2, off2, len2, differences, priorities, used1, used2, unreliableLeft, unreliableRight, pri);
+ }
+ }
+ // Zero means unreliable comparison result, move all unmatched to unreliable.
+ if (org.simantics.utils.datastructures.Arrays.contains(pris, 0)) {
+ priorityProcessUnmatched(ss1, off1, len1, ss2, off2, len2, differences, priorities, used1, used2, unreliableLeft, unreliableRight, 0);
+ }
+ }
+// Previous version processed 0 priority statements, even when unreliableLeft collection was null.
+// The problem was that property relations were not filtered in process() from "tested" statements.
+// else {
+// if (org.simantics.utils.datastructures.Arrays.contains(pris, 0)) {
+// priorityProcessUnmatched(ss1, off1, len1, ss2, off2, len2, differences, priorities, used1, used2, unreliableLeft, unreliableRight, 0);
+// }
+// }
+ // Report unmatched statements as changes.
+ for (int i1 = off1; i1 < off1 + len1; i1++) {
+ if (!used1[i1-off1]) {
+ if (DEBUG) System.out.println("Compare Object deletion " + printStatement(g,ss1.get(i1)));
+ addDeletion(ss1.get(i1));
+ }
+ }
+ for (int i2 = off2; i2 < off2 + len2; i2++) {
+ if (!used2[i2-off2]) {
+ if (DEBUG) System.out.println("Compare Object addition " + printStatement(g,ss2.get(i2)));
+ addAddition(ss2.get(i2));
+ }
+ }
+ }
+
+ /**
+ * Moves unmatched statements to unreliable collections.
+ * @param ss1
+ * @param off1
+ * @param len1
+ * @param ss2
+ * @param off2
+ * @param len2
+ * @param differences
+ * @param priorities
+ * @param used1
+ * @param used2
+ * @param unreliableLeft
+ * @param unreliableRight
+ * @param pri
+ */
+ private void priorityProcessUnmatched(List<Statement> ss1, int off1, int len1, List<Statement> ss2, int off2, int len2,List<List<Integer>> differences,MapList<Integer, Integer> priorities,boolean used1[],boolean used2[], Collection<Statement> unreliableLeft, Collection<Statement> unreliableRight, int pri) {
+ Set<Statement> s1s = new HashSet<Statement>();
+ Set<Statement> s2s = new HashSet<Statement>();
+ Set<Integer> s1i = new HashSet<Integer>();
+ Set<Integer> s2i = new HashSet<Integer>();
+ List<Integer> i1s = priorities.getValues(pri);
+ for (Integer i1 : i1s) {
+ if (used1[i1])
+ continue;
+ List<Integer> i2diff = differences.get(i1);
+ for (int i2 = 0; i2 < i2diff.size(); i2++) {
+ if (i2diff.get(i2) == pri) {
+ if (used2[i2])
+ continue;
+ Statement s1 = ss1.get(i1+off1);
+ Statement s2 = ss2.get(i2+off2);
+ s1s.add(s1);
+ s2s.add(s2);
+ s1i.add(i1);
+ s2i.add(i2);
+ }
+ }
+ }
+ if (unreliableLeft != null) {
+ unreliableLeft.addAll(s1s);
+ unreliableRight.addAll(s2s);
+ }
+ for (Integer i : s1i)
+ used1[i] = true;
+ for (Integer i : s2i)
+ used2[i] = true;
+ }
+ /**
+ * Matches left and right side statements.
+ *
+ * When there are two or more equally good matching objects, the behaviour depends on force flag.
+ * False: Matching is aborted and matchFail is returned (method return true).
+ * True: equally good matches will be paired randomly. Method always returns false.
+ * @param ss1
+ * @param off1
+ * @param len1
+ * @param ss2
+ * @param off2
+ * @param len2
+ * @param pris
+ * @param differences
+ * @param priorities
+ * @param used1
+ * @param used2
+ * @param objectsLeft
+ * @param objectsRight
+ * @param force
+ * @return
+ * @throws DatabaseException
+ */
+ private boolean priorityMatching(List<Statement> ss1, int off1, int len1, List<Statement> ss2, int off2, int len2, Integer[] pris, List<List<Integer>> differences, MapList<Integer, Integer> priorities, boolean used1[],boolean used2[], Collection<Resource> objectsLeft, Collection<Resource> objectsRight, boolean force) throws DatabaseException {
+ boolean matchFail = false;