Improve the performance of regrouping algorithm for GumTree results.

This commit is contained in:
Kui LIU
2017-09-10 11:11:16 +02:00
parent b635c4a703
commit bee915e2c1
@@ -8,6 +8,7 @@ import com.github.gumtreediff.actions.model.Addition;
import com.github.gumtreediff.actions.model.Delete; import com.github.gumtreediff.actions.model.Delete;
import com.github.gumtreediff.actions.model.Insert; import com.github.gumtreediff.actions.model.Insert;
import com.github.gumtreediff.actions.model.Move; import com.github.gumtreediff.actions.model.Move;
import com.github.gumtreediff.actions.model.Update;
import com.github.gumtreediff.tree.ITree; import com.github.gumtreediff.tree.ITree;
import edu.lu.uni.serval.FixPattern.utils.ASTNodeMap; import edu.lu.uni.serval.FixPattern.utils.ASTNodeMap;
@@ -21,14 +22,14 @@ import edu.lu.uni.serval.utils.ListSorter;
*/ */
public class HierarchicalRegrouper { public class HierarchicalRegrouper {
public List<HierarchicalActionSet> regroupGumTreeResults(List<Action> actionsArgu) { public List<HierarchicalActionSet> regroupGumTreeResults(List<Action> actions) {
/* /*
* First, sort actions by their positions. * First, sort actions by their positions.
*/ */
List<Action> actions = new ListSorter<Action>(actionsArgu).sortAscending(); // List<Action> actions = new ListSorter<Action>(actionsArgu).sortAscending();
if (actions == null) { // if (actions == null) {
actions = actionsArgu; // actions = actionsArgu;
} // }
/* /*
* Second, group actions by their positions. * Second, group actions by their positions.
@@ -84,7 +85,7 @@ public class HierarchicalRegrouper {
int index = actStrFrag.lastIndexOf(" ") + 1; int index = actStrFrag.lastIndexOf(" ") + 1;
String nodeType = actStrFrag.substring(index); String nodeType = actStrFrag.substring(index);
if (!"".equals(nodeType)) { if (!"".equals(nodeType)) {
if (Character.isDigit(nodeType.charAt(0)) || nodeType.startsWith("-")) { if (Character.isDigit(nodeType.charAt(0)) || (nodeType.startsWith("-") && Character.isDigit(nodeType.charAt(1)))) {
try { try {
int typeInt = Integer.parseInt(nodeType); int typeInt = Integer.parseInt(nodeType);
if (ASTNodeMap.map.containsKey(typeInt)) { if (ASTNodeMap.map.containsKey(typeInt)) {
@@ -108,68 +109,71 @@ public class HierarchicalRegrouper {
for (HierarchicalActionSet actSet : actionSets) { for (HierarchicalActionSet actSet : actionSets) {
if (actSet.equals(actionSet)) continue; if (actSet.equals(actionSet)) continue;
Action action = actSet.getAction(); Action action = actSet.getAction();
if (action instanceof Move && !(act instanceof Move)) continue; // If action is MOV, its children must be MOV.
if (action instanceof Insert && !(act instanceof Addition)) continue;// If action is INS, its children must be MOV or INS. if (!areRelatedActions(action, act)) continue;
if (action instanceof Delete && !(act instanceof Delete)) continue;// If action is DEL, its children must be DEL.
if (action.equals(parentAct)) { // actSet is the parent of actionSet. if (action.equals(parentAct)) { // actSet is the parent of actionSet.
actionSet.setParent(actSet); actionSet.setParent(actSet);
actSet.getSubActions().add(actionSet); actSet.getSubActions().add(actionSet);
ListSorter<HierarchicalActionSet> sorter = new ListSorter<HierarchicalActionSet>(actSet.getSubActions()); sortSubActions(actSet);
List<HierarchicalActionSet> subActions = sorter.sortAscending();
if (subActions != null) {
actSet.setSubActions(subActions);
}
break; break;
} else { } else {
// if (!(action instanceof Addition) && !(act instanceof Addition)) { if ((action instanceof Update && !(act instanceof Addition))
//// || (action instanceof Insert && (act instanceof Insert))) { || (action instanceof Delete && act instanceof Delete)
// int startPosition = act.getPosition(); || (action instanceof Insert && (act instanceof Insert))) {
// int length = act.getLength(); int startPosition = act.getPosition();
// int startP = action.getPosition(); int length = act.getLength();
// int leng = action.getLength(); int startPosition2 = action.getPosition();
// int length2 = action.getLength();
// if (startP > startPosition + length) {
// break; if (!(startPosition2 >= startPosition && startPosition + length <= startPosition2 + length2)) {
// } else if (startP + leng < startPosition) { // when act is not the sub-set of action.
// continue; continue;
// } }
// } }
// SubAction range startP <= startPosition && startPosition + length <= startP + leng // SubAction range startPosition2 <= startPosition && startPosition + length <= startPosition2 + length2
addToActionSets(actionSet, parentAct, actSet.getSubActions()); addToActionSets(actionSet, parentAct, actSet.getSubActions());
} }
} }
} }
private void sortSubActions(HierarchicalActionSet actionSet) {
ListSorter<HierarchicalActionSet> sorter = new ListSorter<HierarchicalActionSet>(actionSet.getSubActions());
List<HierarchicalActionSet> subActions = sorter.sortAscending();
if (subActions != null) {
actionSet.setSubActions(subActions);
}
}
private boolean addToAactionSet(Action act, Action parentAct, List<HierarchicalActionSet> actionSets) { private boolean addToAactionSet(Action act, Action parentAct, List<HierarchicalActionSet> actionSets) {
ITree parentTree = parentAct.getNode(); ITree parentTree = parentAct.getNode();
for(HierarchicalActionSet actionSet : actionSets) { for(HierarchicalActionSet actionSet : actionSets) {
Action action = actionSet.getAction(); Action action = actionSet.getAction();
if (action instanceof Move && !(act instanceof Move)) continue; // If action is MOV, its children must be MOV.
if (action instanceof Insert && !(act instanceof Addition)) continue;// If action is INS, its children must be MOV or INS. if (!areRelatedActions(action, act)) continue;
if (action instanceof Delete && !(act instanceof Delete)) continue;// If action is DEL, its children must be DEL.
ITree tree = action.getNode(); ITree tree = action.getNode();
if (tree.equals(parentTree)) { // actionSet is the parent of actSet. if (tree.equals(parentTree)) { // actionSet is the parent of actSet.
HierarchicalActionSet actSet = createActionSet(act, actionSet.getAction(), actionSet); HierarchicalActionSet actSet = createActionSet(act, actionSet.getAction(), actionSet);
actionSet.getSubActions().add(actSet); actionSet.getSubActions().add(actSet);
sortSubActions(actionSet);
return true; return true;
} else { } else {
// if (!(action instanceof Addition) && !(act instanceof Addition)) { if ((action instanceof Update && !(act instanceof Addition))
//// || (action instanceof Insert && (act instanceof Insert))) { || (action instanceof Delete && act instanceof Delete)
// int startPosition = act.getPosition(); || (action instanceof Insert && (act instanceof Insert))) {
// int length = act.getLength(); int startPosition = act.getPosition();
// int startP = action.getPosition(); int length = act.getLength();
// int leng = action.getLength(); int startPosition2 = action.getPosition();
// int length2 = action.getLength();
// if (startP > startPosition + length) {
// break; if (!(startPosition2 >= startPosition && startPosition + length <= startPosition2 + length2)) {
// } else if (startP + leng < startPosition) { // when act is not the sub-set of action.
// continue; continue;
// } }
// } }
// SubAction range startP <= startPosition && startPosition + length <= startP + leng // SubAction range startPosition2 <= startPosition && startPosition + length <= startP + length2
List<HierarchicalActionSet> subActionSets = actionSet.getSubActions(); List<HierarchicalActionSet> subActionSets = actionSet.getSubActions();
if (subActionSets.size() > 0) { if (subActionSets.size() > 0) {
boolean added = addToAactionSet(act, parentAct, subActionSets); boolean added = addToAactionSet(act, parentAct, subActionSets);
@@ -192,15 +196,24 @@ public class HierarchicalRegrouper {
} }
for (Action act : actions) { for (Action act : actions) {
if (act.getNode().equals(parent)) { if (act.getNode().equals(parent)) {
if (act instanceof Move && !(action instanceof Move)) { if (areRelatedActions(act, action)) {
continue; return act;
} }
if (act instanceof Delete && !(action instanceof Delete)) {
continue;
}
return act;
} }
} }
return null; return null;
} }
private boolean areRelatedActions(Action parent, Action child) {
if (parent instanceof Move && !(child instanceof Move)) {// If action is MOV, its children must be MOV.
return false;
}
if (parent instanceof Delete && !(child instanceof Delete)) {// If action is INS, its children must be MOV or INS.
return false;
}
if (parent instanceof Insert && !(child instanceof Addition)) {// If action is DEL, its children must be DEL.
return false;
}
return true;
}
} }