2424
2525import static org .variantsync .diffdetective .util .fide .FormulaUtils .negate ;
2626
27+ /**
28+ * Implementation of the feasibility study from Section 6 of our paper
29+ * Views on Edits to Variational Software
30+ * at SPLC'23.
31+ * This Analysis is run on a batch of commits of a single repository.
32+ * For the whole feasibility study, multiple analysis are run in parallel, each
33+ * processing a part of a repositories history.
34+ */
2735public class ViewAnalysis implements Analysis .Hooks {
28- // Result data
36+ /**
37+ * File extension for csv files created by this analysis.
38+ */
2939 public static final String VIEW_CSV_EXTENSION = ".views.csv" ;
40+ /**
41+ * StringBuilder that is used to iteratively create a csv file with this analysis' results.
42+ */
3043 private StringBuilder csv ;
44+ /**
45+ * Random instance to generate random numbers.
46+ * Used to generate random relevance predicates.
47+ */
3148 private Random random ;
3249
3350 @ Override
@@ -40,6 +57,18 @@ public void initializeResults(Analysis analysis) {
4057 csv .append (ViewEvaluation .makeHeader (CSV .DEFAULT_CSV_DELIMITER )).append (StringUtils .LINEBREAK );
4158 }
4259
60+ /**
61+ * Benchmark for view generation on the given variation diff with the given relevance.
62+ * This method generates a view once with each algorithm:
63+ * - once with the {@link DiffView#naive(DiffTree, Relevance) naive algorithm} view_naive (Equation 8 from our paper),
64+ * - and once with the {@link DiffView#optimized(DiffTree, Relevance) optimized algorithm} view_smart (Equation 10 in our paper).
65+ * This method measures both algorithms runtimes and stores the runtimes and metadata in terms of a
66+ * {@link ViewEvaluation} in this objects {@link #csv} field.
67+ * @param analysis The current instance of the analysis that is run.
68+ * Used to access metadata of the current commit that is processed.
69+ * @param d The variation diff to benchmark view generation on.
70+ * @param rho A relevance predicate that determines which nodes should be contained in the view.
71+ */
4372 private void runRelevanceExperiment (Analysis analysis , final DiffTree d , final Relevance rho ) {
4473 final long preprocessingTime , naiveTime , optimizedTime ;
4574
@@ -84,6 +113,16 @@ private void runRelevanceExperiment(Analysis analysis, final DiffTree d, final R
84113// return Analysis.Hooks.super.onParsedCommit(analysis);
85114// }
86115
116+ /**
117+ * Runs the feasibility study on the current variation diff.
118+ * Creates random relevance predicates as explained in Section 6 of our paper.
119+ * Then runs {@link #runRelevanceExperiment(Analysis, DiffTree, Relevance)} for each relevance on the
120+ * current variation diff.
121+ * @param analysis The current instance of the analysis that is run.
122+ * Used to access metadata of the current commit that is processed.
123+ * @return {@link Analysis.Hooks#analyzeDiffTree(Analysis)}
124+ * @throws Exception
125+ */
87126 @ Override
88127 public boolean analyzeDiffTree (Analysis analysis ) throws Exception {
89128 final DiffTree d = analysis .getCurrentDiffTree ();
@@ -96,6 +135,14 @@ public boolean analyzeDiffTree(Analysis analysis) throws Exception {
96135 return Analysis .Hooks .super .analyzeDiffTree (analysis );
97136 }
98137
138+ /**
139+ * Generates random relevance predicates for creating random views on
140+ * the given variation diff d, as explained in Section 6.1 in our paper.
141+ * If possible, this method will generate one relevance of each type of
142+ * {@link Configure}, {@link Trace}, and {@link Search}.
143+ * @param d The variation diff to generate relevance predicates for.
144+ * @return A list of three random relevance predicates.
145+ */
99146 private List <Relevance > generateRandomRelevances (final DiffTree d ) {
100147 final List <Node > deselectedPCs = new ArrayList <>();
101148 final Set <String > features = new HashSet <>();
@@ -133,7 +180,20 @@ else if (a.isConditionalAnnotation()) {
133180
134181 return relevances ;
135182 }
136-
183+
184+ /**
185+ * This is a convenience method for creating a random relevance predicate from a collection of
186+ * potential parameterisations.
187+ * <p>
188+ * If the given collection {@code source} of parameters for relevance predicates is not empty, this method
189+ * picks a random parameterization and creates a relevance predicate from it.
190+ * The created predicate is added to the given target collection.
191+ * @param source A potentially empty collection of arguments for relevance predicates.
192+ * @param pick A function that picks a parameterisation at random and creates a relevance predicate from it.
193+ * @param target A collection to which the randomly created relevance predicate will be added to.
194+ * @param <RelevanceParams> The type of the parameters for the relevance predicates.
195+ * @param <RelevanceCandidates> The type of collection of the parameters.
196+ */
137197 private static <RelevanceParams , RelevanceCandidates extends Collection <RelevanceParams >> void addRandomRelevance (
138198 RelevanceCandidates source ,
139199 Function <RelevanceCandidates , Relevance > pick ,
@@ -147,6 +207,17 @@ private static <RelevanceParams, RelevanceCandidates extends Collection<Relevanc
147207 }
148208 }
149209
210+ /**
211+ * This is a convenience method for creating relevance predicates from their parameters.
212+ * <p>
213+ * If the given collection of parameters for relevance predicates is not empty, this method
214+ * generates corresponding relevance predicates for all those predicates and adds them to the given target collection.
215+ * @param source A potentially empty collection of arguments for relevance predicates.
216+ * @param prepare A function that creates a relevance predicate from suitable arguments.
217+ * @param target A collection to which all relevance predicates will be added to.
218+ * @param <RelevanceParams> The type of the parameters for the relevance predicates.
219+ * @param <RelevanceCandidates> The type of collection of the parameters.
220+ */
150221 private static <RelevanceParams , RelevanceCandidates extends Collection <? extends RelevanceParams >> void addAll (
151222 RelevanceCandidates source ,
152223 Function <? super RelevanceCandidates , ? extends Collection <? extends Relevance >> prepare ,
@@ -157,6 +228,14 @@ private static <RelevanceParams, RelevanceCandidates extends Collection<? extend
157228 }
158229 }
159230
231+ /**
232+ * Generates all {@link Configure} relevance predicates that can be generated from the given list of
233+ * deselected presence conditions.
234+ * The returned list of predicates is complete: For every (partial) variant of the variation tree or diff the
235+ * deselected presence conditions come from, a corresponding relevance predicate is within the returned list.
236+ * @param deselectedPCs A list of negations of all presence conditions that occur in a variation tree or diff.
237+ * @return A complete list of {@link Configure} predicates.
238+ */
160239 private List <Configure > allConfigureRelevances (final List <Node > deselectedPCs ) {
161240 /*
162241 * Select a random satisfiable configuration (i.e., a non-false config).
@@ -174,7 +253,15 @@ private List<Configure> allConfigureRelevances(final List<Node> deselectedPCs) {
174253
175254 return all ;
176255 }
177-
256+
257+ /**
258+ * Creates a random {@link Configure} relevance predicate from the given list of
259+ * deselected presence conditions.
260+ * This method picks a random satisfiable formula from the given list and returns it as a relevance predicate
261+ * for configuration.
262+ * @return A random, satisfiable {@link Configure} predicate, created from the given presence conditions.
263+ * Null if the given list is empty or if it does not contain a satisfiable formula.
264+ */
178265 private Configure randomConfigure (final List <Node > deselectedPCs ) {
179266 /*
180267 Do we need this?
@@ -209,11 +296,21 @@ private Configure randomConfigure(final List<Node> deselectedPCs) {
209296
210297 return new Configure (winner );
211298 }
212-
299+
300+ /**
301+ * Generates a {@link Trace} relevance predicate for each feature in the given set of feature names.
302+ * @param features A set of feature names to trace.
303+ * @return A {@link Trace} predicate for each feature name in the given set.
304+ */
213305 private List <Trace > allTraceRelevances (final Set <String > features ) {
214306 return features .stream ().map (Trace ::new ).toList ();
215307 }
216308
309+ /**
310+ * Creates a random {@link Trace} relevance predicate from the given set of feature names.
311+ * @param features A set of feature names.
312+ * @return A {@link Trace} predicate for a feature name randomly picked from the given set.
313+ */
217314 private Trace randomTrace (final Set <String > features ) {
218315 /*
219316 Pick a random feature for our relevance.
@@ -223,10 +320,20 @@ private Trace randomTrace(final Set<String> features) {
223320 return new Trace (CollectionUtils .getRandomElement (random , features ));
224321 }
225322
323+ /**
324+ * Generates a {@link Search} relevance predicate for each artifact in the given set.
325+ * @param artifacts A list of text-based artifacts.
326+ * @return A {@link Search} predicate for each artifact.
327+ */
226328 private List <Search > allSearchRelevances (final Set <String > artifacts ) {
227329 return artifacts .stream ().map (Search ::new ).toList ();
228330 }
229331
332+ /**
333+ * Creates a random {@link Search} relevance predicate from the given set of artifacts.
334+ * @param artifacts A set of text-based artifacts (e.g., lines of code).
335+ * @return A {@link Search} predicate for an artifact randomly picked from the given set.
336+ */
230337 private Search randomSearch (final Set <String > artifacts ) {
231338 /*
232339 Pick a random artifact for our relevance.
@@ -236,6 +343,11 @@ private Search randomSearch(final Set<String> artifacts) {
236343 return new Search (CollectionUtils .getRandomElement (random , artifacts ));
237344 }
238345
346+ /**
347+ * Writes the results of this analysis to disk as CSV file.
348+ * @param analysis The current state of the analysis.
349+ * @throws IOException When the file cannot be created or written.
350+ */
239351 @ Override
240352 public void endBatch (Analysis analysis ) throws IOException {
241353 IO .write (
0 commit comments