Skip to content

Commit

Permalink
Fix building unnecessary AG problem
Browse files Browse the repository at this point in the history
  • Loading branch information
kimseokjin committed Mar 9, 2020
1 parent d7c39f6 commit f69fc39
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 121 deletions.
17 changes: 12 additions & 5 deletions src/main/java/hgu/csee/isel/alinew/szz/AGSZZ.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.eclipse.jgit.api.Git;
Expand Down Expand Up @@ -52,12 +54,16 @@ public void run() throws IOException {

System.out.println("Having repository: " + git.getRepository().getDirectory());


Repository repo = git.getRepository();

List<RevCommit> revs = GitUtils.getRevs(git);

RevsWithPath revsWithPath = GitUtils.collectRevsWithSpecificPath(GitUtils.configurePathRevisionList(repo, revs));


List<RevCommit> bfcList = GitUtils.getBFCList(BFCList, revs);

List<String> targetPaths = GitUtils.getTargetPaths(repo, bfcList);

RevsWithPath revsWithPath = GitUtils.collectRevsWithSpecificPath(GitUtils.configurePathRevisionList(repo, revs), targetPaths);

// Phase 1 : Build the annotation graph
final long startBuildingTime = System.currentTimeMillis();

Expand All @@ -71,7 +77,8 @@ public void run() throws IOException {
final long startTracingTime = System.currentTimeMillis();

Tracer tracer = new Tracer();
List<Line> BILines = tracer.collectBILines(repo, revs, agm, revsWithPath, BFCList, debug);
//List<Line> BILines = tracer.collectBILines(repo, revs, agm, revsWithPath, BFCList, debug);
List<Line> BILines = tracer.collectBILines(repo, bfcList, agm, revsWithPath, debug);

final long endTracingTime = System.currentTimeMillis();
System.out.println("\nCollecting BICs takes " + (endTracingTime - startTracingTime) / 1000.0 + "s\n");
Expand Down
205 changes: 102 additions & 103 deletions src/main/java/hgu/csee/isel/alinew/szz/trace/Tracer.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,124 +21,123 @@
public class Tracer {
private static final int REFACTOIRNG_THRESHOLD = 10;
private HashSet<Line> BILines = new HashSet<>();

public List<Line> collectBILines(Repository repo, List<RevCommit> revs, AnnotationGraphModel annotationGraph,
RevsWithPath revsWithPath, List<String> BFCList, boolean debug) throws IOException {
// Phase 1 : traverse all commits and find BFC
for (String bfc : BFCList) {
for (RevCommit childRev : revs) {
if (childRev.getName().equals(bfc)) {
// Phase 2 : Find path and line index for tracing
RevCommit parentRev = childRev.getParent(0); // Get BFC pre-commit (i.e. BFC~1 commit)
if (parentRev == null) {
System.err.println("ERROR: Parent commit does not exist: " + childRev.name());
break;
}

public List<Line> collectBILines(Repository repo, List<RevCommit> BFCList, AnnotationGraphModel annotationGraph,
RevsWithPath revsWithPath, boolean debug) throws IOException {
// Phase 1 : Find path and line index for tracing
for (RevCommit BFC : BFCList) {
if(BFC.getParentCount() == 0)
continue;

RevCommit parentRev = BFC.getParent(0); // Get BFC pre-commit (i.e. BFC~1 commit)
if (parentRev == null) {
System.err.println("ERROR: Parent commit does not exist: " + BFC.name());
break;
}

if (debug) {
System.out.println("\nParent Revision : " + parentRev.getName());
System.out.println("Child Revision (BFC) : " + BFC.getName());
}

List<DiffEntry> diffs = GitUtils.diff(repo, parentRev.getTree(), BFC.getTree());

/*
* HEURISTIC : If the number of changed path in BFC is greater than 10, that
* commit is highly likely to involve refactoring codes that can be noise for
* collecting BIC.
*/
if (REFACTOIRNG_THRESHOLD <= diffs.size())
continue;

for (DiffEntry diff : diffs) {
String path = diff.getNewPath();

// Ignore non-java file and test file
if (!path.endsWith(".java") || path.contains("test"))
continue;

if (debug) {
System.out.println("\nChanged Path : " + path);
System.out.println("Graph contains " + path + "? " + annotationGraph.containsKey(path) );

HashMap<RevCommit, ArrayList<Line>> subAG = annotationGraph.get(path);
System.out.println("Sub Graph contains " + BFC.getName() + "? " + subAG.containsKey(BFC));
}

// get list of lines of BFC
ArrayList<Line> linesToTrace = annotationGraph.get(path).get(BFC);

// get preFixSource and fixSource
String parentContent = Utils.removeComments(GitUtils.fetchBlob(repo, parentRev, path)).trim();
String childContent = Utils.removeComments(GitUtils.fetchBlob(repo, BFC, path)).trim();

// get line indices that fix bug
EditList editList = GitUtils.getEditListFromDiff(parentContent, childContent);
for (Edit edit : editList) {
int begin = -1;
int end = -1;

if (debug) {
System.out.println("\nParent Revision : " + parentRev.getName());
System.out.println("Child Revision (BFC) : " + childRev.getName());
System.out.println("\nHunk Info");
System.out.println("\tType : " + edit.getType());
System.out.println("\tbA : " + edit.getBeginA());
System.out.println("\teA : " + edit.getEndA());
System.out.println("\tbB : " + edit.getBeginB());
System.out.println("\teB : " + edit.getEndB());
}

List<DiffEntry> diffs = GitUtils.diff(repo, parentRev.getTree(), childRev.getTree());

/*
* HEURISTIC : If the number of changed path in BFC is greater than 10, that
* commit is highly likely to involve refactoring codes that can be noise for
* collecting BIC.
*/
if (REFACTOIRNG_THRESHOLD <= diffs.size())
continue;
switch (edit.getType()) {
case DELETE:
begin = edit.getBeginA();
end = edit.getEndA();

for (DiffEntry diff : diffs) {
String path = diff.getNewPath();

// Ignore test files
if(path.contains("test"))
continue;
/*
* Get a revision just before BFC among changed revisions with path
*
* [REMARK] This list is sorted in chronological order.
*
* Latest ------------> Oldest
* [][][][][][][][][][][][][][][]
*/
List<RevCommit> changeRevsWithPath = revsWithPath.get(path);
RevCommit changedPreBugFixRev = changeRevsWithPath.get(changeRevsWithPath.indexOf(BFC) + 1);

if (debug) {
System.out.println("\nChanged Path : " + path);
linesToTrace = annotationGraph.get(path).get(changedPreBugFixRev);

HashMap<RevCommit, ArrayList<Line>> subAG = annotationGraph.get(path);
System.out.println("Sub Graph contains " + childRev.getName() + "? " + subAG.containsKey(childRev));
}
break;

// get list of lines of BFC
ArrayList<Line> linesToTrace = annotationGraph.get(path).get(childRev);

// get preFixSource and fixSource
String parentContent = Utils.removeComments(GitUtils.fetchBlob(repo, parentRev, path)).trim();
String childContent = Utils.removeComments(GitUtils.fetchBlob(repo, childRev, path)).trim();

// get line indices that fix bug
EditList editList = GitUtils.getEditListFromDiff(parentContent, childContent);
for (Edit edit : editList) {
int begin = -1;
int end = -1;

if (debug) {
System.out.println("\nHunk Info");
System.out.println("\tType : " + edit.getType());
System.out.println("\tbA : " + edit.getBeginA());
System.out.println("\teA : " + edit.getEndA());
System.out.println("\tbB : " + edit.getBeginB());
System.out.println("\teB : " + edit.getEndB());
}
case REPLACE:
begin = edit.getBeginB();
end = edit.getEndB();
break;

switch (edit.getType()) {
case DELETE:
begin = edit.getBeginA();
end = edit.getEndA();

/*
* Get a revision just before BFC among changed revisions with path
*
* [REMARK] This list is sorted in chronological order.
*
* Latest ------------> Oldest
* [][][][][][][][][][][][][][][]
*/
List<RevCommit> changeRevsWithPath = revsWithPath.get(path);
RevCommit changedPreBugFixRev = changeRevsWithPath.get(changeRevsWithPath.indexOf(childRev) + 1);

linesToTrace = annotationGraph.get(path).get(changedPreBugFixRev);

break;

case REPLACE:
begin = edit.getBeginB();
end = edit.getEndB();
break;

default:
break;
}
default:
break;
}

if (debug) {
System.out.println("\nTraced Line Info : " + begin);
System.out.println("Begin : " + begin);
System.out.println("End : " + end);
if (debug) {
System.out.println("\nTraced Line Info : " + begin);
System.out.println("Begin : " + begin);
System.out.println("End : " + end);

System.out.println("\nSize of lines to trace : " + linesToTrace.size());
System.out.println("\nSize of lines to trace : " + linesToTrace.size());

for (Line line : linesToTrace) {
for (Line line : linesToTrace) {

int lindIdx = line.getIdx();
if (lindIdx >= begin && lindIdx < end) {
System.out.println("\nLine Idx : " + line.getIdx());
System.out.println("Content : " + line.getContent());
}
}
int lindIdx = line.getIdx();
if (lindIdx >= begin && lindIdx < end) {
System.out.println("\nLine Idx : " + line.getIdx());
System.out.println("Content : " + line.getContent());
}
}
}

// Phase 3 : trace
if (0 <= begin && 0 <= end) {
for (int i = begin; i < end; i++) {
Line line = linesToTrace.get(i);
trace(line);
}
}
// Phase 2 : trace
if (0 <= begin && 0 <= end) {
for (int i = begin; i < end; i++) {
Line line = linesToTrace.get(i);
trace(line);
}
}
}
Expand Down
64 changes: 54 additions & 10 deletions src/main/java/hgu/csee/isel/alinew/szz/util/GitUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ public static List<PathRevision> configurePathRevisionList(Repository repo, List

for (RevCommit commit : commits) {
// Skip when there are no parents
if(commit.getParentCount() == 0)
if (commit.getParentCount() == 0)
continue;

RevCommit parent = commit.getParent(0);
if (parent == null)
break;
Expand All @@ -80,7 +80,7 @@ public static List<PathRevision> configurePathRevisionList(Repository repo, List
for (DiffEntry diff : diffs) {
String path = diff.getNewPath();

// contains only files which are java files and not test files
// contains only files which are java files and not test files
if (path.endsWith(".java") && !path.contains("test")) {
paths.add(new PathRevision(path, commit));
}
Expand All @@ -90,22 +90,28 @@ public static List<PathRevision> configurePathRevisionList(Repository repo, List
return paths;
}

public static RevsWithPath collectRevsWithSpecificPath(List<PathRevision> pathRevisions) {
RevsWithPath revsInPath = new RevsWithPath();
public static RevsWithPath collectRevsWithSpecificPath(List<PathRevision> pathRevisions, List<String> targetPaths) {
RevsWithPath revsWithPath = new RevsWithPath();

for (PathRevision pr : pathRevisions) {
if (revsInPath.containsKey(pr.getPath())) {
List<RevCommit> lst = revsInPath.get(pr.getPath());
String path = pr.getPath();

// Skip when the path is not a target
if(!targetPaths.contains(path))
continue;

if (revsWithPath.containsKey(path)) {
List<RevCommit> lst = revsWithPath.get(path);
lst.add(pr.getCommit());
revsInPath.replace(pr.getPath(), lst);
revsWithPath.replace(path, lst);
} else {
List<RevCommit> lst = new ArrayList<>();
lst.add(pr.getCommit());
revsInPath.put(pr.getPath(), lst);
revsWithPath.put(path, lst);
}
}

return revsInPath;
return revsWithPath;
}

public static String fetchBlob(Repository repo, RevCommit commit, String path)
Expand Down Expand Up @@ -173,4 +179,42 @@ public static List<RevCommit> getRevs(Git git) throws NoHeadException, GitAPIExc
return commits;
}

public static List<RevCommit> getBFCList(List<String> BFCList, List<RevCommit> revs) {
List<RevCommit> bfcList = new ArrayList<>();

for (String bfc : BFCList) {
for (RevCommit rev : revs) {
if (rev.getName().equals(bfc)) {
bfcList.add(rev);
}
}
}

return bfcList;
}

public static List<String> getTargetPaths(Repository repo, List<RevCommit> BFCList) throws IOException{
List<String> targetPaths = new ArrayList<>();

for (RevCommit bfc : BFCList) {
// Skip when there are no parents
if (bfc.getParentCount() == 0)
continue;

RevCommit parent = bfc.getParent(0);
if (parent == null)
break;

List<DiffEntry> diffs = GitUtils.diff(repo, parent.getTree(), bfc.getTree());

// get changed paths
for (DiffEntry diff : diffs) {
String path = diff.getNewPath();

targetPaths.add(path);
}
}

return targetPaths;
}
}
6 changes: 3 additions & 3 deletions src/main/java/hgu/csee/isel/alinew/szz/util/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,12 @@ public static void storeOutputFile(String GIT_URL, List<Line> BICLines) throws I

FileWriter writer = new FileWriter(savedFile);

CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT.withHeader("Path", "BIC", "Content", "Line Idx", "Committer", "Commit Date(GMT)"));
CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT.withHeader("Path", "BIC", "Content", "Line Idx", "Committer", "Author", "Commit Date(GMT)"));

for (Line BICLine : BICLines) {
csvPrinter.printRecord(BICLine.getPath(), BICLine.getRev(), BICLine.getContent(), BICLine.getIdx(), BICLine.getCommiter(), BICLine.getCommitDate());
csvPrinter.printRecord(BICLine.getPath(), BICLine.getRev(), BICLine.getContent(), BICLine.getIdx(), BICLine.getCommiter(), BICLine.getAuthor(), BICLine.getCommitDate());
}

csvPrinter.flush();
csvPrinter.close();
}
}

0 comments on commit f69fc39

Please sign in to comment.