diff --git a/reasoner/src/main/java/eu/knowledge/engine/reasoner/Match.java b/reasoner/src/main/java/eu/knowledge/engine/reasoner/Match.java index 68a0a3fb7..d7f083b47 100644 --- a/reasoner/src/main/java/eu/knowledge/engine/reasoner/Match.java +++ b/reasoner/src/main/java/eu/knowledge/engine/reasoner/Match.java @@ -76,21 +76,16 @@ public Match merge(Match otherMatch) { Match m = null; - // if both sides of the matching patterns do not overlap - boolean doMapsIntersect = doIntersect(this.getMatchingPatterns(), otherMatch.getMatchingPatterns()); - - if (!doMapsIntersect) { + var mergedMatchingPatterns = mergeMatchingPatterns(this.getMatchingPatterns(), + otherMatch.getMatchingPatterns()); + // if both sides of the matching patterns do not overlap + if (mergedMatchingPatterns != null) { // and if the mappings do not conflict Map mergedMapping = mergeContexts(this.getMappings(), otherMatch.getMappings()); if (mergedMapping != null) { // if both patterns and mappings do not conflict. - Map newMatchingPatterns = new HashMap<>(this.getMatchingPatterns()); - newMatchingPatterns.putAll(otherMatch.getMatchingPatterns()); - - Map newMapping = new HashMap<>(this.getMappings()); - newMapping.putAll(otherMatch.getMappings()); - m = new Match(newMatchingPatterns, newMapping); + m = new Match(mergedMatchingPatterns, mergedMapping); } } return m; @@ -101,19 +96,29 @@ public Match merge(Match otherMatch) { * * @param aFirstMap * @param aSecondMap - * @return + * @return {@code null} if the matching patterns overlap on either keys or + * values, otherwise the merged mapping. */ - private boolean doIntersect(Map aFirstMap, + private HashMap mergeMatchingPatterns(Map aFirstMap, Map aSecondMap) { + var mergedMatchingPatterns = new HashMap(aFirstMap.size() + aSecondMap.size()); + + boolean firstTime = true; + for (Entry entry1 : aFirstMap.entrySet()) { for (Entry entry2 : aSecondMap.entrySet()) { if (entry1.getKey().equals(entry2.getKey()) || entry1.getValue().equals(entry2.getValue())) - return true; + return null; + + if (firstTime) + mergedMatchingPatterns.put(entry2.getKey(), entry2.getValue()); } + mergedMatchingPatterns.put(entry1.getKey(), entry1.getValue()); + firstTime = false; } - return false; + return mergedMatchingPatterns; } public Map getMappings() { @@ -135,7 +140,10 @@ private Map mergeContexts(Map ex Map newContext) { Collection existingContextValues = existingContext.values(); - Map mergedContext = new HashMap(existingContext); + Map mergedContext = new HashMap( + existingContext.size() + newContext.size()); + mergedContext.putAll(existingContext); + for (Map.Entry newEntry : newContext.entrySet()) { Node node; if ((node = getOtherNode(existingContext, newEntry.getKey().node)) != null) {