From cc340e8c3c3c9912dec7b0f977c2ed57ec30c749 Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Sat, 24 Sep 2022 17:50:28 +0200 Subject: [PATCH 1/9] Strip `DiffTree` from `DiffTreeLineGraphExport` names --- .../analysis/CommitHistoryAnalysisTask.java | 6 ++--- .../analysis/HistoryAnalysis.java | 4 +-- .../analysis/strategies/AnalysisMonitor.java | 4 +-- .../analysis/strategies/AnalysisStrategy.java | 6 ++--- .../strategies/AnalyzeAllThenExport.java | 4 +-- .../AnalyzeAndExportIncrementally.java | 4 +-- .../strategies/CompositeAnalysisStrategy.java | 4 +-- .../difftree/render/DiffTreeRenderer.java | 26 +++++++++---------- .../difftree/render/PatchDiffRenderer.java | 4 +-- .../diff/difftree/render/RenderOptions.java | 6 ++--- .../difftree/serialize/LineGraphExport.java | 24 ++++++++--------- ...tions.java => LineGraphExportOptions.java} | 8 +++--- ...phExporter.java => LineGraphExporter.java} | 6 ++--- .../difftree/serialize/LineGraphImport.java | 10 +++---- ...tions.java => LineGraphImportOptions.java} | 2 +- .../diffdetective/mining/DiffTreeMiner.java | 12 ++++----- .../diffdetective/mining/MiningTask.java | 4 +-- .../postprocessing/MiningPostprocessing.java | 4 +-- .../validation/EditClassValidationTask.java | 4 +-- .../diffdetective/validation/Validation.java | 12 ++++----- src/test/java/ExportTest.java | 4 +-- src/test/java/LineGraphTest.java | 4 +-- src/test/java/MarlinDebug.java | 2 +- src/test/java/TestMultiLineMacros.java | 6 ++--- 24 files changed, 85 insertions(+), 85 deletions(-) rename src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/{DiffTreeLineGraphExportOptions.java => LineGraphExportOptions.java} (88%) rename src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/{DiffTreeLineGraphExporter.java => LineGraphExporter.java} (91%) rename src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/{DiffTreeLineGraphImportOptions.java => LineGraphImportOptions.java} (95%) diff --git a/src/main/java/org/variantsync/diffdetective/analysis/CommitHistoryAnalysisTask.java b/src/main/java/org/variantsync/diffdetective/analysis/CommitHistoryAnalysisTask.java index 66d731886..700dff054 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/CommitHistoryAnalysisTask.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/CommitHistoryAnalysisTask.java @@ -5,7 +5,7 @@ import org.variantsync.diffdetective.analysis.strategies.AnalysisStrategy; import org.variantsync.diffdetective.datasets.Repository; import org.variantsync.diffdetective.diff.GitDiffer; -import org.variantsync.diffdetective.diff.difftree.serialize.DiffTreeLineGraphExportOptions; +import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import org.variantsync.diffdetective.util.CSV; import org.variantsync.diffdetective.util.IO; import org.variantsync.diffdetective.util.StringUtils; @@ -37,7 +37,7 @@ public record Options( Repository repository, GitDiffer differ, Path outputDir, - DiffTreeLineGraphExportOptions exportOptions, + LineGraphExportOptions exportOptions, AnalysisStrategy analysisStrategy, Iterable commits ) {} @@ -61,7 +61,7 @@ public AnalysisResult call() throws Exception { options.analysisStrategy().start(options.repository(), options.outputDir(), options.exportOptions()); final AnalysisResult miningResult = new AnalysisResult(options.repository.getRepositoryName()); - final DiffTreeLineGraphExportOptions exportOptions = options.exportOptions(); + final LineGraphExportOptions exportOptions = options.exportOptions(); miningResult.putCustomInfo(MetadataKeys.TREEFORMAT, exportOptions.treeFormat().getName()); miningResult.putCustomInfo(MetadataKeys.NODEFORMAT, exportOptions.nodeFormat().getName()); diff --git a/src/main/java/org/variantsync/diffdetective/analysis/HistoryAnalysis.java b/src/main/java/org/variantsync/diffdetective/analysis/HistoryAnalysis.java index 3d44e79c3..518dca04a 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/HistoryAnalysis.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/HistoryAnalysis.java @@ -6,7 +6,7 @@ import org.variantsync.diffdetective.analysis.strategies.AnalysisStrategy; import org.variantsync.diffdetective.datasets.Repository; import org.variantsync.diffdetective.diff.GitDiffer; -import org.variantsync.diffdetective.diff.difftree.serialize.DiffTreeLineGraphExportOptions; +import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import org.variantsync.diffdetective.metadata.Metadata; import org.variantsync.diffdetective.mining.MiningTask; import org.variantsync.diffdetective.parallel.ScheduledTasksIterator; @@ -56,7 +56,7 @@ public record HistoryAnalysis( public static void analyze( final Repository repo, final Path outputDir, - final DiffTreeLineGraphExportOptions exportOptions, + final LineGraphExportOptions exportOptions, final AnalysisStrategy strategy) { AnalysisResult totalResult; diff --git a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisMonitor.java b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisMonitor.java index eb48d3763..98556e9b8 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisMonitor.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisMonitor.java @@ -3,7 +3,7 @@ import org.variantsync.diffdetective.analysis.monitoring.TaskCompletionMonitor; import org.variantsync.diffdetective.datasets.Repository; import org.variantsync.diffdetective.diff.CommitDiff; -import org.variantsync.diffdetective.diff.difftree.serialize.DiffTreeLineGraphExportOptions; +import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import java.nio.file.Path; @@ -24,7 +24,7 @@ public AnalysisMonitor(int seconds) { } @Override - public void start(Repository repo, Path outputPath, DiffTreeLineGraphExportOptions options) { + public void start(Repository repo, Path outputPath, LineGraphExportOptions options) { super.start(repo, outputPath, options); monitor.start(); } diff --git a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisStrategy.java b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisStrategy.java index eaf854143..83ac02e8b 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisStrategy.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisStrategy.java @@ -2,7 +2,7 @@ import org.variantsync.diffdetective.datasets.Repository; import org.variantsync.diffdetective.diff.CommitDiff; -import org.variantsync.diffdetective.diff.difftree.serialize.DiffTreeLineGraphExportOptions; +import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import java.nio.file.Path; @@ -15,7 +15,7 @@ public abstract class AnalysisStrategy { protected Repository repo; protected Path outputPath; - protected DiffTreeLineGraphExportOptions exportOptions; + protected LineGraphExportOptions exportOptions; /** * Invoked when the analysis starts. @@ -24,7 +24,7 @@ public abstract class AnalysisStrategy { * @param outputPath A directory to which output should be written. * @param options Options for data export. */ - public void start(Repository repo, Path outputPath, DiffTreeLineGraphExportOptions options) { + public void start(Repository repo, Path outputPath, LineGraphExportOptions options) { this.repo = repo; this.outputPath = outputPath; this.exportOptions = options; diff --git a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAllThenExport.java b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAllThenExport.java index 7b222f0ce..61427c46d 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAllThenExport.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAllThenExport.java @@ -2,7 +2,7 @@ import org.variantsync.diffdetective.datasets.Repository; import org.variantsync.diffdetective.diff.CommitDiff; -import org.variantsync.diffdetective.diff.difftree.serialize.DiffTreeLineGraphExportOptions; +import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import org.variantsync.diffdetective.util.IO; import java.nio.file.Path; @@ -15,7 +15,7 @@ public class AnalyzeAllThenExport extends AnalysisStrategy { private StringBuilder waitForAll; @Override - public void start(Repository repo, Path outputPath, DiffTreeLineGraphExportOptions options) { + public void start(Repository repo, Path outputPath, LineGraphExportOptions options) { super.start(repo, outputPath, options); waitForAll = new StringBuilder(); } diff --git a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAndExportIncrementally.java b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAndExportIncrementally.java index 1f70a49c2..4a3a6202c 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAndExportIncrementally.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAndExportIncrementally.java @@ -3,7 +3,7 @@ import org.tinylog.Logger; import org.variantsync.diffdetective.datasets.Repository; import org.variantsync.diffdetective.diff.CommitDiff; -import org.variantsync.diffdetective.diff.difftree.serialize.DiffTreeLineGraphExportOptions; +import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import org.variantsync.diffdetective.util.IO; import java.io.IOException; @@ -44,7 +44,7 @@ public AnalyzeAndExportIncrementally() { } @Override - public void start(Repository repo, Path outputPath, DiffTreeLineGraphExportOptions options) { + public void start(Repository repo, Path outputPath, LineGraphExportOptions options) { super.start(repo, outputPath, options); IO.tryDeleteFile(outputPath); diff --git a/src/main/java/org/variantsync/diffdetective/analysis/strategies/CompositeAnalysisStrategy.java b/src/main/java/org/variantsync/diffdetective/analysis/strategies/CompositeAnalysisStrategy.java index 482336135..dddbb5a17 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/strategies/CompositeAnalysisStrategy.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/strategies/CompositeAnalysisStrategy.java @@ -2,7 +2,7 @@ import org.variantsync.diffdetective.datasets.Repository; import org.variantsync.diffdetective.diff.CommitDiff; -import org.variantsync.diffdetective.diff.difftree.serialize.DiffTreeLineGraphExportOptions; +import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import java.nio.file.Path; import java.util.Arrays; @@ -26,7 +26,7 @@ public CompositeAnalysisStrategy(final AnalysisStrategy... strategies) { } @Override - public void start(Repository repo, Path outputPath, DiffTreeLineGraphExportOptions options) { + public void start(Repository repo, Path outputPath, LineGraphExportOptions options) { super.start(repo, outputPath, options); for (final AnalysisStrategy s : strategies) { s.start(repo, outputPath, options); diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/render/DiffTreeRenderer.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/render/DiffTreeRenderer.java index 80c455d59..4592c3880 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/render/DiffTreeRenderer.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/render/DiffTreeRenderer.java @@ -6,7 +6,7 @@ import org.variantsync.diffdetective.diff.difftree.DiffTree; import org.variantsync.diffdetective.diff.difftree.DiffTreeSource; import org.variantsync.diffdetective.diff.difftree.LineGraphConstants; -import org.variantsync.diffdetective.diff.difftree.serialize.DiffTreeLineGraphExportOptions; +import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import org.variantsync.diffdetective.diff.difftree.serialize.DiffTreeSerializeDebugData; import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExport; import org.variantsync.diffdetective.shell.PythonCommand; @@ -103,27 +103,27 @@ public boolean render(PatchDiff patchDiff, final Path directory, final RenderOpt } /** - * Invokes {@link DiffTreeRenderer#render(DiffTree, GitPatch, Path, RenderOptions, DiffTreeLineGraphExportOptions)} + * Invokes {@link DiffTreeRenderer#render(DiffTree, GitPatch, Path, RenderOptions, LineGraphExportOptions)} * by extracting the given patchDiff's DiffTree. */ - public boolean render(PatchDiff patchDiff, final Path directory, final RenderOptions options, final DiffTreeLineGraphExportOptions exportOptions) { + public boolean render(PatchDiff patchDiff, final Path directory, final RenderOptions options, final LineGraphExportOptions exportOptions) { return render(patchDiff.getDiffTree(), patchDiff, directory, options, exportOptions); } /** - * Invokes {@link DiffTreeRenderer#render(DiffTree, GitPatch, Path, RenderOptions, DiffTreeLineGraphExportOptions)} - * by creating {@link DiffTreeLineGraphExportOptions} via {@link RenderOptions#toLineGraphOptions()}. + * Invokes {@link DiffTreeRenderer#render(DiffTree, GitPatch, Path, RenderOptions, LineGraphExportOptions)} + * by creating {@link LineGraphExportOptions} via {@link RenderOptions#toLineGraphOptions()}. */ public boolean render(final DiffTree tree, final GitPatch patch, final Path directory, final RenderOptions options) { return render(tree, patch, directory, options, options.toLineGraphOptions()); } /** - * Invokes {@link DiffTreeRenderer#render(DiffTree, String, Path, RenderOptions, DiffTreeLineGraphExportOptions)} + * Invokes {@link DiffTreeRenderer#render(DiffTree, String, Path, RenderOptions, LineGraphExportOptions)} * by creating a name for the tree and its produced image file. * The created treeAndFileName is the given patches file name and commit hash, separated by {@link LineGraphConstants#TREE_NAME_SEPARATOR}. */ - public boolean render(final DiffTree tree, final GitPatch patch, final Path directory, final RenderOptions options, final DiffTreeLineGraphExportOptions exportOptions) { + public boolean render(final DiffTree tree, final GitPatch patch, final Path directory, final RenderOptions options, final LineGraphExportOptions exportOptions) { final String treeAndFileName = patch.getFileName() + LineGraphConstants.TREE_NAME_SEPARATOR @@ -140,29 +140,29 @@ public boolean render(final DiffTree tree, final String treeAndFileName, final P } /** - * Invokes {@link DiffTreeRenderer#render(DiffTree, String, Path, RenderOptions, DiffTreeLineGraphExportOptions)} - * by creating {@link DiffTreeLineGraphExportOptions} via {@link RenderOptions#toLineGraphOptions()}. + * Invokes {@link DiffTreeRenderer#render(DiffTree, String, Path, RenderOptions, LineGraphExportOptions)} + * by creating {@link LineGraphExportOptions} via {@link RenderOptions#toLineGraphOptions()}. */ public boolean render(final DiffTree tree, final String treeAndFileName, final Path directory, RenderOptions options) { return render(tree, treeAndFileName, directory, options, options.toLineGraphOptions()); } /** - * Invokes {@link DiffTreeRenderer#render(DiffTree, String, Path, RenderOptions, DiffTreeLineGraphExportOptions, BiFunction)} + * Invokes {@link DiffTreeRenderer#render(DiffTree, String, Path, RenderOptions, LineGraphExportOptions, BiFunction)} * with the a default tree header factory. * The tree header factory uses the given treeAndFileName to create * LineGraphConstants.LG_TREE_HEADER + " " + treeAndFileName + LineGraphConstants.TREE_NAME_SEPARATOR + "0". * @see LineGraphConstants#LG_TREE_HEADER * @see LineGraphConstants#TREE_NAME_SEPARATOR */ - public boolean render(final DiffTree tree, final String treeAndFileName, final Path directory, RenderOptions options, final DiffTreeLineGraphExportOptions exportOptions) { + public boolean render(final DiffTree tree, final String treeAndFileName, final Path directory, RenderOptions options, final LineGraphExportOptions exportOptions) { return render(tree, treeAndFileName, directory, options, exportOptions, (treeName, treeSource) -> LineGraphConstants.LG_TREE_HEADER + " " + treeAndFileName + LineGraphConstants.TREE_NAME_SEPARATOR + "0" ); } /** - * Invokes {@link DiffTreeRenderer#render(DiffTree, String, Path, RenderOptions, DiffTreeLineGraphExportOptions, BiFunction)} + * Invokes {@link DiffTreeRenderer#render(DiffTree, String, Path, RenderOptions, LineGraphExportOptions, BiFunction)} * with the a default tree header factory. * The tree header factory uses the given treeAndFileName to create * LineGraphConstants.LG_TREE_HEADER + " " + treeAndFileName + LineGraphConstants.TREE_NAME_SEPARATOR + "0". @@ -191,7 +191,7 @@ public boolean renderWithTreeFormat(final DiffTree tree, final String treeAndFil * The function is invoked on the given treeAndFileName as first argument and the given DiffTree's source as second argument. * @return True iff rendering was successful. False iff an error occurred. */ - private boolean render(final DiffTree tree, final String treeAndFileName, final Path directory, RenderOptions options, DiffTreeLineGraphExportOptions exportOptions, BiFunction treeHeader) { + private boolean render(final DiffTree tree, final String treeAndFileName, final Path directory, RenderOptions options, LineGraphExportOptions exportOptions, BiFunction treeHeader) { final Path tempFile = directory.resolve(treeAndFileName + ".lg"); final Pair result = LineGraphExport.toLineGraphFormat(tree, exportOptions); diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/render/PatchDiffRenderer.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/render/PatchDiffRenderer.java index 2864d6f5e..20eeb61b0 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/render/PatchDiffRenderer.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/render/PatchDiffRenderer.java @@ -5,7 +5,7 @@ import org.variantsync.diffdetective.diff.PatchDiff; import org.variantsync.diffdetective.diff.difftree.DiffTree; import org.variantsync.diffdetective.diff.difftree.LineGraphConstants; -import org.variantsync.diffdetective.diff.difftree.serialize.DiffTreeLineGraphExportOptions; +import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import org.variantsync.diffdetective.diff.difftree.serialize.nodeformat.TypeDiffNodeFormat; import org.variantsync.diffdetective.util.IO; @@ -64,7 +64,7 @@ public static PatchDiffRenderer ErrorRendering(final DiffTreeRenderer renderer) * Renders the given patch to the given output directory. * @param patch The patch to render. * @param outputDirectory The directory to which the rendered image should be written. - * @see DiffTreeRenderer#render(DiffTree, String, Path, RenderOptions, DiffTreeLineGraphExportOptions, BiFunction) + * @see DiffTreeRenderer#render(DiffTree, String, Path, RenderOptions, LineGraphExportOptions, BiFunction) */ public void render(final PatchDiff patch, final Path outputDirectory) { render(patch.getDiffTree(), patch, outputDirectory); diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/render/RenderOptions.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/render/RenderOptions.java index 36fdd3e50..a5eb5c56a 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/render/RenderOptions.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/render/RenderOptions.java @@ -1,6 +1,6 @@ package org.variantsync.diffdetective.diff.difftree.render; -import org.variantsync.diffdetective.diff.difftree.serialize.DiffTreeLineGraphExportOptions; +import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import org.variantsync.diffdetective.diff.difftree.serialize.GraphFormat; import org.variantsync.diffdetective.diff.difftree.serialize.edgeformat.DefaultEdgeLabelFormat; import org.variantsync.diffdetective.diff.difftree.serialize.edgeformat.EdgeLabelFormat; @@ -221,7 +221,7 @@ public Builder addExtraArguments(String... args) { * Linegraph options are a subset of render options. * @return Options for linegraph export consistent to this RenderOptions. */ - public DiffTreeLineGraphExportOptions toLineGraphOptions() { - return new DiffTreeLineGraphExportOptions(format(), treeFormat(), nodeFormat(), edgeFormat()); + public LineGraphExportOptions toLineGraphOptions() { + return new LineGraphExportOptions(format(), treeFormat(), nodeFormat(), edgeFormat()); } } \ No newline at end of file diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java index 1abb8c01d..de89f2afc 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java @@ -26,12 +26,12 @@ private LineGraphExport() {} * @param options Configuration options for the export, such as the format used for node and edge labels. * @return A pair holding some debug information and the produced linegraph as a string. */ - public static Pair toLineGraphFormat(final DiffTree diffTree, final DiffTreeLineGraphExportOptions options) { + public static Pair toLineGraphFormat(final DiffTree diffTree, final LineGraphExportOptions options) { DiffTreeTransformer.apply(options.treePreProcessing(), diffTree); diffTree.assertConsistency(); if (options.treeFilter().test(diffTree)) { - final var exporter = new DiffTreeLineGraphExporter(options); + final var exporter = new LineGraphExporter(options); var output = new ByteArrayOutputStream(); exporter.exportDiffTree(diffTree, output); return new Pair<>(exporter.getDebugData(), output.toString()); @@ -47,7 +47,7 @@ public static Pair toLineGraphFormat(final D * @param options Configuration options for the export, such as the format used for node and edge labels. * @return A pair of (1) metadata about the exported DiffTrees, and (2) the produced linegraph as String. */ - public static Pair toLineGraphFormat(final String repoName, final Iterable trees, final DiffTreeLineGraphExportOptions options) { + public static Pair toLineGraphFormat(final String repoName, final Iterable trees, final LineGraphExportOptions options) { final AnalysisResult result = new AnalysisResult(repoName); final StringBuilder lineGraph = new StringBuilder(); @@ -68,18 +68,18 @@ public static Pair toLineGraphFormat(final String repoNa } /** - * Same as {@link LineGraphExport#toLineGraphFormat(String, Iterable, DiffTreeLineGraphExportOptions)} but with an + * Same as {@link LineGraphExport#toLineGraphFormat(String, Iterable, LineGraphExportOptions)} but with an * {@link AnalysisResult#NO_REPO unkown repository}. */ - public static Pair toLineGraphFormat(final Iterable trees, final DiffTreeLineGraphExportOptions options) { + public static Pair toLineGraphFormat(final Iterable trees, final LineGraphExportOptions options) { return toLineGraphFormat(AnalysisResult.NO_REPO, trees, options); } /** - * Same as {@link LineGraphExport#toLineGraphFormat(String, CommitDiff, StringBuilder, DiffTreeLineGraphExportOptions)} + * Same as {@link LineGraphExport#toLineGraphFormat(String, CommitDiff, StringBuilder, LineGraphExportOptions)} * but with an {@link AnalysisResult#NO_REPO unkown repository}. */ - public static AnalysisResult toLineGraphFormat(final CommitDiff commitDiff, final StringBuilder lineGraph, final DiffTreeLineGraphExportOptions options) { + public static AnalysisResult toLineGraphFormat(final CommitDiff commitDiff, final StringBuilder lineGraph, final LineGraphExportOptions options) { return toLineGraphFormat(AnalysisResult.NO_REPO, commitDiff, lineGraph, options); } @@ -91,7 +91,7 @@ public static AnalysisResult toLineGraphFormat(final CommitDiff commitDiff, fina * @param options Configuration options for the export, such as the format used for node and edge labels. * @return The number of the next diff tree to export (updated value of treeCounter). */ - public static AnalysisResult toLineGraphFormat(final String repoName, final CommitDiff commitDiff, final StringBuilder lineGraph, final DiffTreeLineGraphExportOptions options) { + public static AnalysisResult toLineGraphFormat(final String repoName, final CommitDiff commitDiff, final StringBuilder lineGraph, final LineGraphExportOptions options) { final AnalysisResult result = new AnalysisResult(repoName); final String hash = commitDiff.getCommitHash(); @@ -124,14 +124,14 @@ public static AnalysisResult toLineGraphFormat(final String repoName, final Comm /** * Produces the final linegraph file content. - * Creates a linegraph header from the given DiffTreeSource using the {@link DiffTreeLineGraphExportOptions#treeFormat} in the given options. + * Creates a linegraph header from the given DiffTreeSource using the {@link LineGraphExportOptions#treeFormat} in the given options. * Then appends the already created file content for nodes and edges. * @param lineGraph The string builder to write the result to. * @param source The {@link DiffTreeSource} that describes where the DiffTree whose content is written to the file originated from. - * @param nodesAndEdges Result from {@link #toLineGraphFormat(DiffTree, DiffTreeLineGraphExportOptions)}. Holds all nodes and edges in linegraph format, separated by a newline each. - * @param options {@link DiffTreeLineGraphExportOptions} used to determine the treeFormat for the header. + * @param nodesAndEdges Result from {@link #toLineGraphFormat(DiffTree, LineGraphExportOptions)}. Holds all nodes and edges in linegraph format, separated by a newline each. + * @param options {@link LineGraphExportOptions} used to determine the treeFormat for the header. */ - public static void composeTreeInLineGraph(final StringBuilder lineGraph, final DiffTreeSource source, final String nodesAndEdges, final DiffTreeLineGraphExportOptions options) { + public static void composeTreeInLineGraph(final StringBuilder lineGraph, final DiffTreeSource source, final String nodesAndEdges, final LineGraphExportOptions options) { lineGraph .append(options.treeFormat().toLineGraphLine(source)) // print "t # $LABEL" .append(StringUtils.LINEBREAK) diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/DiffTreeLineGraphExportOptions.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExportOptions.java similarity index 88% rename from src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/DiffTreeLineGraphExportOptions.java rename to src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExportOptions.java index 1a1f519c1..57f3474bd 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/DiffTreeLineGraphExportOptions.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExportOptions.java @@ -29,7 +29,7 @@ * @param onError Callback that is invoked when an error occurs. * @author Paul Bittner */ -public record DiffTreeLineGraphExportOptions( +public record LineGraphExportOptions( GraphFormat graphFormat, DiffTreeLabelFormat treeFormat, DiffNodeLabelFormat nodeFormat, @@ -41,17 +41,17 @@ public record DiffTreeLineGraphExportOptions( /** * Creates a export options with a neutral filter (that accepts all trees), no transformers, and that logs errors. */ - public DiffTreeLineGraphExportOptions(GraphFormat graphFormat, DiffTreeLabelFormat treeFormat, DiffNodeLabelFormat nodeFormat, EdgeLabelFormat edgeFormat) { + public LineGraphExportOptions(GraphFormat graphFormat, DiffTreeLabelFormat treeFormat, DiffNodeLabelFormat nodeFormat, EdgeLabelFormat edgeFormat) { this(graphFormat, treeFormat, nodeFormat, edgeFormat, ExplainedFilter.Any(), new ArrayList<>(), LogError()); } /** * Create export options from the given import options. - * Invokes {@link DiffTreeLineGraphExportOptions#DiffTreeLineGraphExportOptions(GraphFormat, DiffTreeLabelFormat, DiffNodeLabelFormat, EdgeLabelFormat)} + * Invokes {@link LineGraphExportOptions#LineGraphExportOptions(GraphFormat, DiffTreeLabelFormat, DiffNodeLabelFormat, EdgeLabelFormat)} * with all formats from the given import options. * @param importOptions The import options to convert to export options. */ - public DiffTreeLineGraphExportOptions(final DiffTreeLineGraphImportOptions importOptions) { + public LineGraphExportOptions(final LineGraphImportOptions importOptions) { this( importOptions.graphFormat(), importOptions.treeFormat(), diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/DiffTreeLineGraphExporter.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExporter.java similarity index 91% rename from src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/DiffTreeLineGraphExporter.java rename to src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExporter.java index 411659a9f..073ee5461 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/DiffTreeLineGraphExporter.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExporter.java @@ -10,16 +10,16 @@ /** * Exporter that converts a single DiffTree's nodes and edges to linegraph. */ -public class DiffTreeLineGraphExporter implements Exporter { +public class LineGraphExporter implements Exporter { private final Format format; private final DiffTreeSerializeDebugData debugData; - public DiffTreeLineGraphExporter(Format format) { + public LineGraphExporter(Format format) { this.format = format; this.debugData = new DiffTreeSerializeDebugData(); } - public DiffTreeLineGraphExporter(DiffTreeLineGraphExportOptions options) { + public LineGraphExporter(LineGraphExportOptions options) { this(new Format(options.nodeFormat(), options.edgeFormat())); } diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphImport.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphImport.java index 4e9cf7656..222f60ab0 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphImport.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphImport.java @@ -27,9 +27,9 @@ public class LineGraphImport { * @param path Path to a linegraph file in which only DiffTrees are stored. * @param options Options for the import, such as hints for the used formats for node and edge labels. * @return All {@link DiffTree DiffTrees} contained in the linegraph file. - * @throws IOException when {@link LineGraphImport#fromLineGraph(BufferedReader, Path, DiffTreeLineGraphImportOptions)} throws. + * @throws IOException when {@link LineGraphImport#fromLineGraph(BufferedReader, Path, LineGraphImportOptions)} throws. */ - public static List fromFile(final Path path, final DiffTreeLineGraphImportOptions options) throws IOException { + public static List fromFile(final Path path, final LineGraphImportOptions options) throws IOException { Assert.assertTrue(Files.isRegularFile(path)); Assert.assertTrue(FileUtils.isLineGraph(path)); try (BufferedReader input = Files.newBufferedReader(path)) { @@ -45,7 +45,7 @@ public static List fromFile(final Path path, final DiffTreeLineGraphIm * @param options Options for the import, such as hints for the used formats for node and edge labels. * @return All {@link DiffTree DiffTrees} contained in the linegraph text. */ - public static List fromLineGraph(final BufferedReader lineGraph, final Path originalFile, final DiffTreeLineGraphImportOptions options) throws IOException { + public static List fromLineGraph(final BufferedReader lineGraph, final Path originalFile, final LineGraphImportOptions options) throws IOException { // All DiffTrees read from the line graph List diffTreeList = new ArrayList<>(); @@ -114,10 +114,10 @@ public static List fromLineGraph(final BufferedReader lineGraph, final * @param lineGraph The header line in the linegraph that describes the DiffTree (starting with t #). * @param inFile Path to the linegraph file that is currently parsed. * @param diffNodeList All nodes of the DiffTree that is to be created. The nodes can be assumed to be complete and already connected. - * @param options {@link DiffTreeLineGraphImportOptions} + * @param options {@link LineGraphImportOptions} * @return {@link DiffTree} generated from the given, already parsed parameters. */ - private static DiffTree parseDiffTree(final String lineGraph, final Path inFile, final List diffNodeList, final DiffTreeLineGraphImportOptions options) { + private static DiffTree parseDiffTree(final String lineGraph, final Path inFile, final List diffNodeList, final LineGraphImportOptions options) { DiffTreeSource diffTreeSource = options.treeFormat().fromLineGraphLine(lineGraph); if (diffTreeSource == null || DiffTreeSource.Unknown.equals(diffTreeSource)) { diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/DiffTreeLineGraphImportOptions.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphImportOptions.java similarity index 95% rename from src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/DiffTreeLineGraphImportOptions.java rename to src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphImportOptions.java index 44c3726a8..f17692145 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/DiffTreeLineGraphImportOptions.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphImportOptions.java @@ -13,7 +13,7 @@ * @param nodeFormat {@link DiffNodeLabelFormat} * @param edgeFormat {@link EdgeLabelFormat} */ -public record DiffTreeLineGraphImportOptions( +public record LineGraphImportOptions( GraphFormat graphFormat, DiffTreeLabelFormat treeFormat, DiffNodeLabelFormat nodeFormat, diff --git a/src/main/java/org/variantsync/diffdetective/mining/DiffTreeMiner.java b/src/main/java/org/variantsync/diffdetective/mining/DiffTreeMiner.java index eea3a1541..83240bdfd 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/DiffTreeMiner.java +++ b/src/main/java/org/variantsync/diffdetective/mining/DiffTreeMiner.java @@ -12,7 +12,7 @@ import org.variantsync.diffdetective.diff.difftree.filter.DiffTreeFilter; import org.variantsync.diffdetective.diff.difftree.filter.ExplainedFilter; import org.variantsync.diffdetective.diff.difftree.parse.DiffNodeParser; -import org.variantsync.diffdetective.diff.difftree.serialize.DiffTreeLineGraphExportOptions; +import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import org.variantsync.diffdetective.diff.difftree.serialize.GraphFormat; import org.variantsync.diffdetective.diff.difftree.serialize.edgeformat.EdgeLabelFormat; import org.variantsync.diffdetective.diff.difftree.serialize.treeformat.CommitDiffDiffTreeLabelFormat; @@ -72,9 +72,9 @@ private static EdgeLabelFormat EdgeFormat(final MiningNodeFormat nodeFormat) { new DirectedEdgeLabelFormat(nodeFormat, false, direction); } - public static DiffTreeLineGraphExportOptions MiningExportOptions(final Repository repository) { + public static LineGraphExportOptions MiningExportOptions(final Repository repository) { final MiningNodeFormat nodeFormat = NodeFormat(); - return new DiffTreeLineGraphExportOptions( + return new LineGraphExportOptions( GraphFormat.DIFFTREE // We have to ensure that all DiffTrees have unique IDs, so use name of changed file and commit hash. , new CommitDiffDiffTreeLabelFormat() @@ -91,9 +91,9 @@ public static DiffTreeLineGraphExportOptions MiningExportOptions(final Repositor DiffTreeFilter.hasAtLeastOneEditToVariability() ) , Postprocessing(repository) - , DiffTreeLineGraphExportOptions.LogError() - .andThen(DiffTreeLineGraphExportOptions.RenderError()) - .andThen(DiffTreeLineGraphExportOptions.SysExitOnError()) + , LineGraphExportOptions.LogError() + .andThen(LineGraphExportOptions.RenderError()) + .andThen(LineGraphExportOptions.SysExitOnError()) ); } diff --git a/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java b/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java index d20f18267..f882faea7 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java +++ b/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java @@ -6,7 +6,7 @@ import org.variantsync.diffdetective.diff.CommitDiff; import org.variantsync.diffdetective.diff.PatchDiff; import org.variantsync.diffdetective.diff.difftree.DiffTree; -import org.variantsync.diffdetective.diff.difftree.serialize.DiffTreeLineGraphExportOptions; +import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExport; import org.variantsync.diffdetective.diff.difftree.transform.DiffTreeTransformer; import org.variantsync.diffdetective.diff.result.CommitDiffResult; @@ -27,7 +27,7 @@ public MiningTask(final Options options) { @Override public AnalysisResult call() throws Exception { final AnalysisResult miningResult = super.call(); - final DiffTreeLineGraphExportOptions exportOptions = options.exportOptions(); + final LineGraphExportOptions exportOptions = options.exportOptions(); final Clock totalTime = new Clock(); diff --git a/src/main/java/org/variantsync/diffdetective/mining/postprocessing/MiningPostprocessing.java b/src/main/java/org/variantsync/diffdetective/mining/postprocessing/MiningPostprocessing.java index 7549f240c..1ad3c512e 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/postprocessing/MiningPostprocessing.java +++ b/src/main/java/org/variantsync/diffdetective/mining/postprocessing/MiningPostprocessing.java @@ -26,13 +26,13 @@ public class MiningPostprocessing { private static final DiffTreeRenderer DefaultRenderer = DiffTreeRenderer.WithinDiffDetective(); private static final boolean RENDER_CANDIDATES = false; - private static final DiffTreeLineGraphImportOptions IMPORT_OPTIONS = new DiffTreeLineGraphImportOptions( + private static final LineGraphImportOptions IMPORT_OPTIONS = new LineGraphImportOptions( GraphFormat.DIFFGRAPH, new IndexedTreeFormat(), DiffTreeMiner.NodeFormat(), DiffTreeMiner.EdgeFormat() ); - private static final DiffTreeLineGraphExportOptions EXPORT_OPTIONS = new DiffTreeLineGraphExportOptions( + private static final LineGraphExportOptions EXPORT_OPTIONS = new LineGraphExportOptions( GraphFormat.DIFFTREE, IMPORT_OPTIONS.treeFormat(), DiffTreeMiner.NodeFormat(), diff --git a/src/main/java/org/variantsync/diffdetective/validation/EditClassValidationTask.java b/src/main/java/org/variantsync/diffdetective/validation/EditClassValidationTask.java index 38ce99370..4e71a46d5 100644 --- a/src/main/java/org/variantsync/diffdetective/validation/EditClassValidationTask.java +++ b/src/main/java/org/variantsync/diffdetective/validation/EditClassValidationTask.java @@ -9,7 +9,7 @@ import org.variantsync.diffdetective.diff.CommitDiff; import org.variantsync.diffdetective.diff.PatchDiff; import org.variantsync.diffdetective.diff.difftree.DiffTree; -import org.variantsync.diffdetective.diff.difftree.serialize.DiffTreeLineGraphExportOptions; +import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import org.variantsync.diffdetective.diff.difftree.transform.DiffTreeTransformer; import org.variantsync.diffdetective.diff.result.CommitDiffResult; import org.variantsync.diffdetective.metadata.ExplainedFilterSummary; @@ -33,7 +33,7 @@ public EditClassValidationTask(Options options) { public AnalysisResult call() throws Exception { // Setup. Obtain the result from the initial setup in the super class. final AnalysisResult miningResult = super.call(); - final DiffTreeLineGraphExportOptions exportOptions = options.exportOptions(); + final LineGraphExportOptions exportOptions = options.exportOptions(); // List to store the process time of each commit. final List commitTimes = new ArrayList<>(HistoryAnalysis.COMMITS_TO_PROCESS_PER_THREAD_DEFAULT); // Clock for runtime measurement. diff --git a/src/main/java/org/variantsync/diffdetective/validation/Validation.java b/src/main/java/org/variantsync/diffdetective/validation/Validation.java index 431ac5aa4..2f5cf2144 100644 --- a/src/main/java/org/variantsync/diffdetective/validation/Validation.java +++ b/src/main/java/org/variantsync/diffdetective/validation/Validation.java @@ -10,7 +10,7 @@ import org.variantsync.diffdetective.datasets.*; import org.variantsync.diffdetective.diff.difftree.filter.DiffTreeFilter; import org.variantsync.diffdetective.diff.difftree.filter.ExplainedFilter; -import org.variantsync.diffdetective.diff.difftree.serialize.DiffTreeLineGraphExportOptions; +import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import org.variantsync.diffdetective.diff.difftree.serialize.GraphFormat; import org.variantsync.diffdetective.diff.difftree.serialize.edgeformat.EdgeLabelFormat; import org.variantsync.diffdetective.diff.difftree.serialize.treeformat.CommitDiffDiffTreeLabelFormat; @@ -79,9 +79,9 @@ private static EdgeLabelFormat EdgeFormat(final MiningNodeFormat nodeFormat) { /** * Creates new export options for running the validation on the given repository. */ - public static DiffTreeLineGraphExportOptions ValidationExportOptions(final Repository repository) { + public static LineGraphExportOptions ValidationExportOptions(final Repository repository) { final MiningNodeFormat nodeFormat = NodeFormat(); - return new DiffTreeLineGraphExportOptions( + return new LineGraphExportOptions( GraphFormat.DIFFTREE // We have to ensure that all DiffTrees have unique IDs, so use name of changed file and commit hash. , new CommitDiffDiffTreeLabelFormat() @@ -89,9 +89,9 @@ public static DiffTreeLineGraphExportOptions ValidationExportOptions(final Repos , EdgeFormat(nodeFormat) , new ExplainedFilter<>(DiffTreeFilter.notEmpty()) , List.of(new CutNonEditedSubtrees()) - , DiffTreeLineGraphExportOptions.LogError() - .andThen(DiffTreeLineGraphExportOptions.RenderError()) - .andThen(DiffTreeLineGraphExportOptions.SysExitOnError()) + , LineGraphExportOptions.LogError() + .andThen(LineGraphExportOptions.RenderError()) + .andThen(LineGraphExportOptions.SysExitOnError()) ); } diff --git a/src/test/java/ExportTest.java b/src/test/java/ExportTest.java index 20fbebd96..75f4f916b 100644 --- a/src/test/java/ExportTest.java +++ b/src/test/java/ExportTest.java @@ -27,8 +27,8 @@ public class ExportTest { /** * Format used to deserialize the test case. */ - private final static DiffTreeLineGraphImportOptions importOptions = - new DiffTreeLineGraphImportOptions( + private final static LineGraphImportOptions importOptions = + new LineGraphImportOptions( GraphFormat.DIFFTREE, new CommitDiffDiffTreeLabelFormat(), new LabelOnlyDiffNodeFormat(), diff --git a/src/test/java/LineGraphTest.java b/src/test/java/LineGraphTest.java index 6783bb867..5db6ddc2d 100644 --- a/src/test/java/LineGraphTest.java +++ b/src/test/java/LineGraphTest.java @@ -23,13 +23,13 @@ * For testing the import of a line graph. */ public class LineGraphTest { - private final static DiffTreeLineGraphImportOptions IMPORT_OPTIONS = new DiffTreeLineGraphImportOptions( + private final static LineGraphImportOptions IMPORT_OPTIONS = new LineGraphImportOptions( GraphFormat.DIFFTREE, new CommitDiffDiffTreeLabelFormat(), new LabelOnlyDiffNodeFormat(), new DefaultEdgeLabelFormat() ); - private final static DiffTreeLineGraphExportOptions EXPORT_OPTIONS = new DiffTreeLineGraphExportOptions( + private final static LineGraphExportOptions EXPORT_OPTIONS = new LineGraphExportOptions( IMPORT_OPTIONS ); diff --git a/src/test/java/MarlinDebug.java b/src/test/java/MarlinDebug.java index b2d0e4340..2673261bb 100644 --- a/src/test/java/MarlinDebug.java +++ b/src/test/java/MarlinDebug.java @@ -106,7 +106,7 @@ public static void testCommit(final RepoInspection repoInspection, final String try { Logger.info(ProposedEditClasses.Instance.match(node)); } catch (Exception e) { - //DiffTreeLineGraphExportOptions.RenderError().accept(patch, e); + //LineGraphExportOptions.RenderError().accept(patch, e); Logger.error(e); Logger.info("Died at node {}", node.toString()); Logger.info(" before parent: {}", node.getBeforeParent()); diff --git a/src/test/java/TestMultiLineMacros.java b/src/test/java/TestMultiLineMacros.java index ccc39d663..e2ab633b7 100644 --- a/src/test/java/TestMultiLineMacros.java +++ b/src/test/java/TestMultiLineMacros.java @@ -4,7 +4,7 @@ import org.variantsync.diffdetective.diff.difftree.DiffTree; import org.variantsync.diffdetective.diff.difftree.parse.DiffNodeParser; import org.variantsync.diffdetective.diff.difftree.parse.DiffTreeParser; -import org.variantsync.diffdetective.diff.difftree.serialize.DiffTreeLineGraphExportOptions; +import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import org.variantsync.diffdetective.diff.difftree.serialize.DiffTreeSerializeDebugData; import org.variantsync.diffdetective.diff.difftree.serialize.GraphFormat; import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExport; @@ -23,7 +23,7 @@ public class TestMultiLineMacros { private static final Path resDir = Constants.RESOURCE_DIR.resolve("multilinemacros"); - public void diffToDiffTree(DiffTreeLineGraphExportOptions exportOptions, Path p) throws IOException { + public void diffToDiffTree(LineGraphExportOptions exportOptions, Path p) throws IOException { DiffTree tree; try (BufferedReader fullDiff = Files.newBufferedReader(p)) { tree = DiffTreeParser.createDiffTree( @@ -49,7 +49,7 @@ public void diffToDiffTree(DiffTreeLineGraphExportOptions exportOptions, Path p) @Test public void test() throws IOException { - final DiffTreeLineGraphExportOptions exportOptions = new DiffTreeLineGraphExportOptions( + final LineGraphExportOptions exportOptions = new LineGraphExportOptions( GraphFormat.DIFFTREE, new CommitDiffDiffTreeLabelFormat(), new DebugDiffNodeFormat(), From f87009b447a9c0f75c41cf6c975accd531c0ed8f Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Sun, 25 Sep 2022 09:55:17 +0200 Subject: [PATCH 2/9] Separate filtering and processing from exporting `DiffTree`s Behavioural changes: - `EditClassValidationTask` doesn't add export options to the metadata anymore because it doesn't actually export anything. - Bug fix: The tree preprocessing in `MiningTask` was run twice: First for the line graph export and second directly by the `call` method. --- .../analysis/CommitHistoryAnalysisTask.java | 17 ++--- .../analysis/HistoryAnalysis.java | 10 ++- .../analysis/strategies/AnalysisMonitor.java | 5 +- .../analysis/strategies/AnalysisStrategy.java | 6 +- .../strategies/AnalyzeAllThenExport.java | 5 +- .../AnalyzeAndExportIncrementally.java | 5 +- .../strategies/CompositeAnalysisStrategy.java | 7 +- .../difftree/serialize/LineGraphExport.java | 73 +++++++++---------- .../serialize/LineGraphExportOptions.java | 7 +- .../diffdetective/mining/DiffTreeMiner.java | 25 +++---- .../diffdetective/mining/MiningTask.java | 32 +++++--- .../validation/EditClassValidationTask.java | 10 +-- .../diffdetective/validation/Validation.java | 5 +- src/test/java/MarlinDebug.java | 16 ++-- 14 files changed, 106 insertions(+), 117 deletions(-) diff --git a/src/main/java/org/variantsync/diffdetective/analysis/CommitHistoryAnalysisTask.java b/src/main/java/org/variantsync/diffdetective/analysis/CommitHistoryAnalysisTask.java index 700dff054..7bc86c676 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/CommitHistoryAnalysisTask.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/CommitHistoryAnalysisTask.java @@ -5,7 +5,9 @@ import org.variantsync.diffdetective.analysis.strategies.AnalysisStrategy; import org.variantsync.diffdetective.datasets.Repository; import org.variantsync.diffdetective.diff.GitDiffer; -import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; +import org.variantsync.diffdetective.diff.difftree.DiffTree; +import org.variantsync.diffdetective.diff.difftree.filter.ExplainedFilter; +import org.variantsync.diffdetective.diff.difftree.transform.DiffTreeTransformer; import org.variantsync.diffdetective.util.CSV; import org.variantsync.diffdetective.util.IO; import org.variantsync.diffdetective.util.StringUtils; @@ -29,7 +31,8 @@ public abstract class CommitHistoryAnalysisTask implements Callable treeFilter, + List treePreProcessing, AnalysisStrategy analysisStrategy, Iterable commits ) {} @@ -58,14 +62,9 @@ public CommitHistoryAnalysisTask.Options getOptions() { @Override public AnalysisResult call() throws Exception { - options.analysisStrategy().start(options.repository(), options.outputDir(), options.exportOptions()); + options.analysisStrategy().start(options.repository(), options.outputDir()); final AnalysisResult miningResult = new AnalysisResult(options.repository.getRepositoryName()); - final LineGraphExportOptions exportOptions = options.exportOptions(); - - miningResult.putCustomInfo(MetadataKeys.TREEFORMAT, exportOptions.treeFormat().getName()); - miningResult.putCustomInfo(MetadataKeys.NODEFORMAT, exportOptions.nodeFormat().getName()); - miningResult.putCustomInfo(MetadataKeys.EDGEFORMAT, exportOptions.edgeFormat().getName()); miningResult.putCustomInfo(MetadataKeys.TASKNAME, this.getClass().getName()); return miningResult; diff --git a/src/main/java/org/variantsync/diffdetective/analysis/HistoryAnalysis.java b/src/main/java/org/variantsync/diffdetective/analysis/HistoryAnalysis.java index 518dca04a..92b7018c5 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/HistoryAnalysis.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/HistoryAnalysis.java @@ -6,7 +6,10 @@ import org.variantsync.diffdetective.analysis.strategies.AnalysisStrategy; import org.variantsync.diffdetective.datasets.Repository; import org.variantsync.diffdetective.diff.GitDiffer; +import org.variantsync.diffdetective.diff.difftree.DiffTree; +import org.variantsync.diffdetective.diff.difftree.filter.ExplainedFilter; import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; +import org.variantsync.diffdetective.diff.difftree.transform.DiffTreeTransformer; import org.variantsync.diffdetective.metadata.Metadata; import org.variantsync.diffdetective.mining.MiningTask; import org.variantsync.diffdetective.parallel.ScheduledTasksIterator; @@ -56,6 +59,8 @@ public record HistoryAnalysis( public static void analyze( final Repository repo, final Path outputDir, + final ExplainedFilter treeFilter, + final List treePreProcessing, final LineGraphExportOptions exportOptions, final AnalysisStrategy strategy) { @@ -71,10 +76,11 @@ public static void analyze( repo, differ, outputDir.resolve(repo.getRepositoryName() + ".lg"), - exportOptions, + treeFilter, + treePreProcessing, strategy, commitsToProcess - )); + ), exportOptions); Logger.info("Scheduled {} commits.", commitsToProcess.size()); commitsToProcess = null; // free reference to enable garbage collection Logger.info("<<< done after {}", clock.printPassedSeconds()); diff --git a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisMonitor.java b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisMonitor.java index 98556e9b8..860cd3817 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisMonitor.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisMonitor.java @@ -3,7 +3,6 @@ import org.variantsync.diffdetective.analysis.monitoring.TaskCompletionMonitor; import org.variantsync.diffdetective.datasets.Repository; import org.variantsync.diffdetective.diff.CommitDiff; -import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import java.nio.file.Path; @@ -24,8 +23,8 @@ public AnalysisMonitor(int seconds) { } @Override - public void start(Repository repo, Path outputPath, LineGraphExportOptions options) { - super.start(repo, outputPath, options); + public void start(Repository repo, Path outputPath) { + super.start(repo, outputPath); monitor.start(); } diff --git a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisStrategy.java b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisStrategy.java index 83ac02e8b..8bec57262 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisStrategy.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisStrategy.java @@ -2,7 +2,6 @@ import org.variantsync.diffdetective.datasets.Repository; import org.variantsync.diffdetective.diff.CommitDiff; -import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import java.nio.file.Path; @@ -15,19 +14,16 @@ public abstract class AnalysisStrategy { protected Repository repo; protected Path outputPath; - protected LineGraphExportOptions exportOptions; /** * Invoked when the analysis starts. * * @param repo The repository on which an analysis is performed. * @param outputPath A directory to which output should be written. - * @param options Options for data export. */ - public void start(Repository repo, Path outputPath, LineGraphExportOptions options) { + public void start(Repository repo, Path outputPath) { this.repo = repo; this.outputPath = outputPath; - this.exportOptions = options; } /** diff --git a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAllThenExport.java b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAllThenExport.java index 61427c46d..eb6405abf 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAllThenExport.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAllThenExport.java @@ -2,7 +2,6 @@ import org.variantsync.diffdetective.datasets.Repository; import org.variantsync.diffdetective.diff.CommitDiff; -import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import org.variantsync.diffdetective.util.IO; import java.nio.file.Path; @@ -15,8 +14,8 @@ public class AnalyzeAllThenExport extends AnalysisStrategy { private StringBuilder waitForAll; @Override - public void start(Repository repo, Path outputPath, LineGraphExportOptions options) { - super.start(repo, outputPath, options); + public void start(Repository repo, Path outputPath) { + super.start(repo, outputPath); waitForAll = new StringBuilder(); } diff --git a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAndExportIncrementally.java b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAndExportIncrementally.java index 4a3a6202c..1ddd341ad 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAndExportIncrementally.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAndExportIncrementally.java @@ -3,7 +3,6 @@ import org.tinylog.Logger; import org.variantsync.diffdetective.datasets.Repository; import org.variantsync.diffdetective.diff.CommitDiff; -import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import org.variantsync.diffdetective.util.IO; import java.io.IOException; @@ -44,8 +43,8 @@ public AnalyzeAndExportIncrementally() { } @Override - public void start(Repository repo, Path outputPath, LineGraphExportOptions options) { - super.start(repo, outputPath, options); + public void start(Repository repo, Path outputPath) { + super.start(repo, outputPath); IO.tryDeleteFile(outputPath); nextChunkToExport = new StringBuilder(); diff --git a/src/main/java/org/variantsync/diffdetective/analysis/strategies/CompositeAnalysisStrategy.java b/src/main/java/org/variantsync/diffdetective/analysis/strategies/CompositeAnalysisStrategy.java index dddbb5a17..cba412c49 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/strategies/CompositeAnalysisStrategy.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/strategies/CompositeAnalysisStrategy.java @@ -2,7 +2,6 @@ import org.variantsync.diffdetective.datasets.Repository; import org.variantsync.diffdetective.diff.CommitDiff; -import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import java.nio.file.Path; import java.util.Arrays; @@ -26,10 +25,10 @@ public CompositeAnalysisStrategy(final AnalysisStrategy... strategies) { } @Override - public void start(Repository repo, Path outputPath, LineGraphExportOptions options) { - super.start(repo, outputPath, options); + public void start(Repository repo, Path outputPath) { + super.start(repo, outputPath); for (final AnalysisStrategy s : strategies) { - s.start(repo, outputPath, options); + s.start(repo, outputPath); } } diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java index de89f2afc..a535b9d0e 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java @@ -8,8 +8,6 @@ import org.variantsync.diffdetective.diff.PatchDiff; import org.variantsync.diffdetective.diff.difftree.DiffTree; import org.variantsync.diffdetective.diff.difftree.DiffTreeSource; -import org.variantsync.diffdetective.diff.difftree.transform.DiffTreeTransformer; -import org.variantsync.diffdetective.metadata.ExplainedFilterSummary; import org.variantsync.diffdetective.util.StringUtils; import org.variantsync.functjonal.Pair; @@ -27,17 +25,10 @@ private LineGraphExport() {} * @return A pair holding some debug information and the produced linegraph as a string. */ public static Pair toLineGraphFormat(final DiffTree diffTree, final LineGraphExportOptions options) { - DiffTreeTransformer.apply(options.treePreProcessing(), diffTree); - diffTree.assertConsistency(); - - if (options.treeFilter().test(diffTree)) { - final var exporter = new LineGraphExporter(options); - var output = new ByteArrayOutputStream(); - exporter.exportDiffTree(diffTree, output); - return new Pair<>(exporter.getDebugData(), output.toString()); - } - - return null; + final var exporter = new LineGraphExporter(options); + var output = new ByteArrayOutputStream(); + exporter.exportDiffTree(diffTree, output); + return new Pair<>(exporter.getDebugData(), output.toString()); } /** @@ -54,15 +45,12 @@ public static Pair toLineGraphFormat(final String repoNa for (final DiffTree t : trees) { final Pair lg = toLineGraphFormat(t, options); - if (lg != null) { - result.debugData.append(lg.first()); - composeTreeInLineGraph(lineGraph, t.getSource(), lg.second(), options); - ++result.exportedTrees; - } + result.debugData.append(lg.first()); + composeTreeInLineGraph(lineGraph, t.getSource(), lg.second(), options); + ++result.exportedTrees; } result.exportedCommits = 1; - result.filterHits = new ExplainedFilterSummary(options.treeFilter()); return new Pair<>(result, lineGraph.toString()); } @@ -94,34 +82,41 @@ public static AnalysisResult toLineGraphFormat(final CommitDiff commitDiff, fina public static AnalysisResult toLineGraphFormat(final String repoName, final CommitDiff commitDiff, final StringBuilder lineGraph, final LineGraphExportOptions options) { final AnalysisResult result = new AnalysisResult(repoName); - final String hash = commitDiff.getCommitHash(); for (final PatchDiff patchDiff : commitDiff.getPatchDiffs()) { - if (patchDiff.isValid()) { - //Logger.info(" Exporting DiffTree #{}", treeCounter); - final Pair patchDiffLg; - try { - patchDiffLg = toLineGraphFormat(patchDiff.getDiffTree(), options); - } catch (Exception e) { - options.onError().accept(patchDiff, e); - break; - } - - if (patchDiffLg != null) { - result.debugData.append(patchDiffLg.first()); - composeTreeInLineGraph(lineGraph, patchDiff, patchDiffLg.second(), options); - ++result.exportedTrees; - } - } else { - Logger.debug(" Skipping invalid patch for file {} at commit {}", patchDiff.getFileName(), hash); + try { + toLineGraphFormat(patchDiff, lineGraph, options, result); + } catch (Exception e) { + options.onError().accept(patchDiff, e); + break; } } result.exportedCommits = 1; - result.filterHits = new ExplainedFilterSummary(options.treeFilter()); return result; } - + + /** + * Writes the given patch in linegraph format to the given StringBuilder. + * @param patch The diff to convert to line graph format. + * @param lineGraph The string builder to write the result to. + * @param options Configuration options for the export, such as the format used for node and edge labels. + * @param result where the number of exported trees and debug data is updated + */ + public static void toLineGraphFormat(final PatchDiff patch, final StringBuilder lineGraph, final LineGraphExportOptions options, AnalysisResult result) { + if (patch.isValid()) { + //Logger.info(" Exporting DiffTree #{}", treeCounter); + final Pair patchLg; + patchLg = toLineGraphFormat(patch.getDiffTree(), options); + + result.debugData.append(patchLg.first()); + composeTreeInLineGraph(lineGraph, patch, patchLg.second(), options); + ++result.exportedTrees; + } else { + Logger.debug(" Skipping invalid patch for file {} at commit {}", patch.getFileName(), patch.getCommitHash()); + } + } + /** * Produces the final linegraph file content. * Creates a linegraph header from the given DiffTreeSource using the {@link LineGraphExportOptions#treeFormat} in the given options. diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExportOptions.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExportOptions.java index 57f3474bd..edba32dc7 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExportOptions.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExportOptions.java @@ -3,7 +3,6 @@ import org.tinylog.Logger; import org.variantsync.diffdetective.diff.PatchDiff; import org.variantsync.diffdetective.diff.difftree.DiffTree; -import org.variantsync.diffdetective.diff.difftree.filter.ExplainedFilter; import org.variantsync.diffdetective.diff.difftree.render.DiffTreeRenderer; import org.variantsync.diffdetective.diff.difftree.render.PatchDiffRenderer; import org.variantsync.diffdetective.diff.difftree.serialize.edgeformat.EdgeLabelFormat; @@ -12,8 +11,6 @@ import org.variantsync.diffdetective.diff.difftree.transform.DiffTreeTransformer; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; import java.util.function.BiConsumer; /** @@ -34,15 +31,13 @@ public record LineGraphExportOptions( DiffTreeLabelFormat treeFormat, DiffNodeLabelFormat nodeFormat, EdgeLabelFormat edgeFormat, - ExplainedFilter treeFilter, - List treePreProcessing, BiConsumer onError) { /** * Creates a export options with a neutral filter (that accepts all trees), no transformers, and that logs errors. */ public LineGraphExportOptions(GraphFormat graphFormat, DiffTreeLabelFormat treeFormat, DiffNodeLabelFormat nodeFormat, EdgeLabelFormat edgeFormat) { - this(graphFormat, treeFormat, nodeFormat, edgeFormat, ExplainedFilter.Any(), new ArrayList<>(), LogError()); + this(graphFormat, treeFormat, nodeFormat, edgeFormat, LogError()); } /** diff --git a/src/main/java/org/variantsync/diffdetective/mining/DiffTreeMiner.java b/src/main/java/org/variantsync/diffdetective/mining/DiffTreeMiner.java index 83240bdfd..7b87a7935 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/DiffTreeMiner.java +++ b/src/main/java/org/variantsync/diffdetective/mining/DiffTreeMiner.java @@ -80,17 +80,6 @@ public static LineGraphExportOptions MiningExportOptions(final Repository reposi , new CommitDiffDiffTreeLabelFormat() , nodeFormat , EdgeFormat(nodeFormat) - , new ExplainedFilter<>( - DiffTreeFilter.notEmpty(), - DiffTreeFilter.moreThanOneArtifactNode(), - /// We want to exclude patches that do not edit variability. - /// In particular, we noticed that most edits just insert or delete artifacts (or replace it). - /// This is reasonable and was also observed in previous studies: Edits to artifacts are more frequent than edits to variability. - /// Yet, such edits cannot reveal compositions of more complex edits to variability. - /// We thus filter them. - DiffTreeFilter.hasAtLeastOneEditToVariability() - ) - , Postprocessing(repository) , LineGraphExportOptions.LogError() .andThen(LineGraphExportOptions.RenderError()) .andThen(LineGraphExportOptions.SysExitOnError()) @@ -110,10 +99,20 @@ public static CommitHistoryAnalysisTaskFactory Mine() { repo, differ, outputPath, - MiningExportOptions(repo), + new ExplainedFilter<>( + DiffTreeFilter.notEmpty(), + DiffTreeFilter.moreThanOneArtifactNode(), + /// We want to exclude patches that do not edit variability. + /// In particular, we noticed that most edits just insert or delete artifacts (or replace it). + /// This is reasonable and was also observed in previous studies: Edits to artifacts are more frequent than edits to variability. + /// Yet, such edits cannot reveal compositions of more complex edits to variability. + /// We thus filter them. + DiffTreeFilter.hasAtLeastOneEditToVariability() + ), + Postprocessing(repo), MiningStrategy(), commits - )); + ), MiningExportOptions(repo)); } public static void main(String[] args) throws IOException { diff --git a/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java b/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java index f882faea7..d4739ee3d 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java +++ b/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java @@ -20,14 +20,20 @@ import java.util.List; public class MiningTask extends CommitHistoryAnalysisTask { - public MiningTask(final Options options) { + private final LineGraphExportOptions exportOptions; + + public MiningTask(final Options options, final LineGraphExportOptions exportOptions) { super(options); + + this.exportOptions = exportOptions; } @Override public AnalysisResult call() throws Exception { final AnalysisResult miningResult = super.call(); - final LineGraphExportOptions exportOptions = options.exportOptions(); + miningResult.putCustomInfo(MetadataKeys.TREEFORMAT, exportOptions.treeFormat().getName()); + miningResult.putCustomInfo(MetadataKeys.NODEFORMAT, exportOptions.nodeFormat().getName()); + miningResult.putCustomInfo(MetadataKeys.EDGEFORMAT, exportOptions.edgeFormat().getName()); final Clock totalTime = new Clock(); @@ -48,14 +54,12 @@ public AnalysisResult call() throws Exception { } /* - * We export all difftrees that match our filter criteria (e.g., match more than one edit class). - * However, we count edit classes of all DiffTrees, even those that are not exported to Linegraph. + * We count the edit classes of all difftrees that match our filter criteria + * (e.g., match more than one edit class) and export them to the destination + * determined by the AnalysisStrategy. */ final CommitDiff commitDiff = commitDiffResult.diff().get(); final StringBuilder lineGraph = new StringBuilder(); - miningResult.append(LineGraphExport.toLineGraphFormat(commitDiff, lineGraph, options.exportOptions())); - options.analysisStrategy().onCommit(commitDiff, lineGraph.toString()); - options.exportOptions().treeFilter().resetExplanations(); // Count edit classes int numDiffTrees = 0; @@ -64,13 +68,15 @@ public AnalysisResult call() throws Exception { if (patch.isValid()) { final DiffTree t = patch.getDiffTree(); - DiffTreeTransformer.apply(exportOptions.treePreProcessing(), t); + DiffTreeTransformer.apply(options.treePreProcessing(), t); t.assertConsistency(); - if (!exportOptions.treeFilter().test(t)) { + if (!options.treeFilter().test(t)) { continue; } + LineGraphExport.toLineGraphFormat(patch, lineGraph, exportOptions, miningResult); + t.forAll(node -> { if (node.isArtifact()) { final EditClass editClass = ProposedEditClasses.Instance.match(node); @@ -87,9 +93,13 @@ public AnalysisResult call() throws Exception { patchStatistics.add(thisPatchesStatistics); } + + options.analysisStrategy().onCommit(commitDiff, lineGraph.toString()); + + miningResult.exportedCommits += 1; miningResult.exportedTrees += numDiffTrees; - miningResult.filterHits.append(new ExplainedFilterSummary(exportOptions.treeFilter())); - exportOptions.treeFilter().resetExplanations(); + miningResult.filterHits.append(new ExplainedFilterSummary(options.treeFilter())); + options.treeFilter().resetExplanations(); // Only consider non-empty commits if (numDiffTrees > 0) { diff --git a/src/main/java/org/variantsync/diffdetective/validation/EditClassValidationTask.java b/src/main/java/org/variantsync/diffdetective/validation/EditClassValidationTask.java index 4e71a46d5..c7db75300 100644 --- a/src/main/java/org/variantsync/diffdetective/validation/EditClassValidationTask.java +++ b/src/main/java/org/variantsync/diffdetective/validation/EditClassValidationTask.java @@ -9,7 +9,6 @@ import org.variantsync.diffdetective.diff.CommitDiff; import org.variantsync.diffdetective.diff.PatchDiff; import org.variantsync.diffdetective.diff.difftree.DiffTree; -import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExportOptions; import org.variantsync.diffdetective.diff.difftree.transform.DiffTreeTransformer; import org.variantsync.diffdetective.diff.result.CommitDiffResult; import org.variantsync.diffdetective.metadata.ExplainedFilterSummary; @@ -33,7 +32,6 @@ public EditClassValidationTask(Options options) { public AnalysisResult call() throws Exception { // Setup. Obtain the result from the initial setup in the super class. final AnalysisResult miningResult = super.call(); - final LineGraphExportOptions exportOptions = options.exportOptions(); // List to store the process time of each commit. final List commitTimes = new ArrayList<>(HistoryAnalysis.COMMITS_TO_PROCESS_PER_THREAD_DEFAULT); // Clock for runtime measurement. @@ -66,10 +64,10 @@ public AnalysisResult call() throws Exception { for (final PatchDiff patch : commitDiff.getPatchDiffs()) { if (patch.isValid()) { final DiffTree t = patch.getDiffTree(); - DiffTreeTransformer.apply(exportOptions.treePreProcessing(), t); + DiffTreeTransformer.apply(options.treePreProcessing(), t); t.assertConsistency(); - if (!exportOptions.treeFilter().test(t)) { + if (!options.treeFilter().test(t)) { continue; } @@ -86,8 +84,8 @@ public AnalysisResult call() throws Exception { } } miningResult.exportedTrees += numDiffTrees; - miningResult.filterHits.append(new ExplainedFilterSummary(exportOptions.treeFilter())); - exportOptions.treeFilter().resetExplanations(); + miningResult.filterHits.append(new ExplainedFilterSummary(options.treeFilter())); + options.treeFilter().resetExplanations(); // Report the commit process time if the commit is not empty. if (numDiffTrees > 0) { diff --git a/src/main/java/org/variantsync/diffdetective/validation/Validation.java b/src/main/java/org/variantsync/diffdetective/validation/Validation.java index 2f5cf2144..3e79bca12 100644 --- a/src/main/java/org/variantsync/diffdetective/validation/Validation.java +++ b/src/main/java/org/variantsync/diffdetective/validation/Validation.java @@ -56,7 +56,8 @@ public class Validation { repo, differ, outputPath, - ValidationExportOptions(repo), + new ExplainedFilter<>(DiffTreeFilter.notEmpty()), + List.of(new CutNonEditedSubtrees()), new NullStrategy(), commits )); @@ -87,8 +88,6 @@ public static LineGraphExportOptions ValidationExportOptions(final Repository re , new CommitDiffDiffTreeLabelFormat() , nodeFormat , EdgeFormat(nodeFormat) - , new ExplainedFilter<>(DiffTreeFilter.notEmpty()) - , List.of(new CutNonEditedSubtrees()) , LineGraphExportOptions.LogError() .andThen(LineGraphExportOptions.RenderError()) .andThen(LineGraphExportOptions.SysExitOnError()) diff --git a/src/test/java/MarlinDebug.java b/src/test/java/MarlinDebug.java index 2673261bb..7ccd3f085 100644 --- a/src/test/java/MarlinDebug.java +++ b/src/test/java/MarlinDebug.java @@ -7,7 +7,6 @@ import org.junit.Test; import org.prop4j.Node; import org.tinylog.Logger; -import org.variantsync.diffdetective.analysis.CommitHistoryAnalysisTask; import org.variantsync.diffdetective.datasets.DatasetDescription; import org.variantsync.diffdetective.datasets.DatasetFactory; import org.variantsync.diffdetective.datasets.ParseOptions; @@ -22,7 +21,6 @@ import org.variantsync.diffdetective.diff.difftree.transform.DiffTreeTransformer; import org.variantsync.diffdetective.feature.CPPAnnotationParser; import org.variantsync.diffdetective.mining.DiffTreeMiner; -import org.variantsync.diffdetective.mining.MiningTask; import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import org.variantsync.diffdetective.util.Clock; import org.variantsync.diffdetective.validation.Validation; @@ -135,14 +133,12 @@ public static void asMiningTask(final RepoInspection repoInspection, final Strin final RevWalk revWalk = new RevWalk(git.getRepository()); final RevCommit childCommit = revWalk.parseCommit(ObjectId.fromString(commitHash)); - MiningTask m = new MiningTask(new CommitHistoryAnalysisTask.Options( - repoInspection.repo, - new GitDiffer(repoInspection.repo), - repoInspection.outputPath, - DiffTreeMiner.MiningExportOptions(repoInspection.repo), - DiffTreeMiner.MiningStrategy(), - List.of(childCommit))); - m.call(); + DiffTreeMiner.Mine().create( + repoInspection.repo, + new GitDiffer(repoInspection.repo), + repoInspection.outputPath, + List.of(childCommit) + ).call(); } public static void asValidationTask(final RepoInspection repoInspection, final String commitHash) throws Exception { From 946295231a3bb2ae9d34c2fd463693a780f7bc71 Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Sun, 25 Sep 2022 14:29:27 +0200 Subject: [PATCH 3/9] Use `OutputStream`s instead of `StringBuilder` in `LineGraphExport` --- .../analysis/strategies/AnalysisMonitor.java | 6 +- .../analysis/strategies/AnalysisStrategy.java | 11 +++- .../strategies/AnalyzeAllThenExport.java | 20 ++++-- .../AnalyzeAndExportIncrementally.java | 34 +++++----- .../strategies/CompositeAnalysisStrategy.java | 17 ++++- .../analysis/strategies/NullStrategy.java | 6 +- .../difftree/render/DiffTreeRenderer.java | 12 ++-- .../difftree/serialize/LineGraphExport.java | 65 +++++++++---------- .../diffdetective/mining/MiningTask.java | 53 +++++++-------- .../postprocessing/MiningPostprocessing.java | 12 ++-- .../variantsync/diffdetective/util/IO.java | 19 ++++++ .../validation/EditClassValidationTask.java | 2 +- src/test/java/LineGraphTest.java | 43 ++++++------ src/test/java/MarlinDebug.java | 4 -- src/test/java/TestMultiLineMacros.java | 20 +++--- 15 files changed, 181 insertions(+), 143 deletions(-) diff --git a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisMonitor.java b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisMonitor.java index 860cd3817..3f52c374e 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisMonitor.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisMonitor.java @@ -4,6 +4,7 @@ import org.variantsync.diffdetective.datasets.Repository; import org.variantsync.diffdetective.diff.CommitDiff; +import java.io.OutputStream; import java.nio.file.Path; /** @@ -29,8 +30,11 @@ public void start(Repository repo, Path outputPath) { } @Override - public void onCommit(CommitDiff commit, String lineGraph) { + public OutputStream onCommit(CommitDiff commit) { + // FIXME This function is called before processing the commit. monitor.addFinishedTasks(1); + + return OutputStream.nullOutputStream(); } @Override diff --git a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisStrategy.java b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisStrategy.java index 8bec57262..adafa29bd 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisStrategy.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalysisStrategy.java @@ -3,6 +3,7 @@ import org.variantsync.diffdetective.datasets.Repository; import org.variantsync.diffdetective.diff.CommitDiff; +import java.io.OutputStream; import java.nio.file.Path; /** @@ -27,11 +28,15 @@ public void start(Repository repo, Path outputPath) { } /** - * Invoked whenever the analysis processed a commit and converted it to linegraph format. + * Invoked before a commit is analyzed. + * + * The returned line graph export destination is closed after processing the commit given by + * {@code commit}. + * * @param commit The commit that was just processed. - * @param lineGraph The linegraph representation of the processed commit. Might be empty if no export to linegraph is desired. + * @return the line graph export destination */ - public abstract void onCommit(CommitDiff commit, String lineGraph); + public abstract OutputStream onCommit(CommitDiff commit); /** * Invoked when the analysis is done for the current repository. diff --git a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAllThenExport.java b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAllThenExport.java index eb6405abf..d2868057b 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAllThenExport.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAllThenExport.java @@ -1,9 +1,14 @@ package org.variantsync.diffdetective.analysis.strategies; +import org.apache.commons.io.output.CloseShieldOutputStream; +import org.tinylog.Logger; import org.variantsync.diffdetective.datasets.Repository; import org.variantsync.diffdetective.diff.CommitDiff; import org.variantsync.diffdetective.util.IO; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; import java.nio.file.Path; /** @@ -11,23 +16,24 @@ * @author Paul Bittner */ public class AnalyzeAllThenExport extends AnalysisStrategy { - private StringBuilder waitForAll; + private ByteArrayOutputStream lineGraphDestination; @Override public void start(Repository repo, Path outputPath) { super.start(repo, outputPath); - waitForAll = new StringBuilder(); } @Override - public void onCommit(CommitDiff commit, String lineGraph) { - waitForAll.append(lineGraph); + public OutputStream onCommit(CommitDiff commit) { + return new CloseShieldOutputStream(lineGraphDestination); } @Override public void end() { - final String lineGraph = waitForAll.toString(); -// Logger.info("Writing file {}", outputPath); - IO.tryWrite(outputPath, lineGraph); + try (var finalDestination = IO.newBufferedOutputStream(outputPath)) { + lineGraphDestination.writeTo(finalDestination); + } catch (IOException e) { + Logger.error(e); + } } } diff --git a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAndExportIncrementally.java b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAndExportIncrementally.java index 1ddd341ad..c9b04a8b6 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAndExportIncrementally.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAndExportIncrementally.java @@ -1,12 +1,16 @@ package org.variantsync.diffdetective.analysis.strategies; +import org.apache.commons.io.output.CloseShieldOutputStream; import org.tinylog.Logger; import org.variantsync.diffdetective.datasets.Repository; import org.variantsync.diffdetective.diff.CommitDiff; import org.variantsync.diffdetective.util.IO; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.nio.file.Path; +import java.nio.file.StandardOpenOption; /** * Collects the linegraph representations generated by an analysis and exports them once a certain threshold of @@ -21,7 +25,7 @@ public class AnalyzeAndExportIncrementally extends AnalysisStrategy { public static final int DEFAULT_NUMBER_OF_COMMITS_TO_EXPORT_AT_ONCE = 100; private final int commitsToExportAtOnce; - private StringBuilder nextChunkToExport; + private ByteArrayOutputStream lineGraphDestination; private int collectedCommits; /** @@ -47,27 +51,27 @@ public void start(Repository repo, Path outputPath) { super.start(repo, outputPath); IO.tryDeleteFile(outputPath); - nextChunkToExport = new StringBuilder(); + + lineGraphDestination = new ByteArrayOutputStream(); collectedCommits = 0; } @Override - public void onCommit(CommitDiff commit, String lineGraph) { + public OutputStream onCommit(CommitDiff commit) { ++collectedCommits; - nextChunkToExport.append(lineGraph); - - if (collectedCommits >= commitsToExportAtOnce) { - exportAppend(outputPath, nextChunkToExport.toString()); - nextChunkToExport = new StringBuilder(); + if (collectedCommits > commitsToExportAtOnce) { + flush(); collectedCommits = 0; } + + // lineGraphDestination is reused for all commits. CloseShieldOutputStream ensures that it + // isn't closed after processing this commit. + return new CloseShieldOutputStream(lineGraphDestination); } @Override public void end() { - if (!nextChunkToExport.isEmpty()) { - exportAppend(outputPath, nextChunkToExport.toString()); - } + flush(); } /** @@ -75,10 +79,10 @@ public void end() { * @param outputPath File to which the linegraph string should be appended. * @param linegraph String to append to the given file. */ - public static void exportAppend(final Path outputPath, final String linegraph) { - try { -// Logger.info("Writing file {}", outputPath); - IO.append(outputPath, linegraph); + private void flush() { + try (var output = IO.newBufferedOutputStream(outputPath, StandardOpenOption.CREATE, StandardOpenOption.APPEND)) { + lineGraphDestination.writeTo(output); + lineGraphDestination.reset(); } catch (IOException exception) { Logger.error(exception); } diff --git a/src/main/java/org/variantsync/diffdetective/analysis/strategies/CompositeAnalysisStrategy.java b/src/main/java/org/variantsync/diffdetective/analysis/strategies/CompositeAnalysisStrategy.java index cba412c49..3acdf2c72 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/strategies/CompositeAnalysisStrategy.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/strategies/CompositeAnalysisStrategy.java @@ -1,8 +1,10 @@ package org.variantsync.diffdetective.analysis.strategies; +import org.apache.commons.io.output.TeeOutputStream; import org.variantsync.diffdetective.datasets.Repository; import org.variantsync.diffdetective.diff.CommitDiff; +import java.io.OutputStream; import java.nio.file.Path; import java.util.Arrays; import java.util.Collection; @@ -33,10 +35,19 @@ public void start(Repository repo, Path outputPath) { } @Override - public void onCommit(CommitDiff commit, String lineGraph) { - for (final AnalysisStrategy s : strategies) { - s.onCommit(commit, lineGraph); + public OutputStream onCommit(CommitDiff commit) { + var it = strategies.iterator(); + + if (!it.hasNext()) { + return OutputStream.nullOutputStream(); } + + OutputStream destination = it.next().onCommit(commit); + while (it.hasNext()) { + destination = new TeeOutputStream(destination, it.next().onCommit(commit)); + } + + return destination; } @Override diff --git a/src/main/java/org/variantsync/diffdetective/analysis/strategies/NullStrategy.java b/src/main/java/org/variantsync/diffdetective/analysis/strategies/NullStrategy.java index 79c7027bb..496a0cc74 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/strategies/NullStrategy.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/strategies/NullStrategy.java @@ -1,5 +1,7 @@ package org.variantsync.diffdetective.analysis.strategies; +import java.io.OutputStream; + import org.variantsync.diffdetective.diff.CommitDiff; /** @@ -8,8 +10,8 @@ */ public class NullStrategy extends AnalysisStrategy { @Override - public void onCommit(CommitDiff commit, String lineGraph) { - + public OutputStream onCommit(CommitDiff commit) { + return OutputStream.nullOutputStream(); } @Override diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/render/DiffTreeRenderer.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/render/DiffTreeRenderer.java index 4592c3880..203c32b3f 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/render/DiffTreeRenderer.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/render/DiffTreeRenderer.java @@ -182,7 +182,7 @@ public boolean renderWithTreeFormat(final DiffTree tree, final String treeAndFil * The python script will produce an image file at the given directory. * @param tree The tree to render. * @param treeAndFileName A name for the written file as well as the tree (used as a caption in the produced image). - * @param directory The directory to which the the rendered file should be written to. + * @param directory The directory to which the rendered file should be written to. * @param options Configuration options for the rendering process. * @param exportOptions Configuration options for the intermediate export to the linegraph format. * Should be compatible with the render options. @@ -194,12 +194,10 @@ public boolean renderWithTreeFormat(final DiffTree tree, final String treeAndFil private boolean render(final DiffTree tree, final String treeAndFileName, final Path directory, RenderOptions options, LineGraphExportOptions exportOptions, BiFunction treeHeader) { final Path tempFile = directory.resolve(treeAndFileName + ".lg"); - final Pair result = LineGraphExport.toLineGraphFormat(tree, exportOptions); - Assert.assertNotNull(result); - final String lg = treeHeader.apply(treeAndFileName, tree.getSource()) + StringUtils.LINEBREAK + result.second(); - - try { - IO.write(tempFile, lg); + try (var destination = IO.newBufferedOutputStream(tempFile)) { + destination.write((treeHeader.apply(treeAndFileName, tree.getSource()) + StringUtils.LINEBREAK).getBytes()); + final DiffTreeSerializeDebugData result = LineGraphExport.toLineGraphFormat(tree, exportOptions, destination); + Assert.assertNotNull(result); } catch (IOException e) { Logger.error(e, "Could not render difftree {} because", treeAndFileName); return false; diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java index a535b9d0e..e7ee874a7 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java @@ -1,6 +1,7 @@ package org.variantsync.diffdetective.diff.difftree.serialize; -import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; import org.tinylog.Logger; import org.variantsync.diffdetective.analysis.AnalysisResult; @@ -9,7 +10,6 @@ import org.variantsync.diffdetective.diff.difftree.DiffTree; import org.variantsync.diffdetective.diff.difftree.DiffTreeSource; import org.variantsync.diffdetective.util.StringUtils; -import org.variantsync.functjonal.Pair; /** * Class that contains functions for writing {@link CommitDiff}s and (sets of) {@link DiffTree}s to a linegraph file. @@ -24,11 +24,10 @@ private LineGraphExport() {} * @param options Configuration options for the export, such as the format used for node and edge labels. * @return A pair holding some debug information and the produced linegraph as a string. */ - public static Pair toLineGraphFormat(final DiffTree diffTree, final LineGraphExportOptions options) { + public static DiffTreeSerializeDebugData toLineGraphFormat(final DiffTree diffTree, final LineGraphExportOptions options, OutputStream destination) throws IOException { final var exporter = new LineGraphExporter(options); - var output = new ByteArrayOutputStream(); - exporter.exportDiffTree(diffTree, output); - return new Pair<>(exporter.getDebugData(), output.toString()); + exporter.exportDiffTree(diffTree, destination); + return exporter.getDebugData(); } /** @@ -38,37 +37,35 @@ public static Pair toLineGraphFormat(final D * @param options Configuration options for the export, such as the format used for node and edge labels. * @return A pair of (1) metadata about the exported DiffTrees, and (2) the produced linegraph as String. */ - public static Pair toLineGraphFormat(final String repoName, final Iterable trees, final LineGraphExportOptions options) { + public static AnalysisResult toLineGraphFormat(final String repoName, final Iterable trees, final LineGraphExportOptions options, OutputStream destination) throws IOException { final AnalysisResult result = new AnalysisResult(repoName); - final StringBuilder lineGraph = new StringBuilder(); for (final DiffTree t : trees) { - final Pair lg = toLineGraphFormat(t, options); - - result.debugData.append(lg.first()); - composeTreeInLineGraph(lineGraph, t.getSource(), lg.second(), options); + destination.write(lineGraphHeader(t.getSource(), options).getBytes()); + result.debugData.append(toLineGraphFormat(t, options, destination)); + destination.write(lineGraphFooter().getBytes()); ++result.exportedTrees; } result.exportedCommits = 1; - return new Pair<>(result, lineGraph.toString()); + return result; } /** - * Same as {@link LineGraphExport#toLineGraphFormat(String, Iterable, LineGraphExportOptions)} but with an + * Same as {@link LineGraphExport#toLineGraphFormat(String, Iterable, LineGraphExportOptions, OutputStream)} but with an * {@link AnalysisResult#NO_REPO unkown repository}. */ - public static Pair toLineGraphFormat(final Iterable trees, final LineGraphExportOptions options) { - return toLineGraphFormat(AnalysisResult.NO_REPO, trees, options); + public static AnalysisResult toLineGraphFormat(final Iterable trees, final LineGraphExportOptions options, OutputStream destination) throws IOException { + return toLineGraphFormat(AnalysisResult.NO_REPO, trees, options, destination); } /** - * Same as {@link LineGraphExport#toLineGraphFormat(String, CommitDiff, StringBuilder, LineGraphExportOptions)} + * Same as {@link LineGraphExport#toLineGraphFormat(String, CommitDiff, LineGraphExportOptions, OutputStream)} * but with an {@link AnalysisResult#NO_REPO unkown repository}. */ - public static AnalysisResult toLineGraphFormat(final CommitDiff commitDiff, final StringBuilder lineGraph, final LineGraphExportOptions options) { - return toLineGraphFormat(AnalysisResult.NO_REPO, commitDiff, lineGraph, options); + public static AnalysisResult toLineGraphFormat(final CommitDiff commitDiff, final LineGraphExportOptions options, OutputStream destination) throws IOException { + return toLineGraphFormat(AnalysisResult.NO_REPO, commitDiff, options, destination); } /** @@ -79,12 +76,12 @@ public static AnalysisResult toLineGraphFormat(final CommitDiff commitDiff, fina * @param options Configuration options for the export, such as the format used for node and edge labels. * @return The number of the next diff tree to export (updated value of treeCounter). */ - public static AnalysisResult toLineGraphFormat(final String repoName, final CommitDiff commitDiff, final StringBuilder lineGraph, final LineGraphExportOptions options) { + public static AnalysisResult toLineGraphFormat(final String repoName, final CommitDiff commitDiff, LineGraphExportOptions options, OutputStream destination) throws IOException { final AnalysisResult result = new AnalysisResult(repoName); for (final PatchDiff patchDiff : commitDiff.getPatchDiffs()) { try { - toLineGraphFormat(patchDiff, lineGraph, options, result); + toLineGraphFormat(patchDiff, options, destination, result); } catch (Exception e) { options.onError().accept(patchDiff, e); break; @@ -103,14 +100,15 @@ public static AnalysisResult toLineGraphFormat(final String repoName, final Comm * @param options Configuration options for the export, such as the format used for node and edge labels. * @param result where the number of exported trees and debug data is updated */ - public static void toLineGraphFormat(final PatchDiff patch, final StringBuilder lineGraph, final LineGraphExportOptions options, AnalysisResult result) { + public static void toLineGraphFormat(final PatchDiff patch, final LineGraphExportOptions options, OutputStream destination, AnalysisResult result) throws IOException { if (patch.isValid()) { //Logger.info(" Exporting DiffTree #{}", treeCounter); - final Pair patchLg; - patchLg = toLineGraphFormat(patch.getDiffTree(), options); - result.debugData.append(patchLg.first()); - composeTreeInLineGraph(lineGraph, patch, patchLg.second(), options); + //Logger.info(" Exporting DiffTree #{}", treeCounter); + destination.write(lineGraphHeader(patch, options).getBytes()); + result.debugData.append(toLineGraphFormat(patch.getDiffTree(), options, destination)); + destination.write(lineGraphFooter().getBytes()); + ++result.exportedTrees; } else { Logger.debug(" Skipping invalid patch for file {} at commit {}", patch.getFileName(), patch.getCommitHash()); @@ -123,15 +121,14 @@ public static void toLineGraphFormat(final PatchDiff patch, final StringBuilder * Then appends the already created file content for nodes and edges. * @param lineGraph The string builder to write the result to. * @param source The {@link DiffTreeSource} that describes where the DiffTree whose content is written to the file originated from. - * @param nodesAndEdges Result from {@link #toLineGraphFormat(DiffTree, LineGraphExportOptions)}. Holds all nodes and edges in linegraph format, separated by a newline each. + * @param nodesAndEdges Result from {@link #toLineGraphFormat(DiffTree, LineGraphExportOptions, OutputStream)}. Holds all nodes and edges in linegraph format, separated by a newline each. * @param options {@link LineGraphExportOptions} used to determine the treeFormat for the header. */ - public static void composeTreeInLineGraph(final StringBuilder lineGraph, final DiffTreeSource source, final String nodesAndEdges, final LineGraphExportOptions options) { - lineGraph - .append(options.treeFormat().toLineGraphLine(source)) // print "t # $LABEL" - .append(StringUtils.LINEBREAK) - .append(nodesAndEdges) - .append(StringUtils.LINEBREAK) - .append(StringUtils.LINEBREAK); + private static String lineGraphHeader(final DiffTreeSource source, final LineGraphExportOptions options) { + return options.treeFormat().toLineGraphLine(source) + StringUtils.LINEBREAK; + } + + private static String lineGraphFooter() { + return StringUtils.LINEBREAK + StringUtils.LINEBREAK; } } diff --git a/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java b/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java index d4739ee3d..3fb6e9b28 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java +++ b/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java @@ -58,44 +58,41 @@ public AnalysisResult call() throws Exception { * (e.g., match more than one edit class) and export them to the destination * determined by the AnalysisStrategy. */ + int numDiffTrees = 0; final CommitDiff commitDiff = commitDiffResult.diff().get(); - final StringBuilder lineGraph = new StringBuilder(); + try (var lineGraphDestination = options.analysisStrategy().onCommit(commitDiff)) { + for (final PatchDiff patch : commitDiff.getPatchDiffs()) { + final PatchStatistics thisPatchesStatistics = new PatchStatistics(patch, ProposedEditClasses.Instance); - // Count edit classes - int numDiffTrees = 0; - for (final PatchDiff patch : commitDiff.getPatchDiffs()) { - final PatchStatistics thisPatchesStatistics = new PatchStatistics(patch, ProposedEditClasses.Instance); + if (patch.isValid()) { + final DiffTree t = patch.getDiffTree(); + DiffTreeTransformer.apply(options.treePreProcessing(), t); + t.assertConsistency(); - if (patch.isValid()) { - final DiffTree t = patch.getDiffTree(); - DiffTreeTransformer.apply(options.treePreProcessing(), t); - t.assertConsistency(); + if (!options.treeFilter().test(t)) { + continue; + } - if (!options.treeFilter().test(t)) { - continue; - } + LineGraphExport.toLineGraphFormat(patch, exportOptions, lineGraphDestination, miningResult); - LineGraphExport.toLineGraphFormat(patch, lineGraph, exportOptions, miningResult); + t.forAll(node -> { + if (node.isArtifact()) { + final EditClass editClass = ProposedEditClasses.Instance.match(node); + miningResult.editClassCounts.reportOccurrenceFor( + editClass, + commitDiff + ); + thisPatchesStatistics.editClassCount().increment(editClass); + } + }); - t.forAll(node -> { - if (node.isArtifact()) { - final EditClass editClass = ProposedEditClasses.Instance.match(node); - miningResult.editClassCounts.reportOccurrenceFor( - editClass, - commitDiff - ); - thisPatchesStatistics.editClassCount().increment(editClass); - } - }); + ++numDiffTrees; + } - ++numDiffTrees; + patchStatistics.add(thisPatchesStatistics); } - - patchStatistics.add(thisPatchesStatistics); } - options.analysisStrategy().onCommit(commitDiff, lineGraph.toString()); - miningResult.exportedCommits += 1; miningResult.exportedTrees += numDiffTrees; miningResult.filterHits.append(new ExplainedFilterSummary(options.treeFilter())); diff --git a/src/main/java/org/variantsync/diffdetective/mining/postprocessing/MiningPostprocessing.java b/src/main/java/org/variantsync/diffdetective/mining/postprocessing/MiningPostprocessing.java index 1ad3c512e..ee3a7e646 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/postprocessing/MiningPostprocessing.java +++ b/src/main/java/org/variantsync/diffdetective/mining/postprocessing/MiningPostprocessing.java @@ -1,6 +1,6 @@ package org.variantsync.diffdetective.mining.postprocessing; -import org.variantsync.diffdetective.analysis.AnalysisResult; +import org.tinylog.Logger; import org.variantsync.diffdetective.diff.difftree.DiffTree; import org.variantsync.diffdetective.diff.difftree.render.DiffTreeRenderer; import org.variantsync.diffdetective.diff.difftree.render.RenderOptions; @@ -9,7 +9,6 @@ import org.variantsync.diffdetective.mining.DiffTreeMiner; import org.variantsync.diffdetective.util.FileUtils; import org.variantsync.diffdetective.util.IO; -import org.variantsync.functjonal.Pair; import java.io.IOException; import java.io.UncheckedIOException; @@ -137,8 +136,13 @@ public static void postprocessAndInterpretResults( ++patternNo; } } else { - final Pair lineGraph = LineGraphExport.toLineGraphFormat(semanticPatterns, EXPORT_OPTIONS); - IO.tryWrite(outputDir.resolve("candidates.lg"), lineGraph.second()); + Path destinationPath = outputDir.resolve("candidates.lg"); + + try (var destination = IO.newBufferedOutputStream(destinationPath)) { + LineGraphExport.toLineGraphFormat(semanticPatterns, EXPORT_OPTIONS, destination); + } catch (IOException e) { + Logger.error(e); + } } } } diff --git a/src/main/java/org/variantsync/diffdetective/util/IO.java b/src/main/java/org/variantsync/diffdetective/util/IO.java index ff0f0ff84..a99509889 100644 --- a/src/main/java/org/variantsync/diffdetective/util/IO.java +++ b/src/main/java/org/variantsync/diffdetective/util/IO.java @@ -7,6 +7,7 @@ import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.OpenOption; import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.util.Optional; @@ -58,6 +59,24 @@ public static void exportCsv(String fileName, String[] headers, Object[]... obje writer.close(); } + /** + * Same as {@link Files#newOutputStream} but creates all parent directories of + * {@code file} and wraps the result in a {@link BuferedOutputStream}. + */ + public static BufferedOutputStream newBufferedOutputStream(Path file, OpenOption... openOptions) throws IOException { + if (file.getParent() != null) { + Files.createDirectories(file.getParent()); + } + + var outputStream = Files.newOutputStream(file, openOptions); + try { + return new BufferedOutputStream(outputStream); + } catch (Exception e) { + outputStream.close(); + throw e; + } + } + /** * Writes the given text to the given file. * Creates a new file and its parent directories if necessary. It assumes that no file exists diff --git a/src/main/java/org/variantsync/diffdetective/validation/EditClassValidationTask.java b/src/main/java/org/variantsync/diffdetective/validation/EditClassValidationTask.java index c7db75300..abf91c626 100644 --- a/src/main/java/org/variantsync/diffdetective/validation/EditClassValidationTask.java +++ b/src/main/java/org/variantsync/diffdetective/validation/EditClassValidationTask.java @@ -57,7 +57,7 @@ public AnalysisResult call() throws Exception { // extract the produced commit diff and inform the strategy final CommitDiff commitDiff = commitDiffResult.diff().get(); - options.analysisStrategy().onCommit(commitDiff, ""); + options.analysisStrategy().onCommit(commitDiff).close(); // Count edit class matches int numDiffTrees = 0; diff --git a/src/test/java/LineGraphTest.java b/src/test/java/LineGraphTest.java index 5db6ddc2d..6ee2d7cbb 100644 --- a/src/test/java/LineGraphTest.java +++ b/src/test/java/LineGraphTest.java @@ -1,24 +1,22 @@ +import org.apache.commons.io.IOUtils; +import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.tinylog.Logger; -import org.variantsync.diffdetective.diff.difftree.CommitDiffDiffTreeSource; import org.variantsync.diffdetective.diff.difftree.DiffTree; import org.variantsync.diffdetective.diff.difftree.serialize.*; import org.variantsync.diffdetective.diff.difftree.serialize.edgeformat.DefaultEdgeLabelFormat; import org.variantsync.diffdetective.diff.difftree.serialize.nodeformat.LabelOnlyDiffNodeFormat; import org.variantsync.diffdetective.diff.difftree.serialize.treeformat.CommitDiffDiffTreeLabelFormat; -import org.variantsync.diffdetective.util.FileUtils; +import org.variantsync.diffdetective.util.IO; import java.io.BufferedReader; import java.io.IOException; -import java.io.StringReader; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; -import java.util.Objects; -import static org.junit.Assert.assertEquals; /** * For testing the import of a line graph. */ @@ -52,8 +50,23 @@ public void idempotentReadWrite() throws IOException { diffTrees = LineGraphImport.fromLineGraph(lineGraph, testFile, IMPORT_OPTIONS); } assertConsistencyForAll(diffTrees); - final String lineGraphResult = exportDiffTreeToLineGraph(diffTrees); - TestUtils.assertEqualToFile(testFile, lineGraphResult); + + Path actualPath = testFile.getParent().resolve(testFile.getFileName().toString() + ".actual"); + try (var output = IO.newBufferedOutputStream(actualPath)) { + LineGraphExport.toLineGraphFormat(diffTrees, EXPORT_OPTIONS, output); + } + + try ( + var expectedFile = Files.newBufferedReader(testFile); + var actualFile = Files.newBufferedReader(actualPath); + ) { + if (!IOUtils.contentEqualsIgnoreEOL(expectedFile, actualFile)) { + Assert.fail("The file " + testFile + " couldn't be exported or imported without modifications"); + } else { + // Only keep output file on errors + Files.delete(actualPath); + } + } } } @@ -68,20 +81,4 @@ private static void assertConsistencyForAll(final List treeList) { // } treeList.forEach(DiffTree::assertConsistency); } - - /** - * Exports computed trees to line graph. - * - * @param treeList A list of {@link DiffTree DiffTrees} - * @return The computed line graph - */ - private static String exportDiffTreeToLineGraph(final List treeList) { - final StringBuilder lineGraphOutput = new StringBuilder(); - for (var tree : treeList) { - if (tree.getSource() instanceof CommitDiffDiffTreeSource source) { - LineGraphExport.composeTreeInLineGraph(lineGraphOutput, source, Objects.requireNonNull(LineGraphExport.toLineGraphFormat(tree, EXPORT_OPTIONS)).second(), EXPORT_OPTIONS); - } else throw new RuntimeException("The DiffTreeSoruce of DiffTree " + tree + " is not a CommitDiffDiffTreeSource: " + tree.getSource()); - } - return lineGraphOutput.toString(); - } } diff --git a/src/test/java/MarlinDebug.java b/src/test/java/MarlinDebug.java index 7ccd3f085..3c99fa735 100644 --- a/src/test/java/MarlinDebug.java +++ b/src/test/java/MarlinDebug.java @@ -17,7 +17,6 @@ import org.variantsync.diffdetective.diff.difftree.DiffTree; import org.variantsync.diffdetective.diff.difftree.parse.DiffTreeParser; import org.variantsync.diffdetective.diff.difftree.parse.IllFormedAnnotationException; -import org.variantsync.diffdetective.diff.difftree.serialize.LineGraphExport; import org.variantsync.diffdetective.diff.difftree.transform.DiffTreeTransformer; import org.variantsync.diffdetective.feature.CPPAnnotationParser; import org.variantsync.diffdetective.mining.DiffTreeMiner; @@ -122,9 +121,6 @@ public static void testCommit(final RepoInspection repoInspection, final String Logger.info(" End processing {}", patch); } } - - StringBuilder bigB = new StringBuilder(); - LineGraphExport.toLineGraphFormat(commitDiff, bigB, DiffTreeMiner.MiningExportOptions(repoInspection.repo)); } public static void asMiningTask(final RepoInspection repoInspection, final String commitHash) throws Exception { diff --git a/src/test/java/TestMultiLineMacros.java b/src/test/java/TestMultiLineMacros.java index e2ab633b7..b8941829a 100644 --- a/src/test/java/TestMultiLineMacros.java +++ b/src/test/java/TestMultiLineMacros.java @@ -13,7 +13,6 @@ import org.variantsync.diffdetective.diff.difftree.serialize.treeformat.CommitDiffDiffTreeLabelFormat; import org.variantsync.diffdetective.util.IO; import org.variantsync.diffdetective.util.StringUtils; -import org.variantsync.functjonal.Pair; import java.io.BufferedReader; import java.io.IOException; @@ -33,18 +32,17 @@ public void diffToDiffTree(LineGraphExportOptions exportOptions, Path p) throws DiffNodeParser.Default).unwrap().getSuccess(); } - final Pair result = LineGraphExport.toLineGraphFormat(tree, exportOptions); - Assert.assertNotNull(result); - final DiffTreeSerializeDebugData debugData = result.first(); - Logger.info("Parsed {} nodes of diff type NON.", debugData.numExportedNonNodes); - Logger.info("Parsed {} nodes of diff type ADD.", debugData.numExportedAddNodes); - Logger.info("Parsed {} nodes of diff type REM.", debugData.numExportedRemNodes); + try (var destination = IO.newBufferedOutputStream(resDir.resolve("gen").resolve(p.getFileName() + ".lg"))) { + destination.write(("t # 1" + StringUtils.LINEBREAK).getBytes()); - final String lg = "t # 1" + - StringUtils.LINEBREAK + - result.second(); - IO.write(resDir.resolve("gen").resolve(p.getFileName() + ".lg"), lg); + final DiffTreeSerializeDebugData debugData = LineGraphExport.toLineGraphFormat(tree, exportOptions, destination); + Assert.assertNotNull(debugData); + Logger.info("Parsed {} nodes of diff type NON.", debugData.numExportedNonNodes); + Logger.info("Parsed {} nodes of diff type ADD.", debugData.numExportedAddNodes); + Logger.info("Parsed {} nodes of diff type REM.", debugData.numExportedRemNodes); + + } } @Test From c29a9e493238d924d2cefe9ada9fb98d60615e33 Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Thu, 29 Sep 2022 19:52:28 +0200 Subject: [PATCH 4/9] Factor out directory creation to a utility function --- .../difftree/render/DiffTreeRenderer.java | 1 - .../variantsync/diffdetective/util/IO.java | 21 +++++++++++-------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/render/DiffTreeRenderer.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/render/DiffTreeRenderer.java index 203c32b3f..7dc8011be 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/render/DiffTreeRenderer.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/render/DiffTreeRenderer.java @@ -15,7 +15,6 @@ import org.variantsync.diffdetective.util.Assert; import org.variantsync.diffdetective.util.IO; import org.variantsync.diffdetective.util.StringUtils; -import org.variantsync.functjonal.Pair; import java.io.IOException; import java.nio.file.Files; diff --git a/src/main/java/org/variantsync/diffdetective/util/IO.java b/src/main/java/org/variantsync/diffdetective/util/IO.java index a99509889..a6485711c 100644 --- a/src/main/java/org/variantsync/diffdetective/util/IO.java +++ b/src/main/java/org/variantsync/diffdetective/util/IO.java @@ -60,13 +60,20 @@ public static void exportCsv(String fileName, String[] headers, Object[]... obje } /** - * Same as {@link Files#newOutputStream} but creates all parent directories of - * {@code file} and wraps the result in a {@link BuferedOutputStream}. + * Creates all parent directories of {@code file}. */ - public static BufferedOutputStream newBufferedOutputStream(Path file, OpenOption... openOptions) throws IOException { + public static void createParentDirectories(Path file) throws IOException { if (file.getParent() != null) { Files.createDirectories(file.getParent()); } + } + + /** + * Same as {@link Files#newOutputStream} but creates all parent directories of + * {@code file} and wraps the result in a {@link BuferedOutputStream}. + */ + public static BufferedOutputStream newBufferedOutputStream(Path file, OpenOption... openOptions) throws IOException { + createParentDirectories(file); var outputStream = Files.newOutputStream(file, openOptions); try { @@ -88,9 +95,7 @@ public static BufferedOutputStream newBufferedOutputStream(Path file, OpenOption * the file, or the text cannot be encoded using UTF-8 */ public static void write(final Path p, final String text) throws IOException { - if (p.getParent() != null) { - Files.createDirectories(p.getParent()); - } + createParentDirectories(p); Files.writeString(p, text, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); } @@ -105,9 +110,7 @@ public static void write(final Path p, final String text) throws IOException { * cannot be encoded using UTF-8 */ public static void append(final Path p, final String text) throws IOException { - if (p.getParent() != null) { - Files.createDirectories(p.getParent()); - } + createParentDirectories(p); Files.writeString(p, text, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.APPEND); } From ebe773898a022bf773790b12ac33fe9a6a5c1775 Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Thu, 29 Sep 2022 19:58:16 +0200 Subject: [PATCH 5/9] Reuse `AnalyzeAndExportIncrementally` for `AnalyzeAllThenExport` --- .../strategies/AnalyzeAllThenExport.java | 34 ++----------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAllThenExport.java b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAllThenExport.java index d2868057b..369ac00d1 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAllThenExport.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAllThenExport.java @@ -1,39 +1,11 @@ package org.variantsync.diffdetective.analysis.strategies; -import org.apache.commons.io.output.CloseShieldOutputStream; -import org.tinylog.Logger; -import org.variantsync.diffdetective.datasets.Repository; -import org.variantsync.diffdetective.diff.CommitDiff; -import org.variantsync.diffdetective.util.IO; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.file.Path; - /** * Collects all linegraph representations generated by an analysis and exports them at the end. * @author Paul Bittner */ -public class AnalyzeAllThenExport extends AnalysisStrategy { - private ByteArrayOutputStream lineGraphDestination; - - @Override - public void start(Repository repo, Path outputPath) { - super.start(repo, outputPath); - } - - @Override - public OutputStream onCommit(CommitDiff commit) { - return new CloseShieldOutputStream(lineGraphDestination); - } - - @Override - public void end() { - try (var finalDestination = IO.newBufferedOutputStream(outputPath)) { - lineGraphDestination.writeTo(finalDestination); - } catch (IOException e) { - Logger.error(e); - } +public class AnalyzeAllThenExport extends AnalyzeAndExportIncrementally { + public AnalyzeAllThenExport() { + super(Integer.MAX_VALUE); } } From 4eebf7974de4cb9924559c0784b290e6bc084776 Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Sun, 9 Oct 2022 09:59:40 +0200 Subject: [PATCH 6/9] Signal failure when exiting because of an error --- .../diffdetective/analysis/CommitHistoryAnalysisTask.java | 4 ++-- .../variantsync/diffdetective/analysis/HistoryAnalysis.java | 2 +- .../diff/difftree/serialize/LineGraphExportOptions.java | 2 +- .../java/org/variantsync/diffdetective/metadata/Metadata.java | 2 +- .../diffdetective/tablegen/MiningResultAccumulator.java | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/variantsync/diffdetective/analysis/CommitHistoryAnalysisTask.java b/src/main/java/org/variantsync/diffdetective/analysis/CommitHistoryAnalysisTask.java index 7bc86c676..8df76b339 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/CommitHistoryAnalysisTask.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/CommitHistoryAnalysisTask.java @@ -86,7 +86,7 @@ public static void exportCommitTimes(final List commitTimes, IO.write(pathToOutputFile, times.toString()); } catch (IOException e) { Logger.error(e); - System.exit(0); + System.exit(1); } } @@ -102,7 +102,7 @@ public static void exportPatchStatistics(final List commitTimes IO.write(pathToOutputFile, csv); } catch (IOException e) { Logger.error(e); - System.exit(0); + System.exit(1); } } } diff --git a/src/main/java/org/variantsync/diffdetective/analysis/HistoryAnalysis.java b/src/main/java/org/variantsync/diffdetective/analysis/HistoryAnalysis.java index 92b7018c5..db844520b 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/HistoryAnalysis.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/HistoryAnalysis.java @@ -150,7 +150,7 @@ public static void analyzeAsync( } } catch (Exception e) { Logger.error(e, "Failed to run all mining task"); - System.exit(0); + System.exit(1); } final double runtime = clock.getPassedSeconds(); diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExportOptions.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExportOptions.java index edba32dc7..3af617805 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExportOptions.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExportOptions.java @@ -77,6 +77,6 @@ public static BiConsumer RenderError() { * Default value for {@link #onError} that exits the program immediately upon an error with {@link System#exit(int)}. */ public static BiConsumer SysExitOnError() { - return (p, e) -> System.exit(0); + return (p, e) -> System.exit(1); } } diff --git a/src/main/java/org/variantsync/diffdetective/metadata/Metadata.java b/src/main/java/org/variantsync/diffdetective/metadata/Metadata.java index f467dfe1a..5eb7cb199 100644 --- a/src/main/java/org/variantsync/diffdetective/metadata/Metadata.java +++ b/src/main/java/org/variantsync/diffdetective/metadata/Metadata.java @@ -75,7 +75,7 @@ default String exportTo(final Path file) { return result; } catch (IOException e) { Logger.error(e); - System.exit(0); + System.exit(1); return ""; } } diff --git a/src/main/java/org/variantsync/diffdetective/tablegen/MiningResultAccumulator.java b/src/main/java/org/variantsync/diffdetective/tablegen/MiningResultAccumulator.java index 1012d9e80..015b3c6e7 100644 --- a/src/main/java/org/variantsync/diffdetective/tablegen/MiningResultAccumulator.java +++ b/src/main/java/org/variantsync/diffdetective/tablegen/MiningResultAccumulator.java @@ -143,7 +143,7 @@ public static void main(final String[] args) throws IOException, ParseException automationResult = FindMedianCommitTime.getResultOfDirectory(automationResultDir); } catch (IOException e) { Logger.error("Could not load automation results for dataset {} in {}", dataset.name(), automationResultDir); - System.exit(0); + System.exit(1); return null; } From 1761bce0b05feaf700cfee7b9691bda3a6ad3e21 Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Fri, 30 Sep 2022 00:30:01 +0200 Subject: [PATCH 7/9] Create an export strategy using the default Java buffering --- .../strategies/AnalyzeAllAndExport.java | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAllAndExport.java diff --git a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAllAndExport.java b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAllAndExport.java new file mode 100644 index 000000000..c0c5df437 --- /dev/null +++ b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAllAndExport.java @@ -0,0 +1,48 @@ +package org.variantsync.diffdetective.analysis.strategies; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Path; + +import org.apache.commons.io.output.CloseShieldOutputStream; +import org.tinylog.Logger; +import org.variantsync.diffdetective.datasets.Repository; +import org.variantsync.diffdetective.diff.CommitDiff; +import org.variantsync.diffdetective.util.IO; + +/** + * Exports all linegraph representations generated by an analysis directly to a file. + * The file operations are buffered by Java, so it flushes them when it thinks there are enough of + * them. In contrast to `AnalyzeAndExportIncrementally` this relies on the sanity of the Java + * defaults + * + * @author Benjamin Moosherr + */ +public class AnalyzeAllAndExport extends AnalysisStrategy { + private OutputStream lineGraphDestination; + + @Override + public void start(Repository repo, Path outputPath) { + try { + lineGraphDestination = IO.newBufferedOutputStream(outputPath); + } catch (IOException e) { + Logger.error(e); + } + } + + @Override + public OutputStream onCommit(CommitDiff commit) { + // lineGraphDestination is reused for all commits. CloseShieldOutputStream ensures that it + // isn't closed after processing this commit. + return new CloseShieldOutputStream(lineGraphDestination); + } + + @Override + public void end() { + try { + lineGraphDestination.close(); + } catch (IOException e) { + Logger.error(e); + } + } +} From d29f9e423a28c1347fd995fd60d2997510024ef2 Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Mon, 17 Oct 2022 11:43:40 +0200 Subject: [PATCH 8/9] Deprecate the MarlinDebug test This test needs manual inspection of the results. --- src/test/java/MarlinDebug.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/MarlinDebug.java b/src/test/java/MarlinDebug.java index 3c99fa735..4936e4619 100644 --- a/src/test/java/MarlinDebug.java +++ b/src/test/java/MarlinDebug.java @@ -29,6 +29,7 @@ import java.nio.file.Paths; import java.util.List; +@Deprecated public class MarlinDebug { private record RepoInspection( List suspiciousCommits, From 1a980165e13d6e009342e56af7e99876da950963 Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Mon, 17 Oct 2022 11:45:58 +0200 Subject: [PATCH 9/9] Compose AnalysisResult instead of mutating it as parameter --- .../diff/difftree/serialize/LineGraphExport.java | 8 ++++++-- .../org/variantsync/diffdetective/mining/MiningTask.java | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java index e7ee874a7..38a8cc7cb 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java @@ -81,7 +81,7 @@ public static AnalysisResult toLineGraphFormat(final String repoName, final Comm for (final PatchDiff patchDiff : commitDiff.getPatchDiffs()) { try { - toLineGraphFormat(patchDiff, options, destination, result); + result.append(toLineGraphFormat(repoName, patchDiff, options, destination)); } catch (Exception e) { options.onError().accept(patchDiff, e); break; @@ -100,7 +100,9 @@ public static AnalysisResult toLineGraphFormat(final String repoName, final Comm * @param options Configuration options for the export, such as the format used for node and edge labels. * @param result where the number of exported trees and debug data is updated */ - public static void toLineGraphFormat(final PatchDiff patch, final LineGraphExportOptions options, OutputStream destination, AnalysisResult result) throws IOException { + public static AnalysisResult toLineGraphFormat(final String repoName, final PatchDiff patch, final LineGraphExportOptions options, OutputStream destination) throws IOException { + final AnalysisResult result = new AnalysisResult(repoName); + if (patch.isValid()) { //Logger.info(" Exporting DiffTree #{}", treeCounter); @@ -113,6 +115,8 @@ public static void toLineGraphFormat(final PatchDiff patch, final LineGraphExpor } else { Logger.debug(" Skipping invalid patch for file {} at commit {}", patch.getFileName(), patch.getCommitHash()); } + + return result; } /** diff --git a/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java b/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java index 3fb6e9b28..81e48c3ba 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java +++ b/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java @@ -73,7 +73,7 @@ public AnalysisResult call() throws Exception { continue; } - LineGraphExport.toLineGraphFormat(patch, exportOptions, lineGraphDestination, miningResult); + miningResult.append(LineGraphExport.toLineGraphFormat(miningResult.repoName, patch, exportOptions, lineGraphDestination)); t.forAll(node -> { if (node.isArtifact()) {