com.github.gumtreediff.matchers.optimizations.InnerNodesMatcherThetaD Maven / Gradle / Ivy
The newest version!
/*
* This file is part of GumTree.
*
* GumTree is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GumTree is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GumTree. If not, see .
*
* Copyright 2015-2016 Georg Dotzler
* Copyright 2015-2016 Marius Kamp
*/
package com.github.gumtreediff.matchers.optimizations;
import java.util.Collections;
import java.util.Comparator;
import java.util.IdentityHashMap;
import java.util.LinkedList;
import java.util.Map.Entry;
import com.github.gumtreediff.matchers.Mapping;
import com.github.gumtreediff.matchers.MappingStore;
import com.github.gumtreediff.matchers.Matcher;
import com.github.gumtreediff.tree.Tree;
/**
* This implements the unmapped leaves optimization (Theta C), the inner node
* repair optimization (Theta D) and the leaf move optimization (Theta E).
*/
public class InnerNodesMatcherThetaD implements Matcher {
private Tree src;
private Tree dst;
private MappingStore mappings;
@Override
public MappingStore match(Tree src, Tree dst, MappingStore mappings) {
this.src = src;
this.dst = dst;
this.mappings = mappings;
thetaD();
return mappings;
}
private class ChangeMapComparator implements Comparator>> {
@Override
public int compare(Entry> o1,
Entry> o2) {
return Integer.compare(o1.getKey().getMetrics().position, o2.getKey().getMetrics().position);
}
}
private boolean allowedMatching(Tree key, Tree maxNodePartner) {
while (key != null) {
if (key == maxNodePartner) {
return false;
}
key = key.getParent();
}
return true;
}
private void thetaD() {
IdentityHashMap> parentCount = new IdentityHashMap<>();
for (Mapping pair : mappings.asSet()) {
Tree parent = pair.first.getParent();
Tree parentPartner = pair.second.getParent();
if (parent != null && parentPartner != null) {
IdentityHashMap countMap = parentCount.get(parent);
if (countMap == null) {
countMap = new IdentityHashMap<>();
parentCount.put(parent, countMap);
}
Integer count = countMap.get(parentPartner);
if (count == null) {
count = Integer.valueOf(0);
}
countMap.put(parentPartner, count + 1);
}
}
LinkedList>> list = new LinkedList<>(parentCount.entrySet());
Collections.sort(list, new ChangeMapComparator());
for (Entry> countEntry : list) {
int max = Integer.MIN_VALUE;
int maxCount = 0;
Tree maxNode = null;
for (Entry newNodeEntry : countEntry.getValue().entrySet()) {
if (newNodeEntry.getValue() > max) {
max = newNodeEntry.getValue();
maxCount = 1;
maxNode = newNodeEntry.getKey();
} else if (newNodeEntry.getValue() == max) {
maxCount++;
}
}
if (maxCount == 1) {
if (mappings.getDstForSrc(countEntry.getKey()) != null && mappings.getSrcForDst(maxNode) != null) {
Tree partner = mappings.getDstForSrc(countEntry.getKey());
Tree maxNodePartner = mappings.getSrcForDst(maxNode);
if (partner != maxNode) {
if (max > countEntry.getKey().getChildren().size() / 2
|| countEntry.getKey().getChildren().size() == 1) {
Tree parentPartner = mappings.getDstForSrc(countEntry.getKey().getParent());
if (parentPartner != null && parentPartner == partner.getParent()) {
continue;
}
if (allowedMatching(countEntry.getKey(), maxNodePartner)) {
if (countEntry.getKey().getType() == maxNode.getType()) {
if (maxNodePartner != null) {
mappings.removeMapping(maxNodePartner, maxNode);
}
if (partner != null) {
mappings.removeMapping(countEntry.getKey(), partner);
}
mappings.addMapping(countEntry.getKey(), maxNode);
}
if (maxNodePartner != null) {
if (maxNodePartner.getType() == partner.getType()) {
mappings.addMapping(maxNodePartner, partner);
}
}
}
}
}
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy