diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/build.properties b/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/build.properties deleted file mode 100644 index fc2472710..000000000 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/build.properties +++ /dev/null @@ -1,17 +0,0 @@ -############################################################################### -# Copyright (c) 2022 École Polytechnique de Montréal -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License 2.0 -# which accompanies this distribution, and is available at -# https://www.eclipse.org/legal/epl-2.0 -# -# SPDX-License-Identifier: EPL-2.0 -############################################################################### - -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - about.html,\ - plugin.properties diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/plugin.properties b/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/plugin.properties deleted file mode 100644 index b310b75e9..000000000 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/plugin.properties +++ /dev/null @@ -1,13 +0,0 @@ -############################################################################### -# Copyright (c) 2022 École Polytechnique de Montréal -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License 2.0 -# which accompanies this distribution, and is available at -# https://www.eclipse.org/legal/epl-2.0 -# -# SPDX-License-Identifier: EPL-2.0 -############################################################################### - -Bundle-Vendor = Eclipse Trace Compass Incubator -Bundle-Name = Trace Compass Incubator ExecutionComparision Core Tests Plug-in diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/plugin.xml b/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/plugin.xml deleted file mode 100644 index 91e1c76fc..000000000 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/plugin.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/ParametricWeightedTreeUtils.java b/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/ParametricWeightedTreeUtils.java deleted file mode 100644 index 1170e8bd1..000000000 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/ParametricWeightedTreeUtils.java +++ /dev/null @@ -1,252 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2024 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License 2.0 which - * accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package org.eclipse.tracecompass.incubator.internal.executioncomparison.core; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.tracecompass.analysis.profiling.core.base.ICallStackSymbol; -import org.eclipse.tracecompass.analysis.profiling.core.callgraph.ICallGraphProvider2; -import org.eclipse.tracecompass.analysis.profiling.core.tree.ITree; -import org.eclipse.tracecompass.analysis.profiling.core.tree.IWeightedTreeSet; -import org.eclipse.tracecompass.analysis.profiling.core.tree.WeightedTree; -import org.eclipse.tracecompass.incubator.analysis.core.weighted.tree.diff.DifferentialWeightedTree; -import org.eclipse.tracecompass.incubator.analysis.core.weighted.tree.diff.DifferentialWeightedTreeProvider; -import org.eclipse.tracecompass.incubator.analysis.core.weighted.tree.diff.DifferentialWeightedTreeSet; -import org.eclipse.tracecompass.incubator.analysis.core.weighted.tree.diff.WeightedTreeUtils; -import org.eclipse.tracecompass.internal.analysis.profiling.core.callgraph2.AggregatedCalledFunction; -import org.eclipse.tracecompass.tmf.core.util.Pair; - -import com.google.common.collect.ImmutableList; - -/** - * Utility methods to operate on {@link WeightedTree} objects - * - * @author Fateme Faraji Daneshgar - */ -@SuppressWarnings("restriction") -public final class ParametricWeightedTreeUtils { - - private ParametricWeightedTreeUtils() { - // Nothing to do - } - - /** - * Does the differential between 2 weighted trees, ie what happened in tree2 - * differently than in tree1. The base weight come from the second tree and - * the differential value will show the difference with the first tree. - * - * @param - * The type of element in the tree - * @param first - * The tree that will be differentiated. - * @param second - * The tree to use as the base - * @param statisticType - * it determine the statistic (duration or self time) that flame graph will represent - * @return The differential weighted tree - */ - public static <@NonNull T> Collection> diffTrees(Collection> first, Collection> second, @Nullable String statisticType) { - List> diffTrees = new ArrayList<>(); - double nullDiff = Double.NaN; - - for (WeightedTree base : second) { - T object = base.getObject(); - // Find the equivalent tree in the first collection - WeightedTree other = findObject(first, object); - double diffWeight; - DifferentialWeightedTree<@NonNull T> diffTree; - if (statisticType == null) { - diffWeight = other == null ? nullDiff : (double) (base.getWeight() - other.getWeight()) / other.getWeight(); - diffTree = new DifferentialWeightedTree<>(base, object, base.getWeight(), diffWeight); - - } else { - long baseWeight = 0; - long otherWeight = 0; - if (base instanceof AggregatedCalledFunction) { - switch(statisticType) { - case "Self Time": //$NON-NLS-1$ - { - baseWeight = ((AggregatedCalledFunction) base).getSelfTime(); - otherWeight = other == null ? 0 : ((AggregatedCalledFunction) other).getSelfTime(); - break; - } - case "Duration": //$NON-NLS-1$ - { - baseWeight = ((AggregatedCalledFunction) base).getWeight(); - otherWeight = other == null ? 0 : ((AggregatedCalledFunction) other).getWeight(); - break; - } - default: - break; - } - - } else { - baseWeight = base.getWeight(); - otherWeight = other == null ? 0 : other.getWeight(); - } - diffWeight = other == null ? nullDiff : (double) (baseWeight - otherWeight) / otherWeight; - diffTree = new DifferentialWeightedTree<>(base, object, base.getWeight(), diffWeight); - - } - diffTrees.add(diffTree); - - // Make the differential of the children - for (WeightedTree childTree : diffTrees(other == null ? Collections.emptyList() : other.getChildren(), base.getChildren(), statisticType)) { - diffTree.addChild(childTree); - } - } - return diffTrees; - } - - /** - * Does the differential between 2 weighted tree sets, ie for each - * comparable elements, what happened in tree set 2 differently than in tree - * set 1. The base weight come from the second tree set and the differential - * value will show the difference with the first tree. - *

- * Calling this method assumes the tree sets are comparable. It is the - * caller's responsibility to make sure the parameters make sense. If the 2 - * tree sets come from different {@link IWeightedTreeProvider}, they should - * be of similar types, otherwise, the comparison may not make sense. - *

- *

- * The elements of each tree set are paired as follows: - *

- *

- * 1- If there is only one element in each tree, they will be paired. - *

- *

- * 2- If the same elements are present in both tree sets, they will be - * paired, all other elements are ignored - *

- *

- * 3- If no elements are paired, they will be paired by name (and - * hierarchical names, if it applies). Unmatched elements will be ignored. - *

- *

- * If elements are not paired at this point, it will return - * null - *

- * - * @param provider - * The base provider of one of the trees, it will be used by the - * differential weighted tree provider to display the metrics and - * titles, etc.. It could be the provider of the second tree set, - * as it serves as the base values. - * @param first - * The first treeset to compare to - * @param second - * The second treeset to compare. - * @return A differential weighted tree provider wrapping the resulting tree - * set, or null if the 2 treesets have no elements in - * common - */ - public static @Nullable DifferentialWeightedTreeProvider diffTreeSets(ICallGraphProvider2 provider, - IWeightedTreeSet> first, - IWeightedTreeSet> second) { - Collection> pairedElements = pairElementsFromTrees(first, second); - if (pairedElements.isEmpty()) { - return null; - } - DifferentialWeightedTreeSet treeSet = new DifferentialWeightedTreeSet<>(); - for (Pair<@NonNull ?, @NonNull ?> pair : pairedElements) { - Collection> trees1 = first.getTreesFor(pair.getFirst()); - Collection> trees2 = second.getTreesFor(pair.getSecond()); - Collection> diffTrees = WeightedTreeUtils.diffTrees(trees1, trees2); - for (DifferentialWeightedTree tree : diffTrees) { - treeSet.addWeightedTree(pair.getFirst(), tree); - } - } - - return new DifferentialWeightedTreeProvider(provider, treeSet); - } - - private static <@NonNull N> Collection> pairElementsFromTrees(IWeightedTreeSet> first, IWeightedTreeSet> second) { - Collection<@NonNull ?> elements1 = first.getElements(); - Collection<@NonNull ?> elements2 = second.getElements(); - // If there is only one element and it is not a tree, pair it - if (elements1.size() == 1 && elements2.size() == 1) { - @NonNull - Object element1 = elements1.iterator().next(); - @NonNull - Object element2 = elements2.iterator().next(); - if (!(element1 instanceof ITree) && !(element2 instanceof ITree)) { - return ImmutableList.of(new Pair(element1, element2)); - } - } - - // Try to find equal elements in both trees - Collection> pairedElements = pairEqualElements(elements1, elements2); - if (!pairedElements.isEmpty()) { - return pairedElements; - } - - // Compare ITree elements by names - pairedElements = pairSameNameElements(elements1, elements2); - return pairedElements; - } - - private static Collection> pairEqualElements(Collection<@NonNull ?> elements1, Collection<@NonNull ?> elements2) { - List> pairedElements = new ArrayList<>(); - for (@NonNull - Object element1 : elements1) { - for (@NonNull - Object element2 : elements2) { - if (element1.equals(element2)) { - pairedElements.add(new Pair<>(element1, element1)); - if (element1 instanceof ITree && element2 instanceof ITree) { - pairedElements.addAll(pairEqualElements(((ITree) element1).getChildren(), ((ITree) element2).getChildren())); - } - break; - } - } - } - return pairedElements; - } - - private static Collection> pairSameNameElements(Collection<@NonNull ?> elements1, Collection elements2) { - List> pairedElements = new ArrayList<>(); - for (@NonNull - Object element1 : elements1) { - if (!(element1 instanceof ITree)) { - continue; - } - for (@NonNull - Object element2 : elements2) { - if (!(element2 instanceof ITree)) { - continue; - } - if (((ITree) element1).getName().equals(((ITree) element2).getName())) { - pairedElements.add(new Pair<>(element1, element2)); - pairedElements.addAll(pairSameNameElements(((ITree) element1).getChildren(), ((ITree) element2).getChildren())); - break; - } - } - } - return pairedElements; - } - - private static @Nullable <@NonNull T> WeightedTree findObject(Collection> tree, @NonNull T object) { - for (WeightedTree other : tree) { - if (other.getObject().equals(object)) { - return other; - } - } - return null; - } - -} \ No newline at end of file diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.classpath b/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.classpath deleted file mode 100644 index b8d064f66..000000000 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.classpath +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.gitignore b/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.gitignore deleted file mode 100644 index 750e145aa..000000000 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.gitignore +++ /dev/null @@ -1 +0,0 @@ -screenshots/ diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.project b/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.project deleted file mode 100644 index 347f85c2d..000000000 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.project +++ /dev/null @@ -1,34 +0,0 @@ - - - org.eclipse.tracecompass.incubator.executioncomparison.ui.swtbot.tests - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - org.eclipse.pde.api.tools.apiAnalysisBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - org.eclipse.pde.api.tools.apiAnalysisNature - - diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.settings/org.eclipse.jdt.core.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index bb4dd23d9..000000000 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,428 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.codeComplete.argumentPrefixes= -org.eclipse.jdt.core.codeComplete.argumentSuffixes= -org.eclipse.jdt.core.codeComplete.fieldPrefixes=f -org.eclipse.jdt.core.codeComplete.fieldSuffixes= -org.eclipse.jdt.core.codeComplete.localPrefixes= -org.eclipse.jdt.core.codeComplete.localSuffixes= -org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= -org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= -org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes= -org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes= -org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=enabled -org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore -org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull -org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault -org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable -org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.doc.comment.support=enabled -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=error -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=error -org.eclipse.jdt.core.compiler.problem.deadCode=error -org.eclipse.jdt.core.compiler.problem.deprecation=error -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=error -org.eclipse.jdt.core.compiler.problem.fallthroughCase=error -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=error -org.eclipse.jdt.core.compiler.problem.finalParameterBound=error -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=error -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=error -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=error -org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning -org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected -org.eclipse.jdt.core.compiler.problem.localVariableHiding=error -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error -org.eclipse.jdt.core.compiler.problem.missingDefaultCase=error -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=error -org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=enabled -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error -org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected -org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags -org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=error -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=error -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore -org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning -org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=warning -org.eclipse.jdt.core.compiler.problem.nullReference=error -org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error -org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error -org.eclipse.jdt.core.compiler.problem.parameterAssignment=error -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error -org.eclipse.jdt.core.compiler.problem.potentialNullReference=error -org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning -org.eclipse.jdt.core.compiler.problem.rawTypeReference=error -org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=error -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=error -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=error -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=error -org.eclipse.jdt.core.compiler.problem.unclosedCloseable=error -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=error -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=error -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=disabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=disabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedImport=error -org.eclipse.jdt.core.compiler.problem.unusedLabel=error -org.eclipse.jdt.core.compiler.problem.unusedLocal=error -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error -org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=error -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error -org.eclipse.jdt.core.compiler.source=1.8 -org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 -org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=true -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert -org.eclipse.jdt.core.formatter.comment.line_length=80 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=false -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=250 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=space -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=false -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true -org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.settings/org.eclipse.jdt.ui.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.settings/org.eclipse.jdt.ui.prefs deleted file mode 100644 index dbbef8b06..000000000 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.settings/org.eclipse.jdt.ui.prefs +++ /dev/null @@ -1,60 +0,0 @@ -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=_tmf-test-style -formatter_settings_version=12 -org.eclipse.jdt.ui.exception.name=e -org.eclipse.jdt.ui.gettersetter.use.is=true -org.eclipse.jdt.ui.keywordthis=false -org.eclipse.jdt.ui.overrideannotation=true -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=false -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=false -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.correct_indentation=false -sp_cleanup.format_source_code=false -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.make_local_variable_final=false -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=true -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=true -sp_cleanup.on_save_use_additional_actions=true -sp_cleanup.organize_imports=false -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=false -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_trailing_whitespaces=true -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=false -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=false -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_blocks=true -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=false -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.settings/org.eclipse.pde.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.settings/org.eclipse.pde.prefs deleted file mode 100644 index c367d4bd0..000000000 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.settings/org.eclipse.pde.prefs +++ /dev/null @@ -1,32 +0,0 @@ -compilers.f.unresolved-features=1 -compilers.f.unresolved-plugins=1 -compilers.incompatible-environment=1 -compilers.p.build=1 -compilers.p.build.bin.includes=0 -compilers.p.build.encodings=2 -compilers.p.build.java.compiler=2 -compilers.p.build.java.compliance=1 -compilers.p.build.missing.output=2 -compilers.p.build.output.library=1 -compilers.p.build.source.library=0 -compilers.p.build.src.includes=0 -compilers.p.deprecated=1 -compilers.p.discouraged-class=1 -compilers.p.internal=1 -compilers.p.missing-packages=1 -compilers.p.missing-version-export-package=2 -compilers.p.missing-version-import-package=2 -compilers.p.missing-version-require-bundle=2 -compilers.p.no-required-att=0 -compilers.p.not-externalized-att=2 -compilers.p.unknown-attribute=1 -compilers.p.unknown-class=1 -compilers.p.unknown-element=1 -compilers.p.unknown-identifier=1 -compilers.p.unknown-resource=1 -compilers.p.unresolved-ex-points=0 -compilers.p.unresolved-import=0 -compilers.s.create-docs=false -compilers.s.doc-folder=doc -compilers.s.open-tags=1 -eclipse.preferences.version=1 diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/META-INF/MANIFEST.MF b/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/META-INF/MANIFEST.MF deleted file mode 100644 index 06729d986..000000000 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/META-INF/MANIFEST.MF +++ /dev/null @@ -1,19 +0,0 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: %Bundle-Name -Bundle-Vendor: %Bundle-Vendor -Bundle-SymbolicName: org.eclipse.tracecompass.incubator.executioncomparison.ui.swtbot.tests;singleton:=true -Bundle-Version: 0.1.0.qualifier -Bundle-Localization: plugin -Bundle-ActivationPolicy: lazy -Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Require-Bundle: org.eclipse.core.resources, - org.eclipse.core.runtime, - org.eclipse.swtbot.eclipse.finder, - org.eclipse.swtbot.junit4_x, - org.eclipse.ui, - org.eclipse.ui.ide, - org.eclipse.ui.views, - org.junit, - org.eclipse.jdt.annotation;bundle-version="[2.0.0,3.0.0)";resolution:=optional -Automatic-Module-Name: org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/swtbot-test-plugin.properties b/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/swtbot-test-plugin.properties deleted file mode 100644 index 338038b93..000000000 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/swtbot-test-plugin.properties +++ /dev/null @@ -1 +0,0 @@ -# This file tells the Maven build to use the settings for SWTBot test plugins diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.settings/org.eclipse.core.resources.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 99f26c020..000000000 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.settings/org.eclipse.core.runtime.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.settings/org.eclipse.core.runtime.prefs deleted file mode 100644 index 5a0ad22d2..000000000 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.settings/org.eclipse.core.runtime.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -line.separator=\n diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/about.html b/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/about.html deleted file mode 100644 index 164f781a8..000000000 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/about.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - -About - - -

About This Content

- -

November 30, 2017

-

License

- -

- The Eclipse Foundation makes available all content in this plug-in - ("Content"). Unless otherwise indicated below, the Content - is provided to you under the terms and conditions of the Eclipse - Public License Version 2.0 ("EPL"). A copy of the EPL is - available at http://www.eclipse.org/legal/epl-2.0. - For purposes of the EPL, "Program" will mean the Content. -

- -

- If you did not receive this Content directly from the Eclipse - Foundation, the Content is being redistributed by another party - ("Redistributor") and different terms and conditions may - apply to your use of any object code in the Content. Check the - Redistributor's license that was provided with the Content. If no such - license exists, contact the Redistributor. Unless otherwise indicated - below, the terms and conditions of the EPL still apply to any source - code in the Content and such source code may be obtained at http://www.eclipse.org. -

- - - \ No newline at end of file diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/plugin.xml b/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/plugin.xml deleted file mode 100644 index 15bf1c4dd..000000000 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/plugin.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/ExecutionComparisonView.java b/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/ExecutionComparisonView.java deleted file mode 100644 index 8bbf28bd5..000000000 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/ExecutionComparisonView.java +++ /dev/null @@ -1,1225 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2024 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License 2.0 which - * accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package org.eclipse.tracecompass.incubator.internal.executioncomparison.ui; - -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Objects; -import java.util.logging.Level; - -import javax.swing.JFormattedTextField; -import javax.swing.JLabel; - -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.ActionContributionItem; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IMenuCreator; -import org.eclipse.jface.action.IMenuManager; -import org.eclipse.jface.action.IStatusLineManager; -import org.eclipse.jface.action.Separator; -import org.eclipse.jface.layout.GridLayoutFactory; -import org.eclipse.swt.SWT; -import org.eclipse.swt.awt.SWT_AWT; -import org.eclipse.swt.custom.SashForm; -import org.eclipse.swt.events.ExpandEvent; -import org.eclipse.swt.events.ExpandListener; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.PaintEvent; -import org.eclipse.swt.events.PaintListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.layout.RowLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.ExpandBar; -import org.eclipse.swt.widgets.ExpandItem; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.Sash; -import org.eclipse.swt.widgets.Text; -import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.ScopeLog; -import org.eclipse.tracecompass.incubator.internal.executioncomparison.core.TmfCheckboxChangedSignal; -import org.eclipse.tracecompass.incubator.internal.executioncomparison.core.TmfComparisonFilteringUpdatedSignal; -import org.eclipse.tracecompass.internal.tmf.ui.viewers.eventdensity.EventDensityTreeViewer; -import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal; -import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; -import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; -import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; -import org.eclipse.tracecompass.tmf.core.signal.TmfWindowRangeUpdatedSignal; -import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; -import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat; -import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; -import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; -import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentInfo; -import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentSignal; -import org.eclipse.tracecompass.tmf.ui.viewers.ILegendImageProvider2; -import org.eclipse.tracecompass.tmf.ui.viewers.TmfTimeViewer; -import org.eclipse.tracecompass.tmf.ui.viewers.TmfViewer; -import org.eclipse.tracecompass.tmf.ui.viewers.tree.AbstractSelectTreeViewer2; -import org.eclipse.tracecompass.tmf.ui.viewers.tree.ICheckboxTreeViewerListener; -import org.eclipse.tracecompass.tmf.ui.viewers.tree.ITmfTreeViewerEntry; -import org.eclipse.tracecompass.tmf.ui.viewers.xychart.TmfXYChartViewer; -import org.eclipse.tracecompass.tmf.ui.viewers.xychart.XYChartLegendImageProvider; -import org.eclipse.tracecompass.tmf.ui.viewers.xychart.linechart.TmfCommonXAxisChartViewer; -import org.eclipse.tracecompass.tmf.ui.viewers.xychart.linechart.TmfFilteredXYChartViewer; -import org.eclipse.tracecompass.tmf.ui.viewers.xychart.linechart.TmfXYChartSettings; -import org.eclipse.tracecompass.tmf.ui.views.ManyEntriesSelectedDialogPreCheckedListener; -import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs.TriStateFilteredCheckboxTree; -import org.eclipse.ui.IWorkbenchPartSite; -import org.eclipse.ui.contexts.IContextActivation; -import org.eclipse.ui.contexts.IContextService; - -/** - * ExecutionComparisonView allows to compare two groups of traces (parts of traces) - * - * @author Fateme Faraji Daneshgar - */ -@SuppressWarnings("restriction") -public class ExecutionComparisonView extends DifferentialFlameGraphView implements ICheckboxTreeViewerListener { - - /** - * the id of the view - */ - public static final String id = "org.eclipse.tracecompass.incubator.internal.executioncomparison.ui.execComparison"; //$NON-NLS-1$ - /** - * Default weights for organizing the view - */ - private static final int[] DEFAULT_WEIGHTS_ShowQuery = new int[] { 450, 290, 260 }; - private static final int[] DEFAULT_WEIGHTS_HideQuery = new int[] { 450, 100, 450 }; - private static final int[] DEFAULT_WEIGHTS_FILTERING_H = new int[] { 3, 9 }; - private static final int[] DEFAULT_WEIGHTS_TimeInterval = new int[] { 240, 380, 380 }; - - /** A composite that allows us to add margins for part A */ - private @Nullable TmfXYChartViewer fChartViewerA; - private @Nullable SashForm fXYViewerContainerA; - private @Nullable TmfViewer fTmfViewerA; - private @Nullable SashForm fSashFormLeftChildA; - private @Nullable SashForm fSashFormLeftChildB; - private @Nullable IContextService fContextService; - private @Nullable Action fConfigureStatisticAction; - private List fActiveContexts = new ArrayList<>(); - - /** A composite that allows us to add margins for part B */ - private @Nullable TmfXYChartViewer fChartViewerB; - private @Nullable SashForm fXYViewerContainerB; - private @Nullable TmfViewer fTmfViewerB; - private List fTraceListA = new ArrayList<>(); - private List fTraceListB = new ArrayList<>(); - private String fTraceStr = "Trace(s): ";//$NON-NLS-1$ - private String fStatisticStr = "Statistic: ";//$NON-NLS-1$ - - /** - * the title of the view - */ - @SuppressWarnings("null") - public static final String VIEW_TITLE = Messages.MultipleDensityView_title; - private ITmfTimestamp fStartTimeA = TmfTimestamp.BIG_BANG; - private ITmfTimestamp fStartTimeB = TmfTimestamp.BIG_BANG; - private ITmfTimestamp fEndTimeA = TmfTimestamp.BIG_CRUNCH; - private ITmfTimestamp fEndTimeB = TmfTimestamp.BIG_CRUNCH; - private String fStatistic = Messages.MultipleDensityView_Duration; - private JFormattedTextField ftextAFrom = new JFormattedTextField(); - private JFormattedTextField ftextBFrom = new JFormattedTextField(); - private JFormattedTextField ftextATo = new JFormattedTextField(); - private JFormattedTextField ftextBTo = new JFormattedTextField(); - private @Nullable Text ftextQuery; - private TmfTimestampFormat fFormat = new TmfTimestampFormat("yyyy-MM-dd HH:mm:ss.SSS.SSS.SSS"); //$NON-NLS-1$ - private @Nullable Listener fSashDragListener; - private SashForm fsashForm; - private static final String TMF_VIEW_UI_CONTEXT = "org.eclipse.tracecompass.tmf.ui.view.context"; //$NON-NLS-1$ - - /** - * Constructs two density charts for selecting the desired traces and time - * ranges in order to comparison - */ - public ExecutionComparisonView() { - super(); - } - - @Override - public void createPartControl(@Nullable Composite parent) { - TmfSignalManager.register(this); - - final SashForm sashForm = new SashForm(parent, SWT.VERTICAL); - fsashForm = sashForm; - sashForm.setLayout(new GridLayout(1, false)); - sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - //// Main organization of the view. there are three main parts in the - //// view:filtering, query and differential flame graph - Composite sashFormFiltering = new Composite(sashForm, SWT.HORIZONTAL); - GridLayout layout = new GridLayout(2, false); - layout.marginHeight = layout.marginWidth = 0; - sashFormFiltering.setLayout(layout); - sashFormFiltering.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - ////GroupA - Group groupA = new Group(sashFormFiltering, SWT.NULL); - groupA.setText(Messages.MultipleDensityView_GroupA); - GridLayout gridLayoutG = new GridLayout(); - gridLayoutG.numColumns = 1; - groupA.setLayout(gridLayoutG); - GridData gridDataG = new GridData(GridData.FILL_BOTH); - gridDataG.horizontalSpan = 1; - groupA.setLayoutData(gridDataG); - - - SashForm densityA = new SashForm(groupA, SWT.NULL); - GridData data = new GridData(SWT.FILL, SWT.TOP, true, false); - data.heightHint = 200; - densityA.setLayoutData(data); - - SashForm timeInputA = new SashForm(groupA, SWT.NULL); - timeInputA.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - ////GroupB - Group groupB = new Group(sashFormFiltering, SWT.NULL); - groupB.setText(Messages.MultipleDensityView_GroupB); - groupB.setLayout(gridLayoutG); - groupB.setLayoutData(gridDataG); - - SashForm densityB = new SashForm(groupB, SWT.NULL); - densityB.setLayoutData(data); - - SashForm timeInputB = new SashForm(groupB, SWT.NULL); - timeInputB.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - //// Group A time Intervals - Composite timelableA = new Composite(timeInputA, SWT.NONE); - Composite timelableAFrom = new Composite(timeInputA, SWT.EMBEDDED); - Composite timelableATo = new Composite(timeInputA, SWT.EMBEDDED); - - timeInputA.setWeights(DEFAULT_WEIGHTS_TimeInterval); - - RowLayout rowLayout = new RowLayout(); - GridLayout gridLayout = new GridLayout(); - gridLayout.numColumns = 2; - - timelableA.setLayout(gridLayout); - timelableAFrom.setLayout(rowLayout); - timelableATo.setLayout(rowLayout); - - // ButtonA - Button resetButtonA = new Button(timelableA, SWT.PUSH); - resetButtonA.setText("Reset Time IntervalA"); //$NON-NLS-1$ - resetButtonA.addListener(SWT.Selection, new Listener() - { - @Override - public void handleEvent(@Nullable Event event) { - ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace(); - - if (trace != null) { - //Reset tree viewer checked items. all items should be checked - List TreeCheckedElements = ((MultipleEventDensityViewer) getChartViewerA()).getWholeCheckedItems(); - setCheckedElements(getChartViewerA(),getTmfViewerA(),TreeCheckedElements,false); - - //Reset start time and end time and relating objects - fStartTimeA = trace.getStartTime(); - fEndTimeA = trace.getEndTime(); - ftextAFrom.setText(fStartTimeA.toString(fFormat)); - ftextATo.setText(fEndTimeA.toString(fFormat)); - if(ftextQuery!=null) { - ftextQuery.setText(makeQuery()); - } - - //dispatch signal to rebuild differential flame graph - TmfSignalManager.dispatchSignal(new TmfSelectionRangeUpdatedSignal(getChartViewerA(), fStartTimeA, fEndTimeA, getTrace())); - } - } - }); - - /// LableAfrom - java.awt.Frame frameAFrom = SWT_AWT.new_Frame(timelableAFrom); - java.awt.Panel panelAFrom = new java.awt.Panel(); - frameAFrom.add(panelAFrom); - - JLabel labelAFrom = new JLabel(); - labelAFrom.setText(Messages.MultipleDensityView_From); - - JFormattedTextField textAFrom = new JFormattedTextField(fFormat); - textAFrom.addFocusListener(new java.awt.event.FocusListener() { - public String oldVal = ""; //$NON-NLS-1$ - - @Override - public void focusGained( java.awt.event.@Nullable FocusEvent e) { - String aFrom = textAFrom.getText(); - if (aFrom!=null) { - oldVal = aFrom; - } - } - - @Override - public void focusLost(java.awt.event.@Nullable FocusEvent e) { - if (!oldVal.equals(textAFrom.getText())) { - long newTime = 0; - try { - newTime = fFormat.parseValue(textAFrom.getText()); - ITmfTimestamp fromTime = TmfTimestamp.fromNanos(newTime); - fStartTimeA = fromTime; - textAFrom.setText(fStartTimeA.toString(fFormat)); - - updateSelectedRange(); - getChartViewerA().selectionRangeUpdated(new TmfSelectionRangeUpdatedSignal(this, fStartTimeA, fEndTimeA, getTrace())); - - } catch (ParseException e1) { - textAFrom.setText(oldVal); - e1.printStackTrace(); - } - } - } - }); - panelAFrom.add(labelAFrom); - panelAFrom.add(textAFrom); - ftextAFrom = textAFrom; - - //// LableATo - java.awt.Frame frameATo = SWT_AWT.new_Frame(timelableATo); - java.awt.Panel panelATo = new java.awt.Panel(); - frameATo.add(panelATo); - - JLabel labelATo = new JLabel(); - labelATo.setText(Messages.MultipleDensityView_To); - JFormattedTextField textATo = new JFormattedTextField(fFormat); - textATo.addFocusListener(new java.awt.event.FocusListener() { - public String oldVal = ""; //$NON-NLS-1$ - - @Override - public void focusGained(java.awt.event.@Nullable FocusEvent e) { - String aTo = textATo.getText(); - if (aTo!=null) { - oldVal = aTo; - } - } - - @Override - public void focusLost( java.awt.event.@Nullable FocusEvent e) { - if (!oldVal.equals(textATo.getText())) { - long newTime = 0; - try { - newTime = fFormat.parseValue(textATo.getText()); - ITmfTimestamp fromTime = TmfTimestamp.fromNanos(newTime); - fEndTimeA = fromTime; - textATo.setText(fEndTimeA.toString(fFormat)); - - updateSelectedRange(); - getChartViewerA().selectionRangeUpdated(new TmfSelectionRangeUpdatedSignal(this, fStartTimeA, fEndTimeA, getTrace())); - - } catch (ParseException e1) { - textATo.setText(oldVal); - e1.printStackTrace(); - } - } - } - }); - - panelATo.add(labelATo); - panelATo.add(textATo); - ftextATo = textATo; - - //// Group B time Intervals - Composite timelableB = new Composite(timeInputB, SWT.FILL); - Composite timelableBFrom = new Composite(timeInputB, SWT.EMBEDDED); - Composite timelableBTo = new Composite(timeInputB, SWT.EMBEDDED); - - timeInputB.setWeights(DEFAULT_WEIGHTS_TimeInterval); - - timelableB.setLayout(gridLayout); - timelableBFrom.setLayout(rowLayout); - timelableBTo.setLayout(rowLayout); - - // Button B - Button resetButtonB = new Button(timelableB, SWT.PUSH); - resetButtonB.setText("Reset Time IntervalB"); //$NON-NLS-1$ - resetButtonB.addListener(SWT.Selection, new Listener() - { - @Override - public void handleEvent(@Nullable Event event) { - ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace(); - - if (trace != null) { - //Reset tree viewer checked items. all items should be checked - List TreeCheckedElements = ((MultipleEventDensityViewer) getChartViewerB()).getWholeCheckedItems(); - setCheckedElements(getChartViewerB(),getTmfViewerB(),TreeCheckedElements,false); - - //Reset start time and end time and relating objects - fStartTimeB = trace.getStartTime(); - fEndTimeB = trace.getEndTime(); - ftextBFrom.setText(fStartTimeB.toString(fFormat)); - ftextBTo.setText(fEndTimeB.toString(fFormat)); - if(ftextQuery!=null) { - ftextQuery.setText(makeQuery()); - } - - //dispatch signal to rebuild differential flame graph - TmfSignalManager.dispatchSignal(new TmfSelectionRangeUpdatedSignal(getChartViewerB(), fStartTimeB, fEndTimeB, getTrace())); - } - } - }); - - - /// LableBFrom - java.awt.Frame frameBFrom = SWT_AWT.new_Frame(timelableBFrom); - java.awt.Panel panelBFrom = new java.awt.Panel(); - frameBFrom.add(panelBFrom); - - JLabel labelBFrom = new JLabel(); - labelBFrom.setText(Messages.MultipleDensityView_From); - JFormattedTextField textBFrom = new JFormattedTextField(fFormat); - textBFrom.addFocusListener(new java.awt.event.FocusListener() { - public String oldVal=""; //$NON-NLS-1$ - - @Override - public void focusGained(java.awt.event.@Nullable FocusEvent e) { - String bFrom = textBFrom.getText(); - if (bFrom!=null) { - oldVal = bFrom; - } - } - - @Override - public void focusLost(java.awt.event.@Nullable FocusEvent e) { - if (!oldVal.equals(textBFrom.getText())) { - long newTime = 0; - try { - newTime = fFormat.parseValue(textBFrom.getText()); - ITmfTimestamp fromTime = TmfTimestamp.fromNanos(newTime); - fStartTimeB = fromTime; - textBFrom.setText(fStartTimeB.toString(fFormat)); - - updateSelectedRange(); - getChartViewerB().selectionRangeUpdated(new TmfSelectionRangeUpdatedSignal(this, fStartTimeB, fEndTimeB, getTrace())); - - } catch (ParseException e1) { - textBFrom.setText(oldVal); - e1.printStackTrace(); - } - - } - } - }); - - panelBFrom.add(labelBFrom); - panelBFrom.add(textBFrom); - ftextBFrom = textBFrom; - - //// LableBTo - java.awt.Frame frameBTo = SWT_AWT.new_Frame(timelableBTo); - java.awt.Panel panelBTo = new java.awt.Panel(); - frameBTo.add(panelBTo); - - JLabel labelBTo = new JLabel(); - labelBTo.setText(Messages.MultipleDensityView_To); - JFormattedTextField textBTo = new JFormattedTextField(fFormat); - textBTo.addFocusListener(new java.awt.event.FocusListener() { - public @Nullable String oldVal = null; - - @SuppressWarnings("null") - @Override - public void focusGained(java.awt.event.FocusEvent e) { - oldVal = textBTo.getText(); - } - - @SuppressWarnings("null") - @Override - public void focusLost(java.awt.event.FocusEvent e) { - if (!oldVal.equals(textBTo.getText())) { - long newTime = 0; - try { - newTime = fFormat.parseValue(textBTo.getText()); - ITmfTimestamp fromTime = TmfTimestamp.fromNanos(newTime); - fEndTimeB = fromTime; - textBTo.setText(fEndTimeB.toString(fFormat)); - updateSelectedRange(); - getChartViewerB().selectionRangeUpdated(new TmfSelectionRangeUpdatedSignal(this, fStartTimeA, fEndTimeA, getTrace())); - - } catch (ParseException e1) { - textBTo.setText(oldVal); - e1.printStackTrace(); - } - } - } - }); - - panelBTo.add(labelBTo); - panelBTo.add(textBTo); - ftextBTo = textBTo; - - setSashFormLeftChildA(new SashForm(densityA, SWT.None)); - - setTmfViewerA(createLeftChildViewer(getSashFormLeftChildA())); - - SashForm xYViewerContainerA = new SashForm(densityA, SWT.None); - fXYViewerContainerA = xYViewerContainerA; - xYViewerContainerA.setLayout(GridLayoutFactory.fillDefaults().create()); - - TmfXYChartViewer chartViewerA = createChartViewer(xYViewerContainerA); - - setChartViewerA(chartViewerA); - - chartViewerA.getControl().addPaintListener(new PaintListener() { - @Override - public void paintControl(@Nullable PaintEvent e) { - // Sashes in a SashForm are being created on layout so add the - // drag listener here - Listener sashDragListener = fSashDragListener; - if (sashDragListener == null) { - for (Control control : getSashFormLeftChildA().getChildren()) { - if (control instanceof Sash) { - sashDragListener = event -> TmfSignalManager.dispatchSignal(new TmfTimeViewAlignmentSignal(getSashFormLeftChildA(), getTimeViewAlignmentInfo(chartViewerA, getSashFormLeftChildA()))); - fSashDragListener = sashDragListener; - control.removePaintListener(this); - control.addListener(SWT.Selection, sashDragListener); - // There should be only one sash - break; - } - - } - } - } - }); - - IStatusLineManager statusLineManager = getViewSite().getActionBars().getStatusLineManager(); - chartViewerA.setStatusLineManager(statusLineManager); - coupleSelectViewer(getTmfViewerA(), chartViewerA); - ((AbstractSelectTreeViewer2) getTmfViewerA()).addTreeListener(this); - - IWorkbenchPartSite site = getSite(); - setContextService(site.getWorkbenchWindow().getService(IContextService.class)); - - setSashFormLeftChildB(new SashForm(densityB, SWT.VERTICAL)); - setTmfViewerB(createLeftChildViewer(getSashFormLeftChildB())); - SashForm xYViewerContainerB = new SashForm(densityB, SWT.VERTICAL); - fXYViewerContainerB = xYViewerContainerB; - xYViewerContainerB.setLayout(GridLayoutFactory.fillDefaults().create()); - - TmfXYChartViewer chartViewerB = createChartViewer(xYViewerContainerB); - setChartViewerB(chartViewerB); - - chartViewerB.getControl().addPaintListener(new PaintListener() { - @Override - public void paintControl(@Nullable PaintEvent e) { - // Sashes in a SashForm are being created on layout so add the - // drag listener here - if (fSashDragListener == null) { - for (Control control : getSashFormLeftChildB().getChildren()) { - Objects.requireNonNull(getSashFormLeftChildB()); - - fSashDragListener = event -> TmfSignalManager.dispatchSignal(new TmfTimeViewAlignmentSignal(getSashFormLeftChildB(), getTimeViewAlignmentInfo(chartViewerB, getSashFormLeftChildB()))); - control.removePaintListener(this); - control.addListener(SWT.Selection, fSashDragListener); - // There should be only one sash - break; - } - } - } - }); - - chartViewerB.setStatusLineManager(statusLineManager); - coupleSelectViewer(getTmfViewerB(), chartViewerB); - ((AbstractSelectTreeViewer2) getTmfViewerB()).addTreeListener(this); - - IMenuManager menuManager = getViewSite().getActionBars().getMenuManager(); - - IAction AggregatedAction = fConfigureStatisticAction; - if (AggregatedAction == null) { - AggregatedAction = getAggregateByAction(); - fConfigureStatisticAction = (Action) AggregatedAction; - } - menuManager.add(new Separator()); - menuManager.add(AggregatedAction); - menuManager.add(new Separator()); - - densityA.setWeights(DEFAULT_WEIGHTS_FILTERING_H); - densityB.setWeights(DEFAULT_WEIGHTS_FILTERING_H); - - Group groupQuery = new Group(sashForm, SWT.NULL); - groupQuery.setText(Messages.MultipleDensityView_QueryGroup); - gridLayoutG = new GridLayout(); - gridLayoutG.numColumns = 1; - groupQuery.setLayout(gridLayoutG); - gridDataG = new GridData(GridData.FILL_BOTH); - gridDataG.horizontalSpan = 1; - groupQuery.setLayoutData(gridDataG); - - ///// Organizing sashFormQuery - ExpandBar bar = new ExpandBar(groupQuery, SWT.NONE); - bar.setLayout(new GridLayout(1, false)); - GridData data2 = new GridData(); - data2.verticalAlignment = SWT.FILL; - data2.horizontalAlignment = SWT.FILL; - data2.grabExcessHorizontalSpace = true; - data2.grabExcessVerticalSpace = true; - data2.heightHint = 75; - data2.widthHint = 100; - bar.setLayoutData(data2); - - - Composite queryText = new Composite(bar, SWT.NONE); - queryText.setLayout(new GridLayout(1, false)); - queryText.setLayoutData(new GridData(SWT.FILL, SWT.FILL,true,true)); - - // Text - Text text = new Text(queryText, SWT.MULTI | SWT.BORDER ); - data.verticalAlignment = SWT.FILL; - data.horizontalAlignment = SWT.FILL; - data.grabExcessHorizontalSpace = true; - data.grabExcessVerticalSpace = true; - data.heightHint = 75; - data.widthHint = 100; - text.setLayoutData(data); - ftextQuery = text; - text.addFocusListener(new FocusListener() { - - @Override - public void focusGained(@Nullable FocusEvent e) { - // TODO Auto-generated method stub - } - - @Override - public void focusLost(@Nullable FocusEvent e) { - String query = ftextQuery.getText(); - if (query==null) - { - return; - } - boolean parsed = parseQuery(query); - if (parsed) { - ///updating blue lines in density chats - getChartViewerA().selectionRangeUpdated(new TmfSelectionRangeUpdatedSignal(this, fStartTimeA, fEndTimeA, getTrace())); - getChartViewerB().selectionRangeUpdated(new TmfSelectionRangeUpdatedSignal(this, fStartTimeB, fEndTimeB, getTrace())); - - //updates checked elements in treeviewers - //treeViewerA - List TreeWholeElements = ((MultipleEventDensityViewer) getChartViewerA()).getWholeCheckedItems(); - List TreeCheckedElements = new ArrayList<>(); - - for (ITmfTreeViewerEntry trace:TreeWholeElements) { - if(fTraceListA.contains(trace.getName())) { - TreeCheckedElements.add(trace); - TreeCheckedElements.addAll(trace.getChildren()); - } - } - - setCheckedElements(getChartViewerA(),getTmfViewerA(),TreeCheckedElements,true); - //TreeVierB - TreeWholeElements = ((MultipleEventDensityViewer) getChartViewerB()).getWholeCheckedItems(); - TreeCheckedElements = new ArrayList<>(); - - for (ITmfTreeViewerEntry trace:TreeWholeElements) { - if(fTraceListB.contains(trace.getName())) { - TreeCheckedElements.add(trace); - TreeCheckedElements.addAll(trace.getChildren()); - } - } - - setCheckedElements(getChartViewerB(),getTmfViewerB(),TreeCheckedElements,true); - - TmfComparisonFilteringUpdatedSignal rangUpdateSignal = new TmfComparisonFilteringUpdatedSignal(this, fStartTimeA, fEndTimeA, fStartTimeB, fEndTimeB, fStatistic, fTraceListA, fTraceListB); - TmfSignalManager.dispatchSignal(rangUpdateSignal); - buildDifferetialFlameGraph(); - } - } - }); - - ExpandItem item0 = new ExpandItem(bar, SWT.NONE,0); - item0.setText(Messages.MultipleDensityView_QueryExpandable); - item0.setHeight(150); - - item0.setControl(queryText); - item0.setExpanded(false); - - bar.setSpacing(5); - bar.addExpandListener(new ExpandListener() { - - @Override - public void itemExpanded(@Nullable ExpandEvent e) { - Display.getCurrent().asyncExec(new Runnable() { - @Override - public void run() { - queryText.pack(true); - sashForm.setWeights(DEFAULT_WEIGHTS_ShowQuery); - - } - }); - } - - @Override - public void itemCollapsed(@Nullable ExpandEvent e) { - Display.getCurrent().asyncExec(new Runnable() { - @Override - public void run() { - queryText.pack(true); - sashForm.setWeights(DEFAULT_WEIGHTS_HideQuery); - - } - }); - } - }); - - super.createPartControl(sashForm); - sashForm.setWeights(DEFAULT_WEIGHTS_HideQuery); - - ITmfTrace activetrace = TmfTraceManager.getInstance().getActiveTrace(); - if (activetrace != null) { - buildDifferetialFlameGraph(); - } - } - - /** - * /** Return the time alignment information - * - * @param chartViewer - * the event distribution viewer - * @param sashFormLeftChild - * the check box viewer - * @return the time alignment information - */ - public TmfTimeViewAlignmentInfo getTimeViewAlignmentInfo(TmfXYChartViewer chartViewer, SashForm sashFormLeftChild) { - return new TmfTimeViewAlignmentInfo(chartViewer.getControl().getShell(), sashFormLeftChild.toDisplay(0, 0), getTimeAxisOffset(chartViewer, sashFormLeftChild)); - } - - private static int getTimeAxisOffset(TmfXYChartViewer chartViewer, SashForm sashFormLeftChild) { - return sashFormLeftChild.getChildren()[0].getSize().x + sashFormLeftChild.getSashWidth() + chartViewer.getPointAreaOffset(); - } - - @Override - @TmfSignalHandler - public void traceSelected(final TmfTraceSelectedSignal signal) { - super.traceSelected(signal); - if (getTmfViewerA() instanceof TmfTimeViewer) { - ((TmfTimeViewer) getTmfViewerA()).traceSelected(signal); - } - getChartViewerA().traceSelected(signal); - - if (getTmfViewerB() instanceof TmfTimeViewer) { - ((TmfTimeViewer) getTmfViewerB()).traceSelected(signal); - } - - getChartViewerB().traceSelected(signal); - ITmfTrace trace = signal.getTrace(); - fStartTimeA = trace.getStartTime(); - fEndTimeA = trace.getEndTime(); - fStartTimeB = trace.getStartTime(); - fEndTimeB = trace.getEndTime(); - - ftextAFrom.setText(fStartTimeA.toString(fFormat)); - ftextBFrom.setText(fStartTimeB.toString(fFormat)); - ftextATo.setText(fEndTimeA.toString(fFormat)); - ftextBTo.setText(fEndTimeB.toString(fFormat)); - - TmfComparisonFilteringUpdatedSignal rangUpdateSignal = new TmfComparisonFilteringUpdatedSignal(this, fStartTimeA, fEndTimeA, fStartTimeB, fEndTimeB, fStatistic, fTraceListA, fTraceListB); - TmfSignalManager.dispatchSignal(rangUpdateSignal); - if(ftextQuery!=null) { - ftextQuery.setText(makeQuery()); - } - buildDifferetialFlameGraph(); - } - - private Action createStatisticAction(String name) { - return new Action(name, IAction.AS_RADIO_BUTTON) { - @Override - public void run() { - ITmfTrace trace = getTrace(); - if (trace == null) { - return; - } - fStatistic = name; - System.out.println(name+"\n"); - TmfComparisonFilteringUpdatedSignal rangUpdateSignal = new TmfComparisonFilteringUpdatedSignal(this, fStatistic, null, null); - TmfSignalManager.dispatchSignal(rangUpdateSignal); - if (ftextQuery!=null) { - ftextQuery.setText(makeQuery()); - } - buildDifferetialFlameGraph(); - } - }; - } - - /** - * @param signal - * the trace open signal - */ - @TmfSignalHandler - public void traceOpened(TmfTraceOpenedSignal signal) { - getChartViewerA().traceOpened(signal); - getChartViewerB().traceOpened(signal); - - } - - private void buildDifferetialFlameGraph() { - - ITmfTrace activetrace = TmfTraceManager.getInstance().getActiveTrace(); - if (activetrace != null) { - Display.getDefault().asyncExec(() -> buildFlameGraph(activetrace, null, null)); - - } - } - - /** - * create left child viewer for event density chart - * - * @param parent - * composite - * @return left chart viewer - */ - public TmfViewer createLeftChildViewer(Composite parent) { - EventDensityTreeViewer histogramTreeViewer = new EventDensityTreeViewer(parent); - ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace(); - if (trace != null) { - histogramTreeViewer.traceSelected(new TmfTraceSelectedSignal(this, trace)); - } - return histogramTreeViewer; - } - - private TmfXYChartViewer createChartViewer(Composite parent) { - MultipleEventDensityViewer chartViewer = new MultipleEventDensityViewer(parent, new TmfXYChartSettings(null, null, null, 1)); - chartViewer.setSendTimeAlignSignals(true); - chartViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - chartViewer.getControl().addMouseListener(new MouseAdapter() { - @Override - public void mouseDoubleClick(@Nullable MouseEvent e) { - super.mouseDoubleClick(e); - resetStartFinishTime(true, chartViewer); - } - }); - chartViewer.getControl().addFocusListener(new FocusListener() { - @Override - public void focusLost(@Nullable FocusEvent e) { - deactivateContextService(); - } - - @Override - public void focusGained(@Nullable FocusEvent e) { - activateContextService(); - } - }); - - return chartViewer; - } - - /** - * Set checked for the elements in TreeCheckedElements - * @param TreeCheckedElements - * the elements in tree that should be checked - */ - public void setCheckedElements(TmfXYChartViewer chart,TmfViewer tree,List TreeCheckedElements, Boolean queryUpdate) { - if (queryUpdate) { - ((MultipleEventDensityViewer) chart).UpdateCheckStateChangedEvent(TreeCheckedElements); - } - else { - ((MultipleEventDensityViewer) chart).handleCheckStateChangedEvent(TreeCheckedElements); - } - Object[] TreeCheckedElementsObj = new Object[TreeCheckedElements.size()]; - - TreeCheckedElements.toArray(TreeCheckedElementsObj); - ((AbstractSelectTreeViewer2) tree).getTriStateFilteredCheckboxTree().setCheckedElements(TreeCheckedElementsObj); - } - - /** - * Reset the start and end times. - * - * @param chart - * determines which chart to reset start and end times - */ - public void resetStartFinishTime(boolean notify, TmfXYChartViewer chart) { - if (notify) { - TmfWindowRangeUpdatedSignal signal = new TmfWindowRangeUpdatedSignal(this, TmfTimeRange.ETERNITY, getTrace()); - broadcast(signal); - - } - } - - private void deactivateContextService() { - getContextService().deactivateContexts(fActiveContexts); - fActiveContexts.clear(); - } - - private void activateContextService() { - if (fActiveContexts.isEmpty()) { - IContextActivation activateContext = getContextService().activateContext(TMF_VIEW_UI_CONTEXT); - Objects.requireNonNull(activateContext); - fActiveContexts.add(activateContext); - } - } - - private static void coupleSelectViewer(TmfViewer tree, TmfXYChartViewer chart) { - if (tree instanceof AbstractSelectTreeViewer2 && chart instanceof TmfFilteredXYChartViewer) { - ILegendImageProvider2 legendImageProvider = new XYChartLegendImageProvider((TmfCommonXAxisChartViewer) chart); - AbstractSelectTreeViewer2 selectTree = (AbstractSelectTreeViewer2) tree; - selectTree.addTreeListener((TmfFilteredXYChartViewer) chart); - selectTree.setLegendImageProvider(legendImageProvider); - TriStateFilteredCheckboxTree checkboxTree = selectTree.getTriStateFilteredCheckboxTree(); - checkboxTree.addPreCheckStateListener(new ManyEntriesSelectedDialogPreCheckedListener(checkboxTree)); - } - } - - - - /** - * @param signal - * TmfSelectionRangeUpdatedSignal signal raised when time ranges - * are updated - */ - @TmfSignalHandler - public void selectionRangeUpdated(TmfSelectionRangeUpdatedSignal signal) { - Object source = signal.getSource(); - if (source == getChartViewerA()) { - fStartTimeA = signal.getBeginTime(); - fEndTimeA = signal.getEndTime(); - ftextAFrom.setText(fStartTimeA.toString(fFormat)); - ftextATo.setText(fEndTimeA.toString(fFormat)); - - } else if (source == getChartViewerB()) { - fStartTimeB = signal.getBeginTime(); - fEndTimeB = signal.getEndTime(); - ftextBFrom.setText(fStartTimeB.toString(fFormat)); - ftextBTo.setText(fEndTimeB.toString(fFormat)); - } - updateSelectedRange(); - - } - - /** - * updates the filtering parameters and query and builds flamegraph - */ - public void updateSelectedRange(){ - try (ScopeLog sl = new ScopeLog(LOGGER, Level.FINE, "MultiDensityView::SelectionRangeUpdated")) { //$NON-NLS-1$ - TmfComparisonFilteringUpdatedSignal rangUpdateSignal = new TmfComparisonFilteringUpdatedSignal(this, fStartTimeA, fEndTimeA, fStartTimeB, fEndTimeB, null, null, null); - TmfSignalManager.dispatchSignal(rangUpdateSignal); - Display.getDefault().syncExec(new Runnable() { - @Override - public void run() { - if(ftextQuery!=null) { - ftextQuery.setText(makeQuery()); - } - } - }); - buildDifferetialFlameGraph(); - } - } - - /** - * @return fStatistic (Duration or Self time) which will be represented in - * the flame graph - */ - public String getStatisticType() { - return fStatistic; - - } - - private Action getAggregateByAction() { - Action configureStatisticAction = new Action(Messages.FlameGraphView_GroupByName, IAction.AS_DROP_DOWN_MENU) { - }; - configureStatisticAction.setToolTipText(Messages.FlameGraphView_StatisticTooltip); - configureStatisticAction.setMenuCreator(new IMenuCreator() { - @Nullable - Menu menu = null; - - @Override - public void dispose() { - if (menu != null) { - menu.dispose(); - menu = null; - } - } - - @Override - public @Nullable Menu getMenu(@Nullable Control parent) { - return null; - } - - @Override - public @Nullable Menu getMenu(@Nullable Menu parent) { - menu = new Menu(parent); - - Action statisticActionDur = createStatisticAction(Objects.requireNonNull(Messages.MultipleDensityView_Duration)); - new ActionContributionItem(statisticActionDur).fill(menu, -1); - - Action statisticActionSelf = createStatisticAction(Objects.requireNonNull(Messages.MultipleDensityView_SelfTime)); - new ActionContributionItem(statisticActionSelf).fill(menu, -1); - return menu; - - } - }); - - Action configureStatisticAction1 = Objects.requireNonNull(configureStatisticAction); - return configureStatisticAction1; - } - - /** - * @param signal - * the TmfCheckboxChangedSignal signal - */ - @TmfSignalHandler - public void CheckBoxUpdated(TmfCheckboxChangedSignal signal) { - try (ScopeLog sl = new ScopeLog(LOGGER, Level.FINE, "MultiDensityView::CheckBoxUpdated")) {//$NON-NLS-1$ - TmfComparisonFilteringUpdatedSignal rangUpdateSignal = null; - - if (signal.getSource() == getChartViewerA()) { - fTraceListA.clear(); - for (String name : signal.getTraceList()) { - fTraceListA.add(name); - } - - rangUpdateSignal = new TmfComparisonFilteringUpdatedSignal(this, null, fTraceListA, null); - TmfSignalManager.dispatchSignal(rangUpdateSignal); - } - - if (signal.getSource() == getChartViewerB()) { - fTraceListB.clear(); - for (String name : signal.getTraceList()) { - fTraceListB.add(name); - } - - rangUpdateSignal = new TmfComparisonFilteringUpdatedSignal(this, null, null, fTraceListB); - TmfSignalManager.dispatchSignal(rangUpdateSignal); - - } - if(ftextQuery!=null) { - ftextQuery.setText(makeQuery()); - } - buildDifferetialFlameGraph(); - } - - } - - @Override - public void handleCheckStateChangedEvent(@SuppressWarnings("null") @Nullable Collection entries) { - // do nothing - } - - @Override - public void dispose() { - super.dispose(); - TmfSignalManager.deregister(this); - - getChartViewerA().dispose(); - getTmfViewerA().dispose(); - getChartViewerB().dispose(); - getTmfViewerB().dispose(); - - if (fXYViewerContainerA != null) { - fXYViewerContainerA.dispose(); - } - if (fXYViewerContainerB != null) { - fXYViewerContainerB.dispose(); - } - if (fContextService!=null) { - fContextService.dispose(); - } - if (fSashFormLeftChildA!=null) { - fSashFormLeftChildA.dispose(); - } - if (fSashFormLeftChildB!=null) { - fSashFormLeftChildB.dispose(); - } - if (fsashForm!=null) { - fsashForm.dispose(); - } - } - - private TmfXYChartViewer getChartViewerA() { - Objects.requireNonNull(fChartViewerA); - return fChartViewerA; - } - - private void setChartViewerA(@Nullable TmfXYChartViewer chartViewerA) { - fChartViewerA = chartViewerA; - } - - private TmfXYChartViewer getChartViewerB() { - Objects.requireNonNull(fChartViewerB); - return fChartViewerB; - } - - private void setChartViewerB(@Nullable TmfXYChartViewer chartViewerB) { - fChartViewerB = chartViewerB; - } - - private SashForm getSashFormLeftChildA() { - Objects.requireNonNull(fSashFormLeftChildA); - return fSashFormLeftChildA; - } - - private void setSashFormLeftChildA(@Nullable SashForm sashFormLeftChildA) { - fSashFormLeftChildA = sashFormLeftChildA; - } - - private SashForm getSashFormLeftChildB() { - Objects.requireNonNull(fSashFormLeftChildB); - return fSashFormLeftChildB; - } - - private void setSashFormLeftChildB(@Nullable SashForm sashFormLeftChildB) { - fSashFormLeftChildB = sashFormLeftChildB; - } - - private TmfViewer getTmfViewerA() { - Objects.requireNonNull(fTmfViewerA); - return fTmfViewerA; - } - - private void setTmfViewerA(@Nullable TmfViewer tmfViewerA) { - fTmfViewerA = tmfViewerA; - } - - private TmfViewer getTmfViewerB() { - Objects.requireNonNull(fTmfViewerB); - return fTmfViewerB; - } - - private void setTmfViewerB(@Nullable TmfViewer tmfViewerB) { - fTmfViewerB = tmfViewerB; - } - - private IContextService getContextService() { - Objects.requireNonNull(fContextService); - return fContextService; - } - - private void setContextService(@Nullable IContextService contextService) { - fContextService = contextService; - } - - @SuppressWarnings("null") - private String makeQuery() { - String query = ""; //$NON-NLS-1$ - /// Query PartA - query = query.concat(fTraceStr); - for (String trace : fTraceListA) { - if (!trace.equals("Total")) { //$NON-NLS-1$ - query = query.concat(trace); - query = query.concat(","); //$NON-NLS-1$ - } - } - query = query.concat(System.lineSeparator()); - - query = query.concat(Messages.MultipleDensityView_From); - query = query.concat(fStartTimeA.toString(fFormat)); - query = query.concat(System.lineSeparator()); - - query = query.concat(Messages.MultipleDensityView_To); - query = query.concat(fEndTimeA.toString(fFormat)); - query = query.concat(System.lineSeparator()); - - query = query.concat(Messages.MultipleDensityView_QueryCompare); - query = query.concat(System.lineSeparator()); - - /// Query PartB - query = query.concat(fTraceStr); - for (String trace : fTraceListB) { - if (!trace.equals("Total")) { //$NON-NLS-1$ - query = query.concat(trace); - query = query.concat(","); //$NON-NLS-1$ - } - } - query = query.concat(System.lineSeparator()); - - query = query.concat(Messages.MultipleDensityView_From); - query = query.concat(fStartTimeB.toString(fFormat)); - query = query.concat(System.lineSeparator()); - - query = query.concat(Messages.MultipleDensityView_To); - query = query.concat(fEndTimeB.toString(fFormat)); - query = query.concat(System.lineSeparator()); - - //// Query Statistic Part - query = query.concat(fStatisticStr); - query = query.concat(fStatistic); - - return query; - } - - @SuppressWarnings("null") - boolean parseQuery(String query) { - try { - String[] parts = query.split(System.lineSeparator()); - // Times - - if (parts[1].indexOf(Messages.MultipleDensityView_From) == -1) { - return false; - } - String fromStrA = parts[1].substring(parts[1].indexOf(Messages.MultipleDensityView_From) + Messages.MultipleDensityView_From.length(), parts[1].length()); - fStartTimeA = TmfTimestamp.fromNanos(fFormat.parseValue(fromStrA)); - - if (parts[2].indexOf(Messages.MultipleDensityView_To) == -1) { - return false; - } - String toStrA = parts[2].substring(parts[2].indexOf(Messages.MultipleDensityView_To) + Messages.MultipleDensityView_To.length(), parts[2].length()); - fEndTimeA = TmfTimestamp.fromNanos(fFormat.parseValue(toStrA)); - - if (parts[5].indexOf(Messages.MultipleDensityView_From) == -1) { - return false; - } - String fromStrB = parts[5].substring(parts[5].indexOf(Messages.MultipleDensityView_From) + Messages.MultipleDensityView_From.length(), parts[5].length()); - fStartTimeB = TmfTimestamp.fromNanos(fFormat.parseValue(fromStrB)); - - if (parts[6].indexOf(Messages.MultipleDensityView_To) == -1) { - return false; - } - String toStrB = parts[6].substring(parts[6].indexOf(Messages.MultipleDensityView_To) + Messages.MultipleDensityView_To.length(), parts[6].length()); - fEndTimeB = TmfTimestamp.fromNanos(fFormat.parseValue(toStrB)); - - // traceListA - fTraceListA.clear(); - - if (parts[0].indexOf(fTraceStr) == -1) { - return false; - } - String traceStrtA = parts[0].substring(parts[0].indexOf(fTraceStr) + fTraceStr.length(), parts[0].length()); - String[] traces = traceStrtA.split(","); //$NON-NLS-1$ - - for (String trace : traces) { - fTraceListA.add(trace); - } - - // traceListB - fTraceListB.clear(); - String traceStrtB = parts[4].substring(parts[4].indexOf(fTraceStr) + fTraceStr.length(), parts[4].length()); - String[] tracesB = traceStrtB.split(","); //$NON-NLS-1$ - - for (String trace : tracesB) { - fTraceListB.add(trace); - } - //// Statistic - fStatistic = parts[7].substring(parts[7].indexOf(fStatisticStr) + fStatisticStr.length(), parts[7].length()); - - //Set time range related objects - ftextAFrom.setText(fStartTimeA.toString(fFormat)); - ftextATo.setText(fEndTimeA.toString(fFormat)); - - ftextBFrom.setText(fStartTimeB.toString(fFormat)); - ftextBTo.setText(fEndTimeB.toString(fFormat)); - - - } catch (ParseException e) { - // TODO Auto-generated catch block - System.out.println("query format is incorrect " + e.toString()); //$NON-NLS-1$ - e.printStackTrace(); - return false; - } - return true; - } -} \ No newline at end of file diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/MultipleEventDensityViewer.java b/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/MultipleEventDensityViewer.java deleted file mode 100644 index 83878cf99..000000000 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/MultipleEventDensityViewer.java +++ /dev/null @@ -1,135 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2024 École Polytechnique de Montréal - * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License 2.0 which - * accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package org.eclipse.tracecompass.incubator.internal.executioncomparison.ui; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.tracecompass.incubator.internal.executioncomparison.core.TmfCheckboxChangedSignal; -import org.eclipse.tracecompass.internal.tmf.ui.viewers.eventdensity.EventDensityViewer; -import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel; -import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal; -import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; -import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; -import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; -import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; -import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; -import org.eclipse.tracecompass.tmf.ui.viewers.tree.ITmfTreeViewerEntry; -import org.eclipse.tracecompass.tmf.ui.viewers.tree.TmfGenericTreeEntry; -import org.eclipse.tracecompass.tmf.ui.viewers.xychart.linechart.TmfXYChartSettings; - -/** - * MultipleEventDensityViewer extends EventDensityViewer to override handleCheckStateChangedEvent and reflect - * changes to differential flame graph - * @author Fateme Faraji Daneshgar - - */ -@SuppressWarnings("restriction") -public class MultipleEventDensityViewer extends EventDensityViewer { - List fWholeTraceList = new ArrayList<>(); - - /** - * @param parent - * Composite - * @param settings - * ChartSetting - */ - public MultipleEventDensityViewer(Composite parent, TmfXYChartSettings settings) { - super(parent, settings); - } - - @Override - @TmfSignalHandler - public void selectionRangeUpdated(@Nullable TmfSelectionRangeUpdatedSignal signal) { - if (signal == null) { - return; - } - - if (!(signal.getSource() instanceof MultipleEventDensityViewer)) { - final ITmfTrace trace = getTrace(); - if (trace != null) { - ITmfTimestamp selectedTime = signal.getBeginTime(); - ITmfTimestamp selectedEndTime = signal.getEndTime(); - TmfTraceManager.getInstance().updateTraceContext(trace, - builder -> builder.setSelection(new TmfTimeRange(selectedTime, selectedEndTime))); - - } - super.selectionRangeUpdated(signal); - } - if (signal.getSource()==this) { - final ITmfTrace trace = getTrace(); - if (trace != null) { - long selectedTime = signal.getBeginTime().toNanos(); - long selectedEndTime = signal.getEndTime().toNanos(); - setSelectionRange(selectedTime, selectedEndTime); - } - } - } - /** - * handles check state of tree viewer and keeps the list of whole trace list - * and dispatch TmfCheckboxChangedSignal signal to update the differential flame graph - * @param entries - * list of entries that should be checked - */ - - @SuppressWarnings("unchecked") - @Override - public void handleCheckStateChangedEvent(Collection entries) { - super.handleCheckStateChangedEvent(entries); - updateTraceList(entries); - List traceNames = new ArrayList<>(); - for (ITmfTreeViewerEntry entry : entries) { - if (entry instanceof TmfGenericTreeEntry) { - TmfGenericTreeEntry genericEntry = (TmfGenericTreeEntry) entry; - String name = genericEntry.getModel().getName(); - traceNames.add(name); - } - } - TmfSignalManager.dispatchSignal(new TmfCheckboxChangedSignal(this, traceNames)); - } - /* - * Keeps fWholeTraceList updated to include all entries for experiment. it will be used when - * checkedboxtree is reset. - */ - private void updateTraceList(Collection entries) { - for(ITmfTreeViewerEntry entry:entries) { - if (!fWholeTraceList.contains(entry)) { - fWholeTraceList.add(entry); - } - } - - } - - - /** - * get WholeCheckedItems which is the checked item in the tree viewer - * @return - * fWholeTraceList list of checked Items in tree viewer - */ - public List getWholeCheckedItems(){ - return fWholeTraceList; - } - - /** - * just handles check state of the treeviewer, used in updating tree viewers with query updating - * @param entries - * list of entries that should be checked - */ - public void UpdateCheckStateChangedEvent(Collection entries) { - super.handleCheckStateChangedEvent(entries); - } - -} \ No newline at end of file diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/messages.properties b/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/messages.properties deleted file mode 100644 index 1f655408f..000000000 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/messages.properties +++ /dev/null @@ -1,23 +0,0 @@ -############################################################################### - # Copyright (c) 2024 École Polytechnique de Montréal - # - # All rights reserved. This program and the accompanying materials are - # made available under the terms of the Eclipse Public License 2.0 which - # accompanies this distribution, and is available at - # https://www.eclipse.org/legal/epl-2.0/ - # - # SPDX-License-Identifier: EPL-2.0 -############################################################################### -MultipleDensityView_GroupA=GroupA -MultipleDensityView_GroupB=GroupB -MultipleDensityView_QueryGroup = Filtering Query -MultipleDensityView_QueryCompare=Compare to: -MultipleDensityView_From = From: -MultipleDensityView_To=To: -MultipleDensityView_Duration=Duration -MultipleDensityView_SelfTime=Self Time -MultipleDensityView_title=Execution Comparison -FlameGraphView_RetrievingData=Retrieving Flame Graph Data -FlameGraphView_GroupByName=Group by Descriptor -FlameGraphView_StatisticTooltip=Select the statistic to represent -MultipleDensityView_QueryExpandable=Get filtering query \ No newline at end of file diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision/feature.xml b/analyses/org.eclipse.tracecompass.incubator.executioncomparision/feature.xml deleted file mode 100644 index ea19102a8..000000000 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision/feature.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - %description - - - - %copyright - - - - %license - - - - - - - - - diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/.classpath b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/.classpath similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/.classpath rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/.classpath diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/.gitignore b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/.gitignore similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/.gitignore rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/.gitignore diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/.project b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/.project similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/.project rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/.project diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/.settings/org.eclipse.core.resources.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/.settings/org.eclipse.core.resources.prefs similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/.settings/org.eclipse.core.resources.prefs rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/.settings/org.eclipse.core.resources.prefs diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/.settings/org.eclipse.core.runtime.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/.settings/org.eclipse.core.runtime.prefs similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/.settings/org.eclipse.core.runtime.prefs rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/.settings/org.eclipse.core.runtime.prefs diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/.settings/org.eclipse.jdt.core.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/.settings/org.eclipse.jdt.core.prefs similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/.settings/org.eclipse.jdt.core.prefs rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/.settings/org.eclipse.jdt.core.prefs diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/.settings/org.eclipse.jdt.ui.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/.settings/org.eclipse.jdt.ui.prefs similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/.settings/org.eclipse.jdt.ui.prefs rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/.settings/org.eclipse.jdt.ui.prefs diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/.settings/org.eclipse.pde.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/.settings/org.eclipse.pde.prefs similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/.settings/org.eclipse.pde.prefs rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/.settings/org.eclipse.pde.prefs diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/META-INF/MANIFEST.MF b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/META-INF/MANIFEST.MF similarity index 96% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/META-INF/MANIFEST.MF rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/META-INF/MANIFEST.MF index af7ba2828..c799ebcfc 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/META-INF/MANIFEST.MF +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/META-INF/MANIFEST.MF @@ -13,4 +13,4 @@ Require-Bundle: org.eclipse.core.runtime, org.junit, org.eclipse.jdt.annotation;bundle-version="[2.0.0,3.0.0)";resolution:=optional Export-Package: org.eclipse.tracecompass.incubator.executioncomparison.core.tests -Automatic-Module-Name: org.eclipse.tracecompass.incubator.executioncomparision.core.tests +Automatic-Module-Name: org.eclipse.tracecompass.incubator.executioncomparison.core.tests diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/about.html b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/about.html similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/about.html rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/about.html diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/build.properties b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/build.properties similarity index 91% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/build.properties rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/build.properties index fc2472710..2728cc2dd 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/build.properties +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/build.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2022 École Polytechnique de Montréal +# Copyright (c) 2024 École Polytechnique de Montréal # # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/plugin.properties b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/plugin.properties similarity index 78% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/plugin.properties rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/plugin.properties index 34e0fb51c..dc5ff561b 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/plugin.properties +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/plugin.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2022 École Polytechnique de Montréal +# Copyright (c) 2024 École Polytechnique de Montréal # # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 @@ -10,4 +10,4 @@ ############################################################################### Bundle-Vendor = Eclipse Trace Compass Incubator -Bundle-Name = Trace Compass ExecutionComparision Core Plug-in (Incubator) +Bundle-Name = Trace Compass Incubator ExecutionComparison Core Tests Plug-in diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/src/org/eclipse/tracecompass/incubator/executioncomparison/core/tests/ActivatorTest.java b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/src/org/eclipse/tracecompass/incubator/executioncomparison/core/tests/ActivatorTest.java similarity index 98% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/src/org/eclipse/tracecompass/incubator/executioncomparison/core/tests/ActivatorTest.java rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/src/org/eclipse/tracecompass/incubator/executioncomparison/core/tests/ActivatorTest.java index cfd2bb50e..ff543e81c 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core.tests/src/org/eclipse/tracecompass/incubator/executioncomparison/core/tests/ActivatorTest.java +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core.tests/src/org/eclipse/tracecompass/incubator/executioncomparison/core/tests/ActivatorTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024 École Polytechnique de Montréal + * Copyright (c) 2024 École Polytechnique de Montréal, Ericsson * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License 2.0 which @@ -119,4 +119,3 @@ public static IPath getAbsoluteFilePath(String relativePath) { } } - diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/.classpath b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/.classpath similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/.classpath rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/.classpath diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/.gitignore b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/.gitignore similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/.gitignore rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/.gitignore diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/.project b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/.project similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/.project rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/.project diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/.settings/org.eclipse.core.resources.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/.settings/org.eclipse.core.resources.prefs similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/.settings/org.eclipse.core.resources.prefs rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/.settings/org.eclipse.core.resources.prefs diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/.settings/org.eclipse.core.runtime.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/.settings/org.eclipse.core.runtime.prefs similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/.settings/org.eclipse.core.runtime.prefs rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/.settings/org.eclipse.core.runtime.prefs diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/.settings/org.eclipse.jdt.core.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/.settings/org.eclipse.jdt.core.prefs similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/.settings/org.eclipse.jdt.core.prefs rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/.settings/org.eclipse.jdt.core.prefs diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/.settings/org.eclipse.jdt.ui.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/.settings/org.eclipse.jdt.ui.prefs similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/.settings/org.eclipse.jdt.ui.prefs rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/.settings/org.eclipse.jdt.ui.prefs diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/.settings/org.eclipse.pde.api.tools.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/.settings/org.eclipse.pde.api.tools.prefs similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/.settings/org.eclipse.pde.api.tools.prefs rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/.settings/org.eclipse.pde.api.tools.prefs diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/.settings/org.eclipse.pde.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/.settings/org.eclipse.pde.prefs similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/.settings/org.eclipse.pde.prefs rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/.settings/org.eclipse.pde.prefs diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/META-INF/MANIFEST.MF b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/META-INF/MANIFEST.MF similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/META-INF/MANIFEST.MF rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/META-INF/MANIFEST.MF diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/about.html b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/about.html similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/about.html rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/about.html diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/build.properties b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/build.properties similarity index 91% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/build.properties rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/build.properties index 21645b6d6..ae7c9d8b8 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/build.properties +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/build.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2022 École Polytechnique de Montréal +# Copyright (c) 2024 École Polytechnique de Montréal # # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/plugin.properties b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/plugin.properties similarity index 79% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/plugin.properties rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/plugin.properties index 096c865e8..03ba2b45e 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/plugin.properties +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/plugin.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2022 École Polytechnique de Montréal +# Copyright (c) 2024 École Polytechnique de Montréal # # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 @@ -10,5 +10,4 @@ ############################################################################### Bundle-Vendor = Eclipse Trace Compass Incubator -Bundle-Name = Trace Compass ExecutionComparision UI Plug-in (Incubator) - +Bundle-Name = Trace Compass ExecutionComparison Core Plug-in (Incubator) diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/plugin.xml b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/plugin.xml new file mode 100644 index 000000000..e52f920a2 --- /dev/null +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/plugin.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/Activator.java b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/Activator.java similarity index 87% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/Activator.java rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/Activator.java index 64c8a0bcc..fd383d292 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/Activator.java +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/Activator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024 École Polytechnique de Montréal + * Copyright (c) 2024 École Polytechnique de Montréal, Ericsson * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License 2.0 which @@ -14,7 +14,9 @@ import org.eclipse.tracecompass.common.core.TraceCompassActivator; /** - * Activator + * Plug-in activator + * + * @author Fateme Faraji Daneshgar and Vlad Arama */ public class Activator extends TraceCompassActivator { @@ -39,11 +41,12 @@ public static TraceCompassActivator getInstance() { @Override protected void startActions() { + // Do nothing } @Override protected void stopActions() { + // Do nothing } } - diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/DifferentialCallGraphProvider.java b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/DifferentialCallGraphProvider.java similarity index 84% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/DifferentialCallGraphProvider.java rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/DifferentialCallGraphProvider.java index 4672a2541..375357921 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/DifferentialCallGraphProvider.java +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/DifferentialCallGraphProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024 École Polytechnique de Montréal + * Copyright (c) 2024 École Polytechnique de Montréal, Ericsson * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License 2.0 which @@ -11,6 +11,7 @@ package org.eclipse.tracecompass.incubator.internal.executioncomparison.core; +import java.util.ArrayList; import java.util.Collection; import org.eclipse.tracecompass.analysis.profiling.core.callgraph.AggregatedCallSite; @@ -25,9 +26,10 @@ import org.eclipse.tracecompass.incubator.analysis.core.weighted.tree.diff.DifferentialWeightedTreeSet; /** - * DifferentialCallGraphProvider which provide a callgraphProvider. Inherited from DifferentialWeightedTreeProvider - * to edit naming and color ICallGraphProviderpalette to provide a differential flame graph - * @author Fateme Faraji Daneshgar + * DifferentialCallGraphProvider provides a callgraphProvider. It is inherited + * from DifferentialWeightedTreeProvider to edit the naming and color. + * + * @author Fateme Faraji Daneshgar and Vlad Arama */ public class DifferentialCallGraphProvider extends DifferentialWeightedTreeProvider { @@ -39,7 +41,7 @@ public class DifferentialCallGraphProvider extends DifferentialWeightedTreeProvi * @param instrumentedCallStackAnalysis * the original tree * @param trees - * the other trees to compare + * the other trees to compare to */ public DifferentialCallGraphProvider(IWeightedTreeProvider instrumentedCallStackAnalysis, Collection> trees) { @@ -55,11 +57,10 @@ public DifferentialCallGraphProvider(IWeightedTreeProvider> originalTree, DifferentialWeightedTreeSet treeSet) { - super((IWeightedTreeProvider>)originalTree, treeSet); + super((IWeightedTreeProvider>) originalTree, treeSet); fOriginalTree = (ICallGraphProvider2) originalTree; } @@ -68,7 +69,6 @@ public IDataPalette getPalette() { return DifferentialFlamePalette.getInstance(); } - @SuppressWarnings("null") @Override public String toDisplayString(DifferentialWeightedTree tree) { double difference = tree.getDifference(); @@ -76,15 +76,13 @@ public String toDisplayString(DifferentialWeightedTree tree) { String label = ""; //$NON-NLS-1$ if (originalTree instanceof AggregatedCallSite) { label = fOriginalTree.toDisplayString((AggregatedCallSite) originalTree); - } - else { - label = String.valueOf(originalTree.getObject().resolve(null)); + } else { + label = String.valueOf(originalTree.getObject().resolve(new ArrayList<>())); } if (Double.isFinite(difference)) { - return String.format("(%#.02f %% ) %s", difference * 100, label); //$NON-NLS-1$ + return String.format("(%#+.02f %% ) %s", difference * 100, label); //$NON-NLS-1$ } return label; - } -} \ No newline at end of file +} diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/DifferentialFlamePalette.java b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/DifferentialFlamePalette.java similarity index 93% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/DifferentialFlamePalette.java rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/DifferentialFlamePalette.java index b1f8871a8..f5da804be 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/DifferentialFlamePalette.java +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/DifferentialFlamePalette.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024 École Polytechnique de Montréal + * Copyright (c) 2024 École Polytechnique de Montréal, Ericsson * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License 2.0 which @@ -29,14 +29,15 @@ import com.google.common.collect.ImmutableMap; /** - * Class to manage the colors of the differential flame graph views + * Manages the colors of the differential flame graph view * - * @author Fateme Faraji Daneshgar + * @author Fateme Faraji Daneshgar and Vlad Arama */ public final class DifferentialFlamePalette implements IDataPalette { private static final String NAN = Objects.requireNonNull(Objects.toString(Double.NaN)); private static final String NO_DIFFERENCE = "NO-Difference"; //$NON-NLS-1$ + private static String generateRed(int i) { return "RED" + i; //$NON-NLS-1$ } @@ -55,11 +56,12 @@ private static String generateBlue(int i) { private static final String RED_COLOR = Objects.requireNonNull(X11ColorUtils.toHexColor(255, 0, 0)); private static final String WHITE_COLOR = Objects.requireNonNull(X11ColorUtils.toHexColor(255, 255, 255)); - private static final Map STYLES; // Map of styles with the parent private static final Map STYLE_MAP = Collections.synchronizedMap(new HashMap<>()); + private static @Nullable DifferentialFlamePalette fInstance = null; + static { IPaletteProvider palette = new RotatingPaletteProvider.Builder().setNbColors(NUM_COLORS).build(); int i = 0; @@ -72,7 +74,7 @@ private static String generateBlue(int i) { StyleProperties.BORDER_STYLE, StyleProperties.BorderStyle.SOLID))); i++; } - int j=0; + int j = 0; // Add dark red color for Nan builder.put(NAN, new OutputElementStyle(null, ImmutableMap.of( StyleProperties.STYLE_NAME, NAN, @@ -88,7 +90,7 @@ private static String generateBlue(int i) { StyleProperties.BORDER_STYLE, StyleProperties.BorderStyle.SOLID))); // Add Blue color palette for Shorter duration for (i = MIN_HUE; i <= MAX_HUE; i++) { - j = (i-50)>0 ? i-50:0; + j = (i - 50) > 0 ? i - 50 : 0; String blueKey = generateBlue(i); builder.put(blueKey, new OutputElementStyle(null, ImmutableMap.of( StyleProperties.STYLE_NAME, blueKey, @@ -109,9 +111,6 @@ private static String generateBlue(int i) { STYLE_MAP.putAll(STYLES); } - - private static @Nullable DifferentialFlamePalette fInstance = null; - private DifferentialFlamePalette() { // Do nothing } @@ -153,11 +152,11 @@ public OutputElementStyle getStyleFor(Object object) { if (object instanceof DifferentialWeightedTree) { DifferentialWeightedTree tree = (DifferentialWeightedTree) object; double difference = tree.getDifference(); - double step = MAX_HUE - MIN_HUE; + double step = (double) MAX_HUE - (double) MIN_HUE; if (Double.isNaN(difference)) { return STYLE_MAP.computeIfAbsent(NAN, OutputElementStyle::new); } - if ((difference <= 0.05) &&(difference >= -0.05)) { + if ((difference <= 0.05) && (difference >= -0.05)) { return STYLE_MAP.computeIfAbsent(NO_DIFFERENCE, OutputElementStyle::new); } if (difference < 0) { @@ -175,10 +174,13 @@ public OutputElementStyle getStyleFor(Object object) { } /** - * @param min the minimum threshold for coloring. + * Sets the minimum threshold for coloring + * + * @param min + * the minimum threshold for coloring. */ public static void setMinThreshold(double min) { fMinThreshold = Math.round(min); } -} \ No newline at end of file +} diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/DifferentialSeqCallGraphAnalysis.java b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/DifferentialSeqCallGraphAnalysis.java similarity index 67% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/DifferentialSeqCallGraphAnalysis.java rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/DifferentialSeqCallGraphAnalysis.java index c25fb115d..40e73283c 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/DifferentialSeqCallGraphAnalysis.java +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/DifferentialSeqCallGraphAnalysis.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024 École Polytechnique de Montréal + * Copyright (c) 2024 École Polytechnique de Montréal, Ericsson * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License 2.0 which @@ -17,12 +17,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jdt.annotation.NonNull; @@ -35,17 +35,16 @@ import org.eclipse.tracecompass.analysis.profiling.core.instrumented.InstrumentedCallStackAnalysis; import org.eclipse.tracecompass.analysis.profiling.core.tree.ITree; import org.eclipse.tracecompass.analysis.profiling.core.tree.IWeightedTreeProvider; -import org.eclipse.tracecompass.analysis.profiling.core.tree.IWeightedTreeSet; import org.eclipse.tracecompass.analysis.profiling.core.tree.WeightedTree; import org.eclipse.tracecompass.analysis.profiling.core.tree.WeightedTreeSet; import org.eclipse.tracecompass.common.core.log.TraceCompassLog; import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.ScopeLog; import org.eclipse.tracecompass.incubator.analysis.core.weighted.tree.diff.DifferentialWeightedTree; import org.eclipse.tracecompass.incubator.analysis.core.weighted.tree.diff.DifferentialWeightedTreeProvider; -import org.eclipse.tracecompass.incubator.analysis.core.weighted.tree.diff.DifferentialWeightedTreeSet; +import org.eclipse.tracecompass.incubator.analysis.core.weighted.tree.diff.WeightedTreeUtils; import org.eclipse.tracecompass.internal.analysis.profiling.core.callgraph2.AggregatedCalledFunction; +import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule; import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule; -import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; @@ -58,11 +57,10 @@ import com.google.common.collect.Iterables; /** - * build a differential call graph using the differentialWeightedTreeSet from + * Builds a differential call graph using the differentialWeightedTreeSet from * two sets of call graphs. * - * - * @author Fateme Faraji Daneshgar + * @author Fateme Faraji Daneshgar and Vlad Arama */ @SuppressWarnings("restriction") public class DifferentialSeqCallGraphAnalysis extends TmfAbstractAnalysisModule { @@ -72,11 +70,11 @@ public class DifferentialSeqCallGraphAnalysis extends TmfAbstractAnalysisModule */ public static final String ID = "org.eclipse.tracecompass.incubator.executioncomparison.diffcallgraph"; //$NON-NLS-1$ private static final Logger LOGGER = TraceCompassLog.getLogger(DifferentialSeqCallGraphAnalysis.class); - private static final String MERGE = "Merge"; //$NON-NLS-1$ - private @Nullable DifferentialCallGraphProvider fDifferentialCallGraphProvider; - private static Map fcallStackAnalysisMap = new HashMap<>(); + private static Map fCallStackAnalysisMap = new HashMap<>(); private static Map fTraceCallGraphRegistry = new HashMap<>(); + + private @Nullable DifferentialCallGraphProvider fDifferentialCallGraphProvider; private ITmfTimestamp fStartA = TmfTimestamp.BIG_BANG; private ITmfTimestamp fEndA = TmfTimestamp.BIG_CRUNCH; private ITmfTimestamp fStartB = TmfTimestamp.BIG_BANG; @@ -92,8 +90,8 @@ public class DifferentialSeqCallGraphAnalysis extends TmfAbstractAnalysisModule public DifferentialSeqCallGraphAnalysis() { super(); // TODO: Make a way to register tracetype->callstack IDs. - fcallStackAnalysisMap.put("org.eclipse.tracecompass.incubator.traceevent.core.trace", "org.eclipse.tracecompass.incubator.traceevent.analysis.callstack"); //$NON-NLS-1$ //$NON-NLS-2$ - fcallStackAnalysisMap.put("org.eclipse.linuxtools.lttng2.ust.tracetype", "org.eclipse.tracecompass.lttng2.ust.core.analysis.callstack"); //$NON-NLS-1$ //$NON-NLS-2$ + fCallStackAnalysisMap.put("org.eclipse.tracecompass.incubator.traceevent.core.trace", "org.eclipse.tracecompass.incubator.traceevent.analysis.callstack"); //$NON-NLS-1$ //$NON-NLS-2$ + fCallStackAnalysisMap.put("org.eclipse.linuxtools.lttng2.ust.tracetype", "org.eclipse.tracecompass.lttng2.ust.core.analysis.callstack"); //$NON-NLS-1$ //$NON-NLS-2$ } /** @@ -101,8 +99,9 @@ public DifferentialSeqCallGraphAnalysis() { * * @param monitor * the progress monitor + * @return the differential call graph provider */ - public void refreshDiffCG(@Nullable IProgressMonitor monitor) { + public DifferentialCallGraphProvider refreshDiffCG(@Nullable IProgressMonitor monitor) { try (ScopeLog sl = new ScopeLog(LOGGER, Level.CONFIG, "DifferentialSequenceCGA::refresh()")) { //$NON-NLS-1$ Collection> originalTree = new ArrayList<>(); Collection> diffTree = new ArrayList<>(); @@ -119,18 +118,19 @@ public void refreshDiffCG(@Nullable IProgressMonitor monitor) { } Collection> trees; - trees = ParametricWeightedTreeUtils.diffTrees(originalTree, diffTree, fStatistic); + trees = WeightedTreeUtils.diffTrees(originalTree, diffTree, fStatistic); IWeightedTreeProvider instrumentedCallStackAnalysis = Iterables.get(fTraceCallGraphRegistry.values(), 0); - setDifferentialCallGraphProvider(new DifferentialCallGraphProvider(instrumentedCallStackAnalysis, trees)); + fDifferentialCallGraphProvider = new DifferentialCallGraphProvider(instrumentedCallStackAnalysis, trees); + return fDifferentialCallGraphProvider; } } /** - * Merge callgraph + * Merges call graph * * @param start - * the start time + * the start time stamp * @param end * the end time stamp * @param traceList @@ -139,28 +139,11 @@ public void refreshDiffCG(@Nullable IProgressMonitor monitor) { * */ public WeightedTreeSet mergeCallGraph(ITmfTimestamp start, ITmfTimestamp end, List traceList) { - try (ScopeLog sl = new ScopeLog(LOGGER, Level.FINE, "DifferenentialSequenceCGA::MergeCallGraph")) { //$NON-NLS-1$ - List cGList = new ArrayList<>(); + try (ScopeLog sl = new ScopeLog(LOGGER, Level.FINE, "DifferentialSequenceCGA::MergeCallGraph")) { //$NON-NLS-1$ WeightedTreeSet newTreeSet = new WeightedTreeSet<>(); String mainGroup = MERGE; - for (String traceName : traceList) { - ICallGraphProvider2 instrumentedCallStackAnalysis = fTraceCallGraphRegistry.get(traceName); - if (instrumentedCallStackAnalysis != null) { - ITmfTrace trace = getTrace(traceName); - ITmfTimestamp traceStart = start; - ITmfTimestamp traceEnd = end; - - if (traceStart.getValue()< trace.getStartTime().getValue()) { - traceStart = trace.getStartTime(); - } - if (traceEnd.getValue()> trace.getEndTime().getValue()) { - traceEnd = trace.getEndTime(); - } - cGList.add(instrumentedCallStackAnalysis.getCallGraph(traceStart, traceEnd)); - - } - } + List cGList = addToCallGraph(start, end, traceList); for (CallGraph callGraph : cGList) { Collection elements = getLeafElements(callGraph); @@ -173,26 +156,48 @@ public WeightedTreeSet mergeCallGraph(ITmfTimestamp st } /** - * get CallGraph + * Helper function that adds the call graphs for the specified time range + * and trace list to the call graph list. * - * @return DifferentialCallGraph + * @param start + * the start time of the time range + * @param end + * the end time of the time range + * @param traceList + * the list of trace names + * @return the list of call graphs */ - public IWeightedTreeSet> getCallGraph() { - DifferentialCallGraphProvider differentialCallGraphProvider = getDifferentialCallGraphProvider(); - if (differentialCallGraphProvider != null) { - return differentialCallGraphProvider.getTreeSet(); + private static List addToCallGraph(ITmfTimestamp start, ITmfTimestamp end, List traceList) { + List cGList = new ArrayList<>(); + for (String traceName : traceList) { + ICallGraphProvider2 instrumentedCallStackAnalysis = fTraceCallGraphRegistry.get(traceName); + if (instrumentedCallStackAnalysis != null) { + ITmfTrace trace = getTrace(traceName); + if (trace != null) { + ITmfTimestamp traceStart = start; + ITmfTimestamp traceEnd = end; + + if (traceStart.getValue() < trace.getStartTime().getValue()) { + traceStart = trace.getStartTime(); + } + if (traceEnd.getValue() > trace.getEndTime().getValue()) { + traceEnd = trace.getEndTime(); + } + cGList.add(instrumentedCallStackAnalysis.getCallGraph(traceStart, traceEnd)); + } + } } - return new DifferentialWeightedTreeSet<>(); + return cGList; } /** - * Get the differential weighted tree provider + * Gets the differential weighted tree provider * * @param monitor - * the monitor, can be null + * the progress monitor, can be null * @return the differential weighted provider or null */ - public @Nullable DifferentialWeightedTreeProvider getDiffProvider(@Nullable IProgressMonitor monitor) { + public @Nullable DifferentialWeightedTreeProvider getDifferentialTreeProvider(IProgressMonitor monitor) { if (fTraceCallGraphRegistry.isEmpty()) { InstrumentedCallStackAnalysis callGraphModule; ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace(); @@ -200,11 +205,16 @@ public IWeightedTreeSet modules = TmfTraceUtils.getAnalysisModulesOfClass(traceMember, InstrumentedCallStackAnalysis.class); for (InstrumentedCallStackAnalysis module : modules) { - if (module.getId().equals(fcallStackAnalysisMap.get(traceMember.getTraceTypeId()))) { + if (module.getId().equals(fCallStackAnalysisMap.get(traceMember.getTraceTypeId()))) { callGraphModule = module; callGraphModule.schedule(); fTraceCallGraphRegistry.put(String.valueOf(traceMember.getName()), callGraphModule); - callGraphModule.waitForCompletion(); + while (!callGraphModule.waitForCompletion()) { + if (monitor.isCanceled()) { + callGraphModule.cancel(); + return null; + } + } break; } } @@ -212,25 +222,7 @@ public IWeightedTreeSet getLeafElement(ICallStackElement group) { } private static void recurseAddElementData(ICallStackElement element, String group, CallGraph callGraph, WeightedTreeSet newTreeSet) { - // Add the current level of trees to the new tree set for (AggregatedCallSite tree : callGraph.getCallingContextTree(element)) { newTreeSet.addWeightedTree(group, tree.copyOf()); @@ -271,22 +262,51 @@ private static void recurseAddElementData(ICallStackElement element, String grou } @Override - protected boolean executeAnalysis(IProgressMonitor monitor) throws TmfAnalysisException { + protected boolean executeAnalysis(IProgressMonitor monitor) { + synchronized (this) { + if (fDiffJob != null) { + fDiffJob.cancel(); + } + fDiffJob = new Job("Make differential Callgraph") { //$NON-NLS-1$ + @Override + protected IStatus run(@Nullable IProgressMonitor progressMonitor) { + refreshDiffCG(progressMonitor); + if (progressMonitor != null) { + progressMonitor.done(); + } + return Status.OK_STATUS; + } + }; + fDiffJob.schedule(); + } return true; } @Override public boolean waitForCompletion() { - return true; - + if (fDiffJob != null) { + try { + fDiffJob.join(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return false; + } + return true; + } + return false; } @Override protected void canceling() { - + if (fDiffJob != null) { + fDiffJob.cancel(); + } + super.cancel(); } /** + * Update the selection range + * * @param signal * TmfComparisonFilteringUpdatedSignal raised when filtering * parameter are changed @@ -305,82 +325,97 @@ public void selectionRangeUpdated(TmfComparisonFilteringUpdatedSignal signal) { // tuning fTraceList List traceListA = signal.getTraceListA(); if (traceListA != null) { - List synchronizedListA = Collections.synchronizedList(fTraceListA); - synchronized (synchronizedListA) { - synchronizedListA.clear(); - for (String name : traceListA) { - synchronizedListA.add(name); - } - } + synchronizedListAdd(traceListA, fTraceListA); } List traceListB = signal.getTraceListB(); if (traceListB != null) { - List synchronizedListB = Collections.synchronizedList(fTraceListB); - synchronizedListB.clear(); - for (String name : traceListB) { - synchronizedListB.add(name); - } + synchronizedListAdd(traceListB, fTraceListB); } if (!fTraceCallGraphRegistry.isEmpty()) { try (ScopeLog sl = new ScopeLog(LOGGER, Level.FINE, "MakeDiffCallGraph")) { //$NON-NLS-1$ - synchronized (this) { - if (fDiffJob != null) { - fDiffJob.cancel(); - } - fDiffJob = new Job("Make differential Callgraph") { //$NON-NLS-1$ - @Override - protected IStatus run(@Nullable IProgressMonitor monitor) { - refreshDiffCG(monitor); - if (monitor != null) { - monitor.done(); - } - return Status.OK_STATUS; - } - }; - fDiffJob.schedule(); - } + IProgressMonitor monitor = new NullProgressMonitor(); + executeAnalysis(monitor); + } + } + } + + /** + * Helper function that adds all elements from the given traceList to the + * given fTraceList in a thread-safe manner. + * + * @param traceList + * the list of strings to be added + * @param fTraceList + * the list to which the strings will be added + * @return the synchronized list after adding the elements + */ + private static List synchronizedListAdd(List traceList, List fTraceList) { + List synchronizedList = Collections.synchronizedList(fTraceList); + synchronized (synchronizedList) { + synchronizedList.clear(); + for (String name : traceList) { + synchronizedList.add(name); } } + return synchronizedList; } @Override public boolean canExecute(ITmfTrace trace) { - return (trace instanceof TmfExperiment); - + if (trace instanceof TmfExperiment) { + for (ITmfTrace individualTrace : ((TmfExperiment) trace).getTraces()) { + Iterable modules = individualTrace.getAnalysisModules(); + for (IAnalysisModule module : modules) { + if (fCallStackAnalysisMap.containsValue(module.getId())) { + return true; + } + } + } + } + return false; } @Override public void dispose() { - super.dispose(); - TmfSignalManager.deregister(this); - } + try { + cancel(); + synchronized (this) { + if (fDiffJob != null) { + fDiffJob.cancel(); + fDiffJob = null; + } - /** - * @return the differentialCallGraphProvider - */ - private @Nullable DifferentialCallGraphProvider getDifferentialCallGraphProvider() { - return fDifferentialCallGraphProvider; - } + // Clear all data structures and fields + fTraceCallGraphRegistry.clear(); + fTraceListA.clear(); + fTraceListB.clear(); + fDifferentialCallGraphProvider = null; - /** - * @param differentialCallGraphProvider - * the differentialCallGraphProvider to set - */ - private void setDifferentialCallGraphProvider(DifferentialCallGraphProvider differentialCallGraphProvider) { - fDifferentialCallGraphProvider = Objects.requireNonNull(differentialCallGraphProvider); + fStartA = TmfTimestamp.BIG_BANG; + fEndA = TmfTimestamp.BIG_CRUNCH; + fStartB = TmfTimestamp.BIG_BANG; + fEndB = TmfTimestamp.BIG_CRUNCH; + } + TmfSignalManager.deregister(this); + + } finally { + super.dispose(); + } } - private static ITmfTrace getTrace(String traceName) { + + private static @Nullable ITmfTrace getTrace(String traceName) { ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace(); Collection traceSet = TmfTraceManager.getTraceSet(trace); for (ITmfTrace traceMember : traceSet) { if (traceMember.getName().equals(traceName)) { - return traceMember; - } + return traceMember; } + } return null; } + private List getTraceListA() { return new ArrayList<>(fTraceListA); } @@ -389,4 +424,4 @@ private List getTraceListB() { return new ArrayList<>(fTraceListB); } -} \ No newline at end of file +} diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/TmfCheckboxChangedSignal.java b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/TmfCheckboxChangedSignal.java similarity index 76% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/TmfCheckboxChangedSignal.java rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/TmfCheckboxChangedSignal.java index 9ef5dbd39..458cd55fe 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/TmfCheckboxChangedSignal.java +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/TmfCheckboxChangedSignal.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024 École Polytechnique de Montréal + * Copyright (c) 2024 École Polytechnique de Montréal, Ericsson * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License 2.0 which @@ -11,25 +11,26 @@ package org.eclipse.tracecompass.incubator.internal.executioncomparison.core; - import java.util.List; import org.eclipse.tracecompass.tmf.core.signal.TmfSignal; /** - * TmfCheckboxChangedSignal for handling check box change events + * Handles check-box change events * - * * @author Fateme Faraji Daneshgar + * * @author Fateme Faraji Daneshgar and Vlad Arama */ public class TmfCheckboxChangedSignal extends TmfSignal { private List fTraceList; /** + * Constructor + * * @param source - * the source class of signal + * the source class of signal * @param traceList - * the list of traces remains checked in the check box + * the list of traces remains checked in the check box */ public TmfCheckboxChangedSignal(Object source, List traceList) { super(source); @@ -37,12 +38,12 @@ public TmfCheckboxChangedSignal(Object source, List traceList) { } /** + * Getter for the trace list + * * @return the list of traces remains checked in the check box */ public List getTraceList() { return fTraceList; } - - } diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/TmfComparisonFilteringUpdatedSignal.java b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/TmfComparisonFilteringUpdatedSignal.java similarity index 68% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/TmfComparisonFilteringUpdatedSignal.java rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/TmfComparisonFilteringUpdatedSignal.java index 0b8490867..7754630f9 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/TmfComparisonFilteringUpdatedSignal.java +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/TmfComparisonFilteringUpdatedSignal.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024 École Polytechnique de Montréal + * Copyright (c) 2024 École Polytechnique de Montréal, Ericsson * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License 2.0 which @@ -18,9 +18,10 @@ import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; - /** + * Signal to notify that the comparison filtering has been updated. * + * @author Fateme Faraji Daneshgar and Vlad Arama */ public class TmfComparisonFilteringUpdatedSignal extends TmfSignal { @@ -33,22 +34,24 @@ public class TmfComparisonFilteringUpdatedSignal extends TmfSignal { private @Nullable List fTraceListB; /** + * Constructor + * * @param source - * the class that has generated the signal + * the class that has generated the signal * @param beginA - * the start time in event density chartA + * the start time in event density chartA * @param endA - * the end time in event density chartA + * the end time in event density chartA * @param beginB - * the start time in event density chartB + * the start time in event density chartB * @param endB - * the end time in event density chartA + * the end time in event density chartA * @param statistic - * the statistic that will be represented in the flame graph + * the statistic that will be represented in the flame graph * @param traceListA - * the list of traces in group A + * the list of traces in group A * @param traceListB - * the list of traces in group B + * the list of traces in group B */ public TmfComparisonFilteringUpdatedSignal(Object source, ITmfTimestamp beginA, ITmfTimestamp endA, ITmfTimestamp beginB, ITmfTimestamp endB, @Nullable String statistic, @Nullable List traceListA, @Nullable List traceListB) { super(source); @@ -62,64 +65,79 @@ public TmfComparisonFilteringUpdatedSignal(Object source, ITmfTimestamp beginA, } /** + * Constructor + * * @param source - * the class that has generated the signal - + * the class that has generated the signal * @param statistic - * the statistic that will be represented in the flame graph + * the statistic that will be represented in the flame graph * @param traceListA - * the list of traces in group A + * the list of traces in group A * @param traceListB - * the list of traces in group B + * the list of traces in group B */ public TmfComparisonFilteringUpdatedSignal(Object source, @Nullable String statistic, @Nullable List traceListA, @Nullable List traceListB) { this(source, TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH, TmfTimestamp.BIG_BANG, TmfTimestamp.BIG_CRUNCH, statistic, traceListA, traceListB); } /** - * @return The begin timestamp of selection in GroupA + * Get beginning of the timestamp in Group A + * + * @return The beginning of the timestamp of the selection in GroupA */ public ITmfTimestamp getBeginTimeA() { return fBeginTimeA; } /** - * @return The end timestamp of selection in GroupA + * Get the end of the timestamp in Group A + * + * @return The end of the timestamp of the selection in GroupA */ public ITmfTimestamp getEndTimeA() { return fEndTimeA; } /** - * @return The begin timestamp of selection in GroupB + * Get beginning of the timestamp in Group B + * + * @return The beginning of the timestamp of the selection in GroupB */ public ITmfTimestamp getBeginTimeB() { return fBeginTimeB; } /** - * @return The end timestamp of selection in GroupB + * Get the end of the timestamp in Group B + * + * @return The end of the timestamp of the selection in GroupB */ public ITmfTimestamp getEndTimeB() { return fEndTimeB; } /** - * @return the type of statistic that will be represented in flame graph + * Get the statistic type + * + * @return the type of statistic that will be represented in flame graph */ public @Nullable String getStatistic() { return fStatistic; } /** - * @return the list of traces in groupA + * Get the list of traces in Group A + * + * @return the list of traces in Group A */ public @Nullable List getTraceListA() { return fTraceListA; } /** - * @return the list of traces in groupB + * Get the list of traces in Group B + * + * @return the list of traces in Group B */ public @Nullable List getTraceListB() { return fTraceListB; diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/package-info.java b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/package-info.java similarity index 61% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/package-info.java rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/package-info.java index 3bdbb38a8..7501a1ca9 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/package-info.java +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.core/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/core/package-info.java @@ -1,10 +1,9 @@ /******************************************************************************* - * Copyright (c) 2024 École Polytechnique de Montréal + * Copyright (c) 2024 École Polytechnique de Montréal, Ericsson * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License 2.0 which - * accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 which accompanies + * this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.classpath b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/.classpath similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.classpath rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/.classpath diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.gitignore b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/.gitignore similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.gitignore rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/.gitignore diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.project b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/.project similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.project rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/.project diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.settings/.api_filters b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/.settings/.api_filters similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.settings/.api_filters rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/.settings/.api_filters diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.settings/org.eclipse.core.resources.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/.settings/org.eclipse.core.resources.prefs similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.settings/org.eclipse.core.resources.prefs rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/.settings/org.eclipse.core.resources.prefs diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.settings/org.eclipse.core.runtime.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/.settings/org.eclipse.core.runtime.prefs similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/.settings/org.eclipse.core.runtime.prefs rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/.settings/org.eclipse.core.runtime.prefs diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.settings/org.eclipse.jdt.core.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/.settings/org.eclipse.jdt.core.prefs similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.settings/org.eclipse.jdt.core.prefs rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/.settings/org.eclipse.jdt.core.prefs diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.settings/org.eclipse.jdt.ui.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/.settings/org.eclipse.jdt.ui.prefs similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.settings/org.eclipse.jdt.ui.prefs rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/.settings/org.eclipse.jdt.ui.prefs diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.settings/org.eclipse.pde.api.tools.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/.settings/org.eclipse.pde.api.tools.prefs similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.settings/org.eclipse.pde.api.tools.prefs rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/.settings/org.eclipse.pde.api.tools.prefs diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.settings/org.eclipse.pde.prefs b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/.settings/org.eclipse.pde.prefs similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/.settings/org.eclipse.pde.prefs rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/.settings/org.eclipse.pde.prefs diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/META-INF/MANIFEST.MF b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/META-INF/MANIFEST.MF similarity index 98% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/META-INF/MANIFEST.MF rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/META-INF/MANIFEST.MF index 9226d2920..5b48100c6 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/META-INF/MANIFEST.MF +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/META-INF/MANIFEST.MF @@ -18,6 +18,6 @@ Require-Bundle: org.eclipse.ui, org.eclipse.tracecompass.analysis.profiling.core, org.eclipse.jdt.annotation;bundle-version="[2.0.0,3.0.0)";resolution:=optional Export-Package: org.eclipse.tracecompass.incubator.internal.executioncomparison.ui;x-internal:=true -Automatic-Module-Name: org.eclipse.tracecompass.incubator.executioncomparision.ui +Automatic-Module-Name: org.eclipse.tracecompass.incubator.executioncomparison.ui Import-Package: com.google.common.collect, org.eclipse.swtchart diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/about.html b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/about.html similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/about.html rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/about.html diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/build.properties b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/build.properties similarity index 91% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/build.properties rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/build.properties index 21645b6d6..ae7c9d8b8 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.core/build.properties +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/build.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2022 École Polytechnique de Montréal +# Copyright (c) 2024 École Polytechnique de Montréal # # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/plugin.properties b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/plugin.properties similarity index 79% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/plugin.properties rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/plugin.properties index 096c865e8..e59d0ebc8 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui.swtbot.tests/plugin.properties +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/plugin.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2022 École Polytechnique de Montréal +# Copyright (c) 2024 École Polytechnique de Montréal # # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 @@ -10,5 +10,5 @@ ############################################################################### Bundle-Vendor = Eclipse Trace Compass Incubator -Bundle-Name = Trace Compass ExecutionComparision UI Plug-in (Incubator) +Bundle-Name = Trace Compass ExecutionComparison UI Plug-in (Incubator) diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/plugin.xml b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/plugin.xml new file mode 100644 index 000000000..87e1f4269 --- /dev/null +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/plugin.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/Activator.java b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/Activator.java similarity index 83% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/Activator.java rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/Activator.java index 24f683972..481940cdc 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/Activator.java +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/Activator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024 École Polytechnique de Montréal + * Copyright (c) 2024 École Polytechnique de Montréal, Ericsson * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License 2.0 which @@ -18,7 +18,7 @@ import org.osgi.framework.BundleContext; /** - * The activator class controls the plug-in life cycle + * Activator class to controls the plug-in life cycle */ public class Activator extends AbstractUIPlugin { @@ -32,17 +32,18 @@ public class Activator extends AbstractUIPlugin { * The constructor */ public Activator() { + // Do nothing } @Override public void start(@Nullable BundleContext context) throws Exception { super.start(context); - plugin = this; + setDefault(this); } @Override public void stop(@Nullable BundleContext context) throws Exception { - plugin = null; + setDefault(null); super.stop(context); } @@ -55,5 +56,8 @@ public static Activator getDefault() { return Objects.requireNonNull(plugin); } -} + private static void setDefault(@Nullable Activator activator) { + plugin = activator; + } +} diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/DifferentialFlameGraphView.java b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/DifferentialFlameGraphView.java similarity index 67% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/DifferentialFlameGraphView.java rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/DifferentialFlameGraphView.java index 10266e625..b09ababd9 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/DifferentialFlameGraphView.java +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/DifferentialFlameGraphView.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024 École Polytechnique de Montréal + * Copyright (c) 2024 École Polytechnique de Montréal, Ericsson * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License 2.0 which @@ -56,6 +56,7 @@ import org.eclipse.tracecompass.incubator.analysis.core.weighted.tree.diff.DifferentialWeightedTreeProvider; import org.eclipse.tracecompass.incubator.internal.executioncomparison.core.DifferentialSeqCallGraphAnalysis; import org.eclipse.tracecompass.internal.analysis.profiling.core.flamegraph.FlameGraphDataProvider; +import org.eclipse.tracecompass.internal.analysis.profiling.core.instrumented.FlameChartEntryModel; import org.eclipse.tracecompass.internal.provisional.tmf.core.model.filters.TmfFilterAppliedSignal; import org.eclipse.tracecompass.internal.provisional.tmf.core.model.filters.TraceCompassFilter; import org.eclipse.tracecompass.internal.provisional.tmf.ui.widgets.timegraph.BaseDataProviderTimeGraphPresentationProvider; @@ -108,9 +109,11 @@ import com.google.common.collect.Multimap; /** - * the differential flame graph used in execution comparison view. Its mostly based on FlameGraphView + * The differential flame graph used in the execution comparison view. It is + * based on the flame graph view and is used to compare two different + * executions. * - * @author Fateme Faraji Daneshgar + * @author Fateme Faraji Daneshgar and Vlad Arama * */ @SuppressWarnings("restriction") @@ -121,13 +124,13 @@ public class DifferentialFlameGraphView extends TmfView { */ public static final String ID = DifferentialFlameGraphView.class.getPackage().getName() + ".diffflamegraphView"; //$NON-NLS-1$ private static final int DEFAULT_BUFFER_SIZE = 3; + private static final String DIRTY_UNDERFLOW = "Dirty underflow"; //$NON-NLS-1$ /** * the Logger that is used in multipleDensityView class */ protected static final Logger LOGGER = Logger.getLogger(DifferentialFlameGraphView.class.getName()); private @Nullable DifferentialWeightedTreeProvider fDataProvider; - private @Nullable ITimeGraphDataProvider fdataProviderGroup = null; private @Nullable TimeGraphViewer fTimeGraphViewer; @@ -184,43 +187,25 @@ protected DifferentialFlameGraphView(String id) { public void createPartControl(@Nullable Composite parent) { super.createPartControl(parent); fDisplayWidth = Display.getDefault().getBounds().width; - fTimeGraphViewer = new TimeGraphViewer(parent, SWT.NONE); + TimeGraphViewer timeGraphViewer = new TimeGraphViewer(parent, SWT.NONE); fPresentationProvider = new BaseDataProviderTimeGraphPresentationProvider(); - getTimeGraphViewer().setTimeGraphProvider(fPresentationProvider); - getTimeGraphViewer().setTimeFormat(TimeFormat.NUMBER); + timeGraphViewer.setTimeGraphProvider(fPresentationProvider); + timeGraphViewer.setTimeFormat(TimeFormat.NUMBER); IEditorPart editor = getSite().getPage().getActiveEditor(); - ITmfTrace trace = null; - if (editor instanceof ITmfTraceEditor) { - trace = ((ITmfTraceEditor) editor).getTrace(); - } else { - // Get the active trace, the editor might be opened on a script - trace = TmfTraceManager.getInstance().getActiveTrace(); - } + ITmfTrace trace = getCurrentTrace(editor); if (trace != null) { traceSelected(new TmfTraceSelectedSignal(this, trace)); } TmfSignalManager.register(this); - getSite().setSelectionProvider(getTimeGraphViewer().getSelectionProvider()); - getTimeGraphViewer().getTimeGraphControl().addMouseListener(new MouseAdapter() { + getSite().setSelectionProvider(timeGraphViewer.getSelectionProvider()); + timeGraphViewer.getTimeGraphControl().addMouseListener(new MouseAdapter() { @Override public void mouseDoubleClick(@Nullable MouseEvent e) { - TimeGraphControl timeGraphControl = getTimeGraphViewer().getTimeGraphControl(); - ISelection selection = timeGraphControl.getSelection(); - if (selection instanceof IStructuredSelection) { - for (Object object : ((IStructuredSelection) selection).toList()) { - if (object instanceof TimeEvent) { - TimeEvent event = (TimeEvent) object; - long startTime = event.getTime(); - long endTime = startTime + event.getDuration(); - getTimeGraphViewer().setStartFinishTime(startTime, endTime); - break; - } - } - } + handleDoubleClick(timeGraphViewer); } }); - getTimeGraphViewer().addRangeListener(event -> startZoomThread(event.getStartTime(), event.getEndTime(), false)); - TimeGraphControl timeGraphControl = getTimeGraphViewer().getTimeGraphControl(); + timeGraphViewer.addRangeListener(event -> startZoomThread(event.getStartTime(), event.getEndTime(), false, timeGraphViewer)); + TimeGraphControl timeGraphControl = timeGraphViewer.getTimeGraphControl(); timeGraphControl.addPaintListener(new PaintListener() { /** @@ -240,7 +225,7 @@ public void paintControl(@Nullable PaintEvent e) { if (timeGraphControl.isDisposed()) { return; } - Set newSet = getVisibleItems(DEFAULT_BUFFER_SIZE); + Set newSet = getVisibleItems(DEFAULT_BUFFER_SIZE, timeGraphViewer); if (!fVisibleEntries.equals(newSet)) { /* * Start a zoom thread if the set of visible entries has @@ -250,22 +235,38 @@ public void paintControl(@Nullable PaintEvent e) { * events. */ fVisibleEntries = newSet; - startZoomThread(getTimeGraphViewer().getTime0(), getTimeGraphViewer().getTime1(), false); + startZoomThread(timeGraphViewer.getTime0(), timeGraphViewer.getTime1(), false, timeGraphViewer); } }); } }); + fTimeGraphViewer = timeGraphViewer; + } + private static void handleDoubleClick(TimeGraphViewer timeGraphViewer) { + TimeGraphControl timeGraphControl = timeGraphViewer.getTimeGraphControl(); + ISelection selection = timeGraphControl.getSelection(); + if (selection instanceof IStructuredSelection structuredSelection) { + for (Object object : (structuredSelection).toList()) { + if (object instanceof TimeEvent event) { + long startTime = event.getTime(); + long endTime = startTime + event.getDuration(); + timeGraphViewer.setStartFinishTime(startTime, endTime); + break; + } + } + } } - /** - * Get the time graph viewer - * - * @return the time graph viewer - */ - public TimeGraphViewer getTimeGraphViewer() { - Objects.requireNonNull(fTimeGraphViewer); - return fTimeGraphViewer; + private static @Nullable ITmfTrace getCurrentTrace(@Nullable IEditorPart editor) { + ITmfTrace trace = null; + if (editor instanceof ITmfTraceEditor tmfTraceEditor) { + trace = tmfTraceEditor.getTrace(); + } else { + // Get the active trace, the editor might be opened on a script + trace = TmfTraceManager.getInstance().getActiveTrace(); + } + return trace; } /** @@ -283,9 +284,10 @@ public void traceSelected(final TmfTraceSelectedSignal signal) { if (trace == null) { return; } - // If entries for this trace are already available, just zoom on - // them, - // otherwise, rebuild + /* + * If entries for this trace are already available, just zoom on + * them, otherwise, rebuild + */ List list = fEntryListMap.get(trace); if (list == null) { refresh(); @@ -297,9 +299,11 @@ public void traceSelected(final TmfTraceSelectedSignal signal) { for (TimeGraphEntry entry : list) { endTime = Math.max(endTime, entry.getEndTime()); } - setEndTime(endTime); + fEndTime = endTime; refresh(); - startZoomThread(0, endTime, false); + if (fTimeGraphViewer != null) { + startZoomThread(0, endTime, false, fTimeGraphViewer); + } } } } @@ -318,8 +322,8 @@ protected Iterable getCallgraphModules() { Iterable modules = TmfTraceUtils.getAnalysisModulesOfClass(trace, ICallGraphProvider2.class); return StreamSupport.stream(modules.spliterator(), false) .filter(m -> { - if (m instanceof IAnalysisModule) { - return ((IAnalysisModule) m).getId().equals(analysisId); + if (m instanceof IAnalysisModule analysisModule) { + return analysisModule.getId().equals(analysisId); } return true; }) @@ -351,146 +355,190 @@ public void run(IProgressMonitor monitor) { } } } - } - private void buildEntryList(@Nullable ITmfTrace trace, ITmfTrace parentTrace, Map additionalParams, IProgressMonitor monitor) { + private void buildEntryList(@Nullable ITmfTrace trace, ITmfTrace parentTrace, Map additionalParams, IProgressMonitor monitor) { + + if (trace != null) { + DifferentialWeightedTreeProvider dataProvider = getDataProvider(monitor); + if (dataProvider == null) { + return; + } + fDataProvider = dataProvider; + ITimeGraphDataProvider dataProviderGroup = new FlameGraphDataProvider<>(trace, fDataProvider, FlameGraphDataProvider.ID + ':' + DifferentialSeqCallGraphAnalysis.ID); + BaseDataProviderTimeGraphPresentationProvider presentationProvider = fPresentationProvider; + if (presentationProvider != null) { + presentationProvider.addProvider(dataProviderGroup, getTooltipResolver(dataProviderGroup)); + } + fetchAndBuildEntries(trace, parentTrace, additionalParams, monitor, dataProviderGroup); - if (trace != null) { - DifferentialWeightedTreeProvider dataProvider = getDataProvider(); - if (dataProvider == null) { - return; } - fDataProvider = dataProvider; - setFdataProviderGroup(new FlameGraphDataProvider(trace, fDataProvider, FlameGraphDataProvider.ID + ':' + DifferentialSeqCallGraphAnalysis.ID)); } - BaseDataProviderTimeGraphPresentationProvider presentationProvider = fPresentationProvider; - if (presentationProvider != null) { - presentationProvider.addProvider(getFdataProviderGroup(), getTooltipResolver(getFdataProviderGroup())); - } - try { - fBuildEntryLock.acquire(); - boolean complete = false; - while (!complete && !monitor.isCanceled()) { - Map parameters = new HashMap<>(additionalParams); - parameters.put(DataProviderParameterUtils.REQUESTED_TIME_KEY, ImmutableList.of(0, Long.MAX_VALUE)); - TmfModelResponse> responseGroupA = getFdataProviderGroup().fetchTree(parameters, monitor); - - if (responseGroupA.getStatus() == ITmfResponse.Status.FAILED) { - Activator.getDefault().getLog().error(getClass().getSimpleName() + " Data Provider failed: " + responseGroupA.getStatusMessage()); //$NON-NLS-1$ - return; - } else if (responseGroupA.getStatus() == ITmfResponse.Status.CANCELLED) { - return; - } + private void fetchAndBuildEntries(@Nullable ITmfTrace trace, ITmfTrace parentTrace, Map additionalParams, IProgressMonitor monitor, ITimeGraphDataProvider dataProviderGroup) { + try { + fBuildEntryLock.acquire(); + boolean complete = false; + while (!complete && !monitor.isCanceled()) { + Map parameters = new HashMap<>(additionalParams); + parameters.put(DataProviderParameterUtils.REQUESTED_TIME_KEY, ImmutableList.of(0, Long.MAX_VALUE)); + TmfModelResponse> responseGroupA = dataProviderGroup.fetchTree(parameters, monitor); + + if (responseGroupA.getStatus() == ITmfResponse.Status.FAILED) { + Activator.getDefault().getLog().error(getClass().getSimpleName() + " Data Provider failed: " + responseGroupA.getStatusMessage()); //$NON-NLS-1$ + return; + } else if (responseGroupA.getStatus() == ITmfResponse.Status.CANCELLED) { + return; + } - complete = responseGroupA.getStatus() == ITmfResponse.Status.COMPLETED; - TmfTreeModel groupAModel = responseGroupA.getModel(); - long endTimeN = Long.MIN_VALUE; + complete = responseGroupA.getStatus() == ITmfResponse.Status.COMPLETED; + TmfTreeModel groupAModel = responseGroupA.getModel(); + if ((groupAModel != null)) { + processAndDisplayEntries(groupAModel, parentTrace, monitor, dataProviderGroup); - if ((groupAModel != null)) { - Map entries; - synchronized (fEntries) { - entries = fEntries.computeIfAbsent(getFdataProviderGroup(), dp -> new HashMap<>()); - /* - * The provider may send entries unordered and parents - * may not exist when child is constructor, we'll - * re-unite families at the end - */ - List orphaned = new ArrayList<>(); - for (TimeGraphEntryModel entry : groupAModel.getEntries()) { - TimeGraphEntry uiEntry = entries.get(entry.getId()); - if (entry.getParentId() != -1) { - if (uiEntry == null) { - uiEntry = new TimeGraphEntry(entry); - TimeGraphEntry parent = entries.get(entry.getParentId()); - if (parent != null) { - parent.addChild(uiEntry); - } else { - orphaned.add(uiEntry); - } - entries.put(entry.getId(), uiEntry); - } else { - if (!monitor.isCanceled()) { - uiEntry.updateModel(entry); - } - } - } else { - endTimeN = Long.max(endTimeN, entry.getEndTime() + 1); - List lables = new ArrayList<>(); - lables.add("GroupB-GroupA"); //$NON-NLS-1$ - - TimeGraphEntryModel newEntry = new TimeGraphEntryModel(0, -1, lables, entry.getStartTime(), entry.getEndTime(), entry.hasRowModel()); - - if (uiEntry != null) { - if (!monitor.isCanceled()) { - uiEntry.updateModel(newEntry); - } - } else { - // Do not assume that parentless entries are - // trace entries - uiEntry = new ParentEntry(newEntry, getFdataProviderGroup()); - entries.put(entry.getId(), uiEntry); - addToEntryList(parentTrace, Collections.singletonList(uiEntry)); - - } - } - } - setEndTime(endTimeN); - // Find missing parents - for (TimeGraphEntry orphanedEntry : orphaned) { - TimeGraphEntry parent = entries.get(orphanedEntry.getEntryModel().getParentId()); - if (parent != null) { - parent.addChild(orphanedEntry); - } + } + + if (monitor.isCanceled()) { + if (trace == null) { + return; } + resetEntries(trace); + return; + } + + if (parentTrace.equals(getTrace())) { + refresh(); } - long start = 0; - final long resolutionN = Long.max(1, (endTimeN - start) / getDisplayWidth()); + monitor.worked(1); - if (!monitor.isCanceled()) { - zoomEntries(ImmutableList.copyOf(entries.values()), start, endTimeN, resolutionN, monitor); + if (!complete && !monitor.isCanceled()) { + waitForDataProvider(); } } + } catch (InterruptedException e1) { + Activator.getDefault().getLog().error(e1.getMessage()); + } finally { + fBuildEntryLock.release(); + } + } - if (monitor.isCanceled()) { - if (trace==null) { - return; + private void processAndDisplayEntries(TmfTreeModel groupAModel, ITmfTrace parentTrace, IProgressMonitor monitor, ITimeGraphDataProvider dataProviderGroup) { + Map entries; + synchronized (fEntries) { + entries = fEntries.computeIfAbsent(dataProviderGroup, dp -> new HashMap<>()); + /* + * The provider may send entries unordered and parents may not + * exist when child is constructor, we'll re-unite families at + * the end + */ + List orphaned = new ArrayList<>(); + for (TimeGraphEntryModel entry : groupAModel.getEntries()) { + if (entry.getParentId() != -1) { + updateOrCreateOrphanedEntry(entry, entries, orphaned, monitor); + } else { + updateOrCreateEntry(entry, entries, parentTrace, monitor, dataProviderGroup); } - resetEntries(trace); - return; } + findMissingParents(entries, orphaned); + } + long start = 0; + final long resolutionN = Long.max(1, (fEndTime - start) / getDisplayWidth()); + + if (!monitor.isCanceled()) { + zoomEntries(ImmutableList.copyOf(entries.values()), start, fEndTime, resolutionN, monitor); + } + } + + private void updateOrCreateOrphanedEntry(TimeGraphEntryModel entry, Map entries, List orphaned, IProgressMonitor monitor) { + TimeGraphEntry uiEntry = entries.get(entry.getId()); + if (uiEntry == null) { + uiEntry = new TimeGraphEntry(entry); + TimeGraphEntry parent = entries.get(entry.getParentId()); + if (parent != null) { + parent.addChild(uiEntry); + } else { + orphaned.add(uiEntry); + } + entries.put(entry.getId(), uiEntry); + } else { + if (!monitor.isCanceled()) { + uiEntry.updateModel(entry); + } + } + } + + private void updateOrCreateEntry(TimeGraphEntryModel entry, Map entries, ITmfTrace parentTrace, IProgressMonitor monitor, ITimeGraphDataProvider dataProviderGroup) { + long endTimeN = fEndTime; + TimeGraphEntry uiEntry = entries.get(entry.getId()); + fEndTime = Long.max(endTimeN, entry.getEndTime() + 1); + List lables = new ArrayList<>(); + lables.add("GroupB-GroupA"); //$NON-NLS-1$ - if (parentTrace.equals(getTrace())) { - refresh(); + TimeGraphEntryModel newEntry = new TimeGraphEntryModel(0, -1, lables, entry.getStartTime(), entry.getEndTime(), entry.hasRowModel()); + + if (uiEntry != null) { + if (!monitor.isCanceled()) { + uiEntry.updateModel(newEntry); } - monitor.worked(1); + } else { + // Do not assume that parentless entries are trace entries + uiEntry = new ParentEntry(newEntry, dataProviderGroup); + entries.put(entry.getId(), uiEntry); + addToEntryList(parentTrace, Collections.singletonList(uiEntry)); - if (!complete && !monitor.isCanceled()) { - try { - Thread.sleep(100); + } + } - } catch (InterruptedException e) { - Activator.getDefault().getLog().error("Failed to wait for data provider", e); //$NON-NLS-1$ - } + private static void findMissingParents(Map entries, List orphaned) { + for (TimeGraphEntry orphanedEntry : orphaned) { + TimeGraphEntry parent = entries.get(orphanedEntry.getEntryModel().getParentId()); + if (parent != null) { + parent.addChild(orphanedEntry); } + } + } + private static void waitForDataProvider() throws InterruptedException { + try { + Thread.sleep(100); + + } catch (InterruptedException e) { + Activator.getDefault().getLog().error("Failed to wait for data provider", e); //$NON-NLS-1$ + throw e; } } - catch (InterruptedException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } finally { - fBuildEntryLock.release(); + + private int getDisplayWidth() { + int displayWidth = fDisplayWidth; + return displayWidth <= 0 ? 1 : displayWidth; } + /** + * Adds a list of entries to a trace's entry list + * + * @param trace + * the trace + * @param list + * the list of time graph entries to add + */ + private void addToEntryList(ITmfTrace trace, List list) { + synchronized (fEntryListMap) { + List entryList = fEntryListMap.get(trace); + if (entryList == null) { + fEntryListMap.put(trace, new CopyOnWriteArrayList<>(list)); + } else { + for (TimeGraphEntry entry : list) { + if (!entryList.contains(entry)) { + entryList.add(entry); + } + } + } + } + } } private static BiFunction> getTooltipResolver(ITimeGraphDataProvider provider) { - return (event, time) -> { - return getTooltip(event, time, provider, false); - }; - + return (event, time) -> getTooltip(event, time, provider, false); } private static Map getTooltip(ITimeEvent event, Long time, ITimeGraphDataProvider provider, boolean getActions) { @@ -501,8 +549,8 @@ private static Map getTooltip(ITimeEvent event, Long time, ITime } long entryId = ((TimeGraphEntry) entry).getEntryModel().getId(); IOutputElement element = null; - if (event instanceof TimeEvent) { - element = ((TimeEvent) event).getModel(); + if (event instanceof TimeEvent timeEvent) { + element = timeEvent.getModel(); } Map parameters = getFetchTooltipParameters(time, entryId, element); if (getActions) { @@ -525,10 +573,11 @@ private static Map getFetchTooltipParameters(long time, long ite } /** - * Zoom thread - * - * @since 1.1 + * The ZoomThread class is responsible for performing zoom operations on a + * collection of TimeGraphEntry objects. It is a thread that runs in the + * background and performs the zoom operation asynchronously. */ + protected class ZoomThread extends Thread { private final long fZoomStartTime; private final long fZoomEndTime; @@ -563,34 +612,6 @@ public ZoomThread(Collection entries, long startTime, long endTi fForce = force; } - /** - * @return the zoom start time - */ - public long getZoomStartTime() { - return fZoomStartTime; - } - - /** - * @return the zoom end time - */ - public long getZoomEndTime() { - return fZoomEndTime; - } - - /** - * @return the resolution - */ - public long getResolution() { - return fResolution; - } - - /** - * @return the monitor - */ - public IProgressMonitor getMonitor() { - return fMonitor; - } - /** * Cancel the zoom thread */ @@ -605,14 +626,14 @@ public final void run() { // No rows to zoom on return; } - Sampling sampling = new Sampling(getZoomStartTime(), getZoomEndTime(), getResolution()); + Sampling sampling = new Sampling(fZoomStartTime, fZoomEndTime, fResolution); Iterable incorrectSample = fForce ? fCurrentEntries : fCurrentEntries.stream().filter(entry -> !sampling.equals(entry.getSampling())).toList(); Objects.requireNonNull(incorrectSample); - zoomEntries(incorrectSample, getZoomStartTime(), getZoomEndTime(), getResolution(), getMonitor()); + zoomEntries(incorrectSample, fZoomStartTime, fZoomEndTime, fResolution, fMonitor); } finally { if (fDirty.decrementAndGet() < 0) { - Activator.getDefault().getLog().error("Dirty underflow", new Throwable()); //$NON-NLS-1$ + Activator.getDefault().getLog().error(DIRTY_UNDERFLOW, new Throwable()); } } } @@ -641,8 +662,10 @@ public void setScopeId(int scopeId) { * @param force * Whether to force the fetch of all rows, or only those that * don't have the same range + * @param timeGraphViewer + * The TimeGraphViewer */ - protected final void startZoomThread(long startTime, long endTime, boolean force) { + protected final void startZoomThread(long startTime, long endTime, boolean force, TimeGraphViewer timeGraphViewer) { ITmfTrace trace = getTrace(); if (trace == null) { return; @@ -650,8 +673,8 @@ protected final void startZoomThread(long startTime, long endTime, boolean force fDirty.incrementAndGet(); try (FlowScopeLog log = new FlowScopeLogBuilder(LOGGER, Level.FINE, "FlameGraphView:ZoomThreadCreated").setCategory(getViewId()).build()) { //$NON-NLS-1$ - long clampedStartTime = Math.max(0, Math.min(startTime, getEndTime())); - long clampedEndTime = Math.min(getEndTime(), Math.max(endTime, 0)); + long clampedStartTime = Math.max(0, Math.min(startTime, fEndTime)); + long clampedEndTime = Math.min(fEndTime, Math.max(endTime, 0)); // Ignore if end time < start time, data has not been set correctly // [yet] if (clampedEndTime < clampedStartTime) { @@ -661,10 +684,10 @@ protected final void startZoomThread(long startTime, long endTime, boolean force if (zoomThread != null) { zoomThread.cancel(); } - int timeSpace = getTimeGraphViewer().getTimeSpace(); + int timeSpace = timeGraphViewer.getTimeSpace(); if (timeSpace > 0) { long resolution = Long.max(1, (clampedEndTime - clampedStartTime) / timeSpace); - zoomThread = new ZoomThread(getVisibleItems(DEFAULT_BUFFER_SIZE), clampedStartTime, clampedEndTime, resolution, force); + zoomThread = new ZoomThread(getVisibleItems(DEFAULT_BUFFER_SIZE, timeGraphViewer), clampedStartTime, clampedEndTime, resolution, force); } else { zoomThread = null; } @@ -684,21 +707,20 @@ protected final void startZoomThread(long startTime, long endTime, boolean force } } finally { if (fDirty.decrementAndGet() < 0) { - Activator.getDefault().getLog().error("Dirty underflow", new Throwable()); //$NON-NLS-1$ + Activator.getDefault().getLog().error(DIRTY_UNDERFLOW, new Throwable()); } } } - private Set getVisibleItems(int buffer) { - - TimeGraphControl timeGraphControl = getTimeGraphViewer().getTimeGraphControl(); + private static Set getVisibleItems(int buffer, TimeGraphViewer timeGraphViewer) { + TimeGraphControl timeGraphControl = timeGraphViewer.getTimeGraphControl(); if (timeGraphControl.isDisposed()) { return Collections.emptySet(); } - int start = Integer.max(0, getTimeGraphViewer().getTopIndex() - buffer); - int end = Integer.min(getTimeGraphViewer().getExpandedElementCount() - 1, - getTimeGraphViewer().getTopIndex() + timeGraphControl.countPerPage() + buffer); + int start = Integer.max(0, timeGraphViewer.getTopIndex() - buffer); + int end = Integer.min(timeGraphViewer.getExpandedElementCount() - 1, + timeGraphViewer.getTopIndex() + timeGraphControl.countPerPage() + buffer); Set visible = new HashSet<>(end - start + 1); for (int i = start; i <= end; i++) { @@ -724,80 +746,64 @@ private void zoomEntries(Iterable normalEntries, long zoomStartT long start = Long.min(zoomStartTime, zoomEndTime); long end = Long.max(zoomStartTime, zoomEndTime); List times = StateSystemUtils.getTimes(start, end, resolution); - Sampling sampling = new Sampling(start, end, resolution); - Multimap, Long> providersToModelIds = filterGroupEntries(normalEntries, zoomStartTime, zoomEndTime); - if (providersToModelIds!=null) { + if (providersToModelIds != null) { - SubMonitor subMonitor = SubMonitor.convert(monitor, getClass().getSimpleName() + "#zoomEntries", providersToModelIds.size()); //$NON-NLS-1$ + SubMonitor subMonitor = SubMonitor.convert(monitor, getClass().getSimpleName() + "#zoomEntries", providersToModelIds.size()); //$NON-NLS-1$ - Entry, Collection> entry = providersToModelIds.asMap().entrySet().iterator().next(); - ITimeGraphDataProvider dataProvider = Objects.requireNonNull(entry.getKey()); - SelectionTimeQueryFilter filter = new SelectionTimeQueryFilter(times, entry.getValue()); - Map parameters = FetchParametersUtils.selectionTimeQueryToMap(filter); - Multimap regexesMap = getRegexes(); - if (!regexesMap.isEmpty()) { - parameters.put(DataProviderParameterUtils.REGEX_MAP_FILTERS_KEY, Objects.requireNonNull(regexesMap.asMap())); - } - TmfModelResponse response = dataProvider.fetchRowModel(parameters, monitor); - TimeGraphModel model = response.getModel(); - Map entries = fEntries.get(dataProvider); - if ((model != null) && (entries) != null) { - zoomEntries(entries, model.getRows(), response.getStatus() == ITmfResponse.Status.COMPLETED, sampling); + Entry, Collection> entry = providersToModelIds.asMap().entrySet().iterator().next(); + ITimeGraphDataProvider dataProvider = Objects.requireNonNull(entry.getKey()); + SelectionTimeQueryFilter filter = new SelectionTimeQueryFilter(times, entry.getValue()); + Map parameters = FetchParametersUtils.selectionTimeQueryToMap(filter); + Multimap regexesMap = getRegexes(); + if (regexesMap != null && !regexesMap.isEmpty()) { + parameters.put(DataProviderParameterUtils.REGEX_MAP_FILTERS_KEY, Objects.requireNonNull(regexesMap.asMap())); + } + TmfModelResponse response = dataProvider.fetchRowModel(parameters, monitor); + TimeGraphModel model = response.getModel(); + Map entries = fEntries.get(dataProvider); + if ((model != null) && (entries) != null) { + zoomEntries(entries, model.getRows()); - } - subMonitor.worked(1); - redraw(); + } + subMonitor.worked(1); + redraw(); } } /** - * This method build the multimap of regexes by property that will be used - * to filter the timegraph states + * Builds the multimap of regexes by the property that will be used to + * filter the timegraph states * * Override this method to add other regexes with their properties. The data * provider should handle everything after. * * @return The multimap of regexes by property */ - @SuppressWarnings("null") - private Multimap getRegexes() { + private @Nullable Multimap getRegexes() { Multimap regexes = HashMultimap.create(); - - ITmfTrace trace = getTrace(); - if (trace == null) { - return regexes; - } - TraceCompassFilter globalFilter = TraceCompassFilter.getFilterForTrace(trace); - if (globalFilter == null) { - return regexes; + if (regexes != null) { + ITmfTrace trace = getTrace(); + if (trace == null) { + return regexes; + } + TraceCompassFilter globalFilter = TraceCompassFilter.getFilterForTrace(trace); + if (globalFilter == null) { + return regexes; + } + regexes.putAll(CoreFilterProperty.DIMMED, globalFilter.getRegexes()); } - regexes.putAll(CoreFilterProperty.DIMMED, globalFilter.getRegexes()); - return regexes; } - private void zoomEntries(Map map, List model, boolean completed, Sampling sampling) { - boolean isZoomThread = false; + private void zoomEntries(Map map, List model) { for (ITimeGraphRowModel rowModel : model) { TimeGraphEntry entry = map.get(rowModel.getEntryID()); if (entry != null) { List events = createTimeEvents(entry, rowModel.getStates()); - if (isZoomThread) { - synchronized (fZoomThreadResultLock) { - Display.getDefault().asyncExec(() -> { - entry.setZoomedEventList(events); - if (completed) { - entry.setSampling(sampling); - } - }); - } - } else { - - entry.setEventList(events); - } + entry.setEventList(events); } } } @@ -884,13 +890,12 @@ protected TimeEvent createTimeEvent(TimeGraphEntry entry, ITimeGraphState state) * @param entry * queried {@link TimeGraphEntry}. * @return the {@link ITimeGraphDataProvider} - * @since 3.3 */ public static ITimeGraphDataProvider getProvider(ITimeGraphEntry entry) { ITimeGraphEntry parent = entry; while (parent != null) { - if (parent instanceof ParentEntry) { - return ((ParentEntry) parent).getProvider(); + if (parent instanceof ParentEntry parentEntry) { + return parentEntry.getProvider(); } parent = parent.getParent(); } @@ -912,7 +917,7 @@ private void refresh() { TmfUiRefreshHandler.getInstance().queueUpdate(this, () -> { try (FlowScopeLog log = new FlowScopeLogBuilder(LOGGER, Level.FINE, "FlameGraphView:Refresh").setParentScope(parentLogger).build()) { //$NON-NLS-1$ fDirty.incrementAndGet(); - if (getTimeGraphViewer().getControl().isDisposed()) { + if (fTimeGraphViewer != null && fTimeGraphViewer.getControl().isDisposed()) { return; } List entries; @@ -923,25 +928,30 @@ private void refresh() { } } - boolean inputChanged = entries != getTimeGraphViewer().getInput(); - if (inputChanged) { - getTimeGraphViewer().setInput(entries); - } else { - getTimeGraphViewer().refresh(); - } - - long startBound = 0; - long endBound = getEndTime(); - endBound = (endBound == Long.MIN_VALUE ? SWT.DEFAULT : endBound); - getTimeGraphViewer().setTimeBounds(startBound, endBound); + if (fTimeGraphViewer != null) { + boolean inputChanged = entries != fTimeGraphViewer.getInput(); + if (inputChanged && fTimeGraphViewer != null) { + fTimeGraphViewer.setInput(entries); + } else if (!inputChanged && fTimeGraphViewer != null) { + fTimeGraphViewer.refresh(); + } else { + return; + } + long startBound = 0; + long endBound = fEndTime; + endBound = (endBound == Long.MIN_VALUE ? SWT.DEFAULT : endBound); + if (fTimeGraphViewer != null) { + fTimeGraphViewer.setTimeBounds(startBound, endBound); + } - if (inputChanged && !isZoomThread) { - getTimeGraphViewer().resetStartFinishTime(); + if (inputChanged && !isZoomThread && fTimeGraphViewer != null) { + fTimeGraphViewer.resetStartFinishTime(); + } } } finally { if (fDirty.decrementAndGet() < 0) { - Activator.getDefault().getLog().error("Dirty underflow", new Throwable()); //$NON-NLS-1$ + Activator.getDefault().getLog().error(DIRTY_UNDERFLOW, new Throwable()); } } }); @@ -949,25 +959,23 @@ private void refresh() { } private void redraw() { - try (FlowScopeLog flowParent = new FlowScopeLogBuilder(LOGGER, Level.FINE, "FlameGraphView:RedrawRequested").setCategory(getViewId()).build()) { //$NON-NLS-1$ Display.getDefault().asyncExec(() -> { try (FlowScopeLog log = new FlowScopeLogBuilder(LOGGER, Level.FINE, "FlameGraphView:Redraw").setParentScope(flowParent).build()) { //$NON-NLS-1$ - if (getTimeGraphViewer().getControl().isDisposed()) { + if (fTimeGraphViewer != null && fTimeGraphViewer.getControl().isDisposed()) { return; } - getTimeGraphViewer().getControl().redraw(); - getTimeGraphViewer().getControl().update(); + if (fTimeGraphViewer != null) { + fTimeGraphViewer.getControl().redraw(); + if (fTimeGraphViewer != null) { + fTimeGraphViewer.getControl().update(); + } + } } }); } } - private int getDisplayWidth() { - int displayWidth = fDisplayWidth; - return displayWidth <= 0 ? 1 : displayWidth; - } - /** * A class for parent entries that contain a link to the data provider * @@ -1000,37 +1008,6 @@ public ITimeGraphDataProvider getProvider() { } } - private synchronized void setEndTime(long endTime) { - fEndTime = endTime; - } - - private synchronized long getEndTime() { - return fEndTime; - } - - /** - * Adds a list of entries to a trace's entry list - * - * @param trace - * the trace - * @param list - * the list of time graph entries to add - */ - private void addToEntryList(ITmfTrace trace, List list) { - synchronized (fEntryListMap) { - List entryList = fEntryListMap.get(trace); - if (entryList == null) { - fEntryListMap.put(trace, new CopyOnWriteArrayList<>(list)); - } else { - for (TimeGraphEntry entry : list) { - if (!entryList.contains(entry)) { - entryList.add(entry); - } - } - } - } - } - private void resetEntries(ITmfTrace trace) { synchronized (fEntries) { synchronized (fEntryListMap) { @@ -1041,8 +1018,8 @@ private void resetEntries(ITmfTrace trace) { return; } for (TimeGraphEntry entry : entries) { - if (entry instanceof ParentEntry) { - fEntries.remove(((ParentEntry) entry).getProvider()); + if (entry instanceof ParentEntry parentEntry) { + fEntries.remove((parentEntry).getProvider()); } } refresh(); @@ -1097,7 +1074,7 @@ public void buildFlameGraph(ITmfTrace viewTrace, @Nullable ITmfTimestamp selStar resetEntries(viewTrace); // Build job will decrement - buildJob = new Job(getTitle() + Messages.FlameGraphView_RetrievingData) { + buildJob = new Job(getTitle() + Messages.flameGraphViewRetrievingData) { @Override protected IStatus run(@Nullable IProgressMonitor monitor) { Objects.requireNonNull(monitor); @@ -1154,14 +1131,16 @@ public void setTrace(ITmfTrace trace) { */ @TmfSignalHandler public void traceClosed(final TmfTraceClosedSignal signal) { - if (signal.getTrace() == fTrace) { - getTimeGraphViewer().setInput(null); + if (signal.getTrace() == fTrace && fTimeGraphViewer != null) { + fTimeGraphViewer.setInput(null); } } @Override public void setFocus() { - getTimeGraphViewer().setFocus(); + if (fTimeGraphViewer != null) { + fTimeGraphViewer.setFocus(); + } } // -------------------------------- // Sorting related methods @@ -1175,14 +1154,18 @@ public void setFocus() { */ @TmfSignalHandler public void symbolMapUpdated(TmfSymbolProviderUpdatedSignal signal) { - if (signal.getSource() != this) { - startZoomThread(getTimeGraphViewer().getTime0(), getTimeGraphViewer().getTime1(), true); + if (signal.getSource() != this && fTimeGraphViewer != null) { + TimeGraphViewer timeGraphViewer = fTimeGraphViewer; + startZoomThread(timeGraphViewer.getTime0(), timeGraphViewer.getTime1(), true, timeGraphViewer); } } @Override protected @Nullable IAction createSaveAction() { - return SaveImageUtil.createSaveAction(getName(), this::getTimeGraphViewer); + if (fTimeGraphViewer != null) { + return SaveImageUtil.createSaveAction(getName(), () -> fTimeGraphViewer); + } + return null; } /** @@ -1196,7 +1179,10 @@ public void restartZoomThread() { zoomThread.cancel(); fZoomThread = null; } - startZoomThread(getTimeGraphViewer().getTime0(), getTimeGraphViewer().getTime1(), true); + if (fTimeGraphViewer != null) { + TimeGraphViewer timeGraphViewer = fTimeGraphViewer; + startZoomThread(timeGraphViewer.getTime0(), timeGraphViewer.getTime1(), true, timeGraphViewer); + } } /** @@ -1214,27 +1200,19 @@ public void regexFilterApplied(TmfFilterAppliedSignal signal) { /** * Listen to see if one of the view's analysis is restarted * - * @param signal - * The analysis started signal + * @param monitor + * The progress monitor * @return The data provider or null */ - private static @Nullable DifferentialWeightedTreeProvider getDataProvider() { + private static @Nullable DifferentialWeightedTreeProvider getDataProvider(IProgressMonitor monitor) { ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace(); if (trace != null) { DifferentialSeqCallGraphAnalysis analysis = (DifferentialSeqCallGraphAnalysis) trace.getAnalysisModule("org.eclipse.tracecompass.incubator.executioncomparison.diffcallgraph"); //$NON-NLS-1$ if (analysis != null) { - return analysis.getDiffProvider(null); + return analysis.getDifferentialTreeProvider(monitor); } } return null; } - private ITimeGraphDataProvider getFdataProviderGroup() { - Objects.requireNonNull(fdataProviderGroup); - return fdataProviderGroup; - } - - private void setFdataProviderGroup(@Nullable ITimeGraphDataProvider fdataProviderGroup) { - this.fdataProviderGroup = fdataProviderGroup; - } -} \ No newline at end of file +} diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/ExecutionComparisonView.java b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/ExecutionComparisonView.java new file mode 100644 index 000000000..e25d9d32c --- /dev/null +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/ExecutionComparisonView.java @@ -0,0 +1,1318 @@ +/******************************************************************************* + * Copyright (c) 2024 École Polytechnique de Montréal, Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License 2.0 which + * accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ + +package org.eclipse.tracecompass.incubator.internal.executioncomparison.ui; + +import java.awt.Color; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.logging.Level; + +import javax.swing.JFormattedTextField; +import javax.swing.JLabel; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuCreator; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.awt.SWT_AWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.events.ExpandEvent; +import org.eclipse.swt.events.ExpandListener; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.ExpandBar; +import org.eclipse.swt.widgets.ExpandItem; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Sash; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.ScopeLog; +import org.eclipse.tracecompass.incubator.internal.executioncomparison.core.TmfCheckboxChangedSignal; +import org.eclipse.tracecompass.incubator.internal.executioncomparison.core.TmfComparisonFilteringUpdatedSignal; +import org.eclipse.tracecompass.internal.tmf.ui.viewers.eventdensity.EventDensityTreeViewer; +import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfWindowRangeUpdatedSignal; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentInfo; +import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentSignal; +import org.eclipse.tracecompass.tmf.ui.viewers.ILegendImageProvider2; +import org.eclipse.tracecompass.tmf.ui.viewers.TmfTimeViewer; +import org.eclipse.tracecompass.tmf.ui.viewers.TmfViewer; +import org.eclipse.tracecompass.tmf.ui.viewers.tree.AbstractSelectTreeViewer2; +import org.eclipse.tracecompass.tmf.ui.viewers.tree.ICheckboxTreeViewerListener; +import org.eclipse.tracecompass.tmf.ui.viewers.tree.ITmfTreeViewerEntry; +import org.eclipse.tracecompass.tmf.ui.viewers.xychart.TmfXYChartViewer; +import org.eclipse.tracecompass.tmf.ui.viewers.xychart.XYChartLegendImageProvider; +import org.eclipse.tracecompass.tmf.ui.viewers.xychart.linechart.TmfCommonXAxisChartViewer; +import org.eclipse.tracecompass.tmf.ui.viewers.xychart.linechart.TmfFilteredXYChartViewer; +import org.eclipse.tracecompass.tmf.ui.viewers.xychart.linechart.TmfXYChartSettings; +import org.eclipse.tracecompass.tmf.ui.views.ManyEntriesSelectedDialogPreCheckedListener; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs.TriStateFilteredCheckboxTree; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.contexts.IContextActivation; +import org.eclipse.ui.contexts.IContextService; +import org.eclipse.ui.themes.ITheme; +import org.eclipse.ui.themes.IThemeManager; + +/** + * The ExecutionComparisonView allows to compare two groups of traces (parts of + * traces) + * + * @author Fateme Faraji Daneshgar and Vlad Arama + */ +@SuppressWarnings("restriction") +public class ExecutionComparisonView extends DifferentialFlameGraphView implements ICheckboxTreeViewerListener { + + /** + * the id of the view + */ + public static final String VIEW_ID = Objects.requireNonNull(Messages.multipleDensityViewId); + /** + * The title of the view + */ + public static final String VIEW_TITLE = Objects.requireNonNull(Messages.multipleDensityViewTitle); + private static final String DATA_SELECTION = Objects.requireNonNull(Messages.dataSelection); + private static final String BACKGROUND = Objects.requireNonNull(Messages.background); + private static final String FOREGROUND = Objects.requireNonNull(Messages.foreground); + private static final String TRACE_NAME = Objects.requireNonNull(Messages.traceName); + private static final String STATISTIC_NAME = Objects.requireNonNull(Messages.statisticName); + private static final String TMF_VIEW_UI_CONTEXT = Objects.requireNonNull(Messages.tmfViewUiContext); + private static final String Y_AXIS_LABEL = Objects.requireNonNull(Messages.yAxisLabel); + private String fStatistic = Objects.requireNonNull(Messages.multipleDensityViewDuration); + + /** + * Default weights for organizing the view + */ + private static final int[] DEFAULT_WEIGHTS_ShowQuery = new int[] { 450, 290, 260 }; + private static final int[] DEFAULT_WEIGHTS_HideQuery = new int[] { 450, 100, 450 }; + private static final int[] DEFAULT_WEIGHTS_FILTERING_H = new int[] { 3, 9 }; + private static final int[] DEFAULT_WEIGHTS_TimeInterval = new int[] { 240, 380, 380 }; + + /** A composite that allows us to add margins for part A and B */ + private @Nullable TmfXYChartViewer fChartViewerA; + private @Nullable TmfXYChartViewer fChartViewerB; + + private @Nullable SashForm fXYViewerContainerA; + private @Nullable SashForm fXYViewerContainerB; + + private @Nullable TmfViewer fTmfViewerA; + private @Nullable TmfViewer fTmfViewerB; + + private @Nullable SashForm fSashFormLeftChildA; + private @Nullable SashForm fSashFormLeftChildB; + + private List fTraceListA = new ArrayList<>(); + private List fTraceListB = new ArrayList<>(); + + private ITmfTimestamp fStartTimeA = TmfTimestamp.BIG_BANG; + private ITmfTimestamp fStartTimeB = TmfTimestamp.BIG_BANG; + private ITmfTimestamp fEndTimeA = TmfTimestamp.BIG_CRUNCH; + private ITmfTimestamp fEndTimeB = TmfTimestamp.BIG_CRUNCH; + private TmfTimestampFormat fFormat = new TmfTimestampFormat("yyyy-MM-dd HH:mm:ss.SSS.SSS.SSS"); //$NON-NLS-1$ + + private JFormattedTextField ftextAFrom = new JFormattedTextField(); + private JFormattedTextField ftextBFrom = new JFormattedTextField(); + private JFormattedTextField ftextATo = new JFormattedTextField(); + private JFormattedTextField ftextBTo = new JFormattedTextField(); + + private @Nullable IContextService fContextService; + private @Nullable Action fConfigureStatisticAction; + private @Nullable Text ftextQuery; + private @Nullable Listener fSashDragListener; + private @Nullable SashForm fsashForm = null; + private List fActiveContexts = new ArrayList<>(); + + /** + * Constructs two density charts for selecting the desired traces and time + * ranges in order to do the comparison + */ + public ExecutionComparisonView() { + super(); + } + + @Override + public void createPartControl(@Nullable Composite parent) { + TmfSignalManager.register(this); + + this.setContentDescription(DATA_SELECTION); + final SashForm sashForm = new SashForm(parent, SWT.VERTICAL); + fsashForm = sashForm; + sashForm.setLayout(new GridLayout(1, false)); + sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + /* + * Main organization of the view. There are three main parts in the + * view: Filtering, Query and Differential Flame Graph + */ + Composite sashFormFiltering = new Composite(sashForm, SWT.HORIZONTAL); + GridLayout layout = new GridLayout(2, false); + layout.marginHeight = layout.marginWidth = 0; + sashFormFiltering.setLayout(layout); + sashFormFiltering.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + // GroupA + Group groupA = new Group(sashFormFiltering, SWT.NULL); + GridLayout gridLayoutG = new GridLayout(); + GridData gridDataG = new GridData(GridData.FILL_BOTH); + SashForm densityA = new SashForm(groupA, SWT.NULL); + GridData data = new GridData(SWT.FILL, SWT.TOP, true, false); + SashForm timeInputA = new SashForm(groupA, SWT.NULL); + createGroups(groupA, gridLayoutG, gridDataG, densityA, data, timeInputA, true); + + // GroupB + Group groupB = new Group(sashFormFiltering, SWT.NULL); + SashForm densityB = new SashForm(groupB, SWT.NULL); + SashForm timeInputB = new SashForm(groupB, SWT.NULL); + createGroups(groupB, gridLayoutG, gridDataG, densityB, data, timeInputB, false); + + // Get the current theme + IThemeManager themeManager = PlatformUI.getWorkbench().getThemeManager(); + ITheme currentTheme = themeManager.getCurrentTheme(); + + // Get background color + RGB backgroundRGB = currentTheme.getColorRegistry().getRGB(BACKGROUND); + java.awt.Color backgroundColor; + if (backgroundRGB != null) { + backgroundColor = new java.awt.Color(backgroundRGB.red, backgroundRGB.green, backgroundRGB.blue); + } else { + org.eclipse.swt.graphics.Color swtColor = Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); + backgroundColor = new java.awt.Color(swtColor.getRed(), swtColor.getGreen(), swtColor.getBlue()); + } + + // Get foreground color + RGB foregroundRGB = currentTheme.getColorRegistry().getRGB(FOREGROUND); + java.awt.Color foregroundColor; + if (foregroundRGB != null) { + foregroundColor = new java.awt.Color(foregroundRGB.red, foregroundRGB.green, foregroundRGB.blue); + } else { + org.eclipse.swt.graphics.Color swtColor = Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND); + foregroundColor = new java.awt.Color(swtColor.getRed(), swtColor.getGreen(), swtColor.getBlue()); + } + // Group A Time Intervals + Composite timelableA = new Composite(timeInputA, SWT.NONE); + Composite timelableAFrom = new Composite(timeInputA, SWT.EMBEDDED); + Composite timelableATo = new Composite(timeInputA, SWT.EMBEDDED); + + timeInputA.setWeights(DEFAULT_WEIGHTS_TimeInterval); + + RowLayout rowLayout = new RowLayout(); + GridLayout gridLayout = new GridLayout(); + gridLayout.numColumns = 2; + + timelableA.setLayout(gridLayout); + timelableAFrom.setLayout(rowLayout); + timelableATo.setLayout(rowLayout); + + SashForm sashFormLeftChildA = new SashForm(densityA, SWT.None); + fSashFormLeftChildA = sashFormLeftChildA; + + TmfViewer tmfViewerA = createLeftChildViewer(sashFormLeftChildA); + fTmfViewerA = tmfViewerA; + + SashForm xYViewerContainerA = new SashForm(densityA, SWT.None); + fXYViewerContainerA = xYViewerContainerA; + xYViewerContainerA.setLayout(GridLayoutFactory.fillDefaults().create()); + + TmfXYChartViewer chartViewerA = createChartViewer(xYViewerContainerA); + fChartViewerA = chartViewerA; + + // Reset Button A + Button resetButtonA = new Button(timelableA, SWT.PUSH); + createResetButtonA(resetButtonA, chartViewerA, tmfViewerA); + + // LabelFromA + java.awt.Frame frameAFrom = SWT_AWT.new_Frame(timelableAFrom); + + java.awt.Panel panelAFrom = new java.awt.Panel(); + JFormattedTextField textAFrom = new JFormattedTextField(fFormat); + if (frameAFrom != null) { + createLabelFromA(frameAFrom, panelAFrom, textAFrom, backgroundColor, foregroundColor, chartViewerA); + } + + // LabelToA + java.awt.Frame frameATo = SWT_AWT.new_Frame(timelableATo); + java.awt.Panel panelATo = new java.awt.Panel(); + JFormattedTextField textATo = new JFormattedTextField(fFormat); + if (frameATo != null) { + createLabelToA(frameATo, panelATo, textATo, backgroundColor, foregroundColor, chartViewerA); + } + + // Group B Time Intervals + Composite timelableB = new Composite(timeInputB, SWT.FILL); + Composite timelableBFrom = new Composite(timeInputB, SWT.EMBEDDED); + Composite timelableBTo = new Composite(timeInputB, SWT.EMBEDDED); + + timeInputB.setWeights(DEFAULT_WEIGHTS_TimeInterval); + + timelableB.setLayout(gridLayout); + timelableBFrom.setLayout(rowLayout); + timelableBTo.setLayout(rowLayout); + + SashForm sashFormLeftChildB = new SashForm(densityB, SWT.None); + fSashFormLeftChildB = sashFormLeftChildB; + + TmfViewer tmfViewerB = createLeftChildViewer(sashFormLeftChildB); + fTmfViewerB = tmfViewerB; + + SashForm xYViewerContainerB = new SashForm(densityB, SWT.VERTICAL); + fXYViewerContainerB = xYViewerContainerB; + xYViewerContainerB.setLayout(GridLayoutFactory.fillDefaults().create()); + + TmfXYChartViewer chartViewerB = createChartViewer(xYViewerContainerB); + fChartViewerB = chartViewerB; + + // Reset Button B + Button resetButtonB = new Button(timelableB, SWT.PUSH); + createResetButtonB(resetButtonB, chartViewerB, tmfViewerB); + + // LabelFromB + java.awt.Frame frameBFrom = SWT_AWT.new_Frame(timelableBFrom); + java.awt.Panel panelBFrom = new java.awt.Panel(); + JFormattedTextField textBFrom = new JFormattedTextField(fFormat); + if (frameBFrom != null) { + createLabelFromB(frameBFrom, panelBFrom, textBFrom, backgroundColor, foregroundColor, chartViewerB); + } + + // LableToB + java.awt.Frame frameBTo = SWT_AWT.new_Frame(timelableBTo); + java.awt.Panel panelBTo = new java.awt.Panel(); + JFormattedTextField textBTo = new JFormattedTextField(fFormat); + if (frameBTo != null) { + createLabelToB(frameBTo, panelBTo, textBTo, backgroundColor, foregroundColor, chartViewerB); + } + + createControlPaintListenerA(chartViewerA, sashFormLeftChildA); + + IStatusLineManager statusLineManager = getViewSite().getActionBars().getStatusLineManager(); + chartViewerA.setStatusLineManager(statusLineManager); + coupleSelectViewer(tmfViewerA, chartViewerA); + ((AbstractSelectTreeViewer2) tmfViewerA).addTreeListener(this); + + IWorkbenchPartSite site = getSite(); + fContextService = site.getWorkbenchWindow().getService(IContextService.class); + + createControlPaintListenerB(chartViewerB, sashFormLeftChildB); + + chartViewerB.setStatusLineManager(statusLineManager); + coupleSelectViewer(tmfViewerB, chartViewerB); + ((AbstractSelectTreeViewer2) tmfViewerB).addTreeListener(this); + + IMenuManager menuManager = getViewSite().getActionBars().getMenuManager(); + + IAction aggregatedAction = fConfigureStatisticAction; + if (aggregatedAction == null) { + aggregatedAction = getAggregateByAction(); + fConfigureStatisticAction = (Action) aggregatedAction; + } + menuManager.add(new Separator()); + menuManager.add(aggregatedAction); + menuManager.add(new Separator()); + + densityA.setWeights(DEFAULT_WEIGHTS_FILTERING_H); + densityB.setWeights(DEFAULT_WEIGHTS_FILTERING_H); + + Group groupQuery = new Group(sashForm, SWT.NULL); + groupQuery.setText(Messages.multipleDensityViewQueryGroup); + gridLayoutG = new GridLayout(); + gridLayoutG.numColumns = 1; + groupQuery.setLayout(gridLayoutG); + gridDataG = new GridData(GridData.FILL_BOTH); + gridDataG.horizontalSpan = 1; + groupQuery.setLayoutData(gridDataG); + + // Organizing sashFormQuery + ExpandBar bar = new ExpandBar(groupQuery, SWT.NONE); + bar.setLayout(new GridLayout(1, false)); + GridData data2 = new GridData(); + data2.verticalAlignment = SWT.FILL; + data2.horizontalAlignment = SWT.FILL; + data2.grabExcessHorizontalSpace = true; + data2.grabExcessVerticalSpace = true; + data2.heightHint = 75; + data2.widthHint = 100; + bar.setLayoutData(data2); + + Composite queryText = new Composite(bar, SWT.NONE); + queryText.setLayout(new GridLayout(1, false)); + queryText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + // Text + Text text = new Text(queryText, SWT.MULTI | SWT.BORDER); + data.verticalAlignment = SWT.FILL; + data.horizontalAlignment = SWT.FILL; + data.grabExcessHorizontalSpace = true; + data.grabExcessVerticalSpace = true; + data.heightHint = 75; + data.widthHint = 100; + text.setLayoutData(data); + ftextQuery = text; + addTextFocusListener(text, chartViewerA, chartViewerB, tmfViewerA, tmfViewerB); + + ExpandItem item0 = new ExpandItem(bar, SWT.NONE, 0); + item0.setText(Messages.multipleDensityViewQueryExpandable); + item0.setHeight(150); + + item0.setControl(queryText); + item0.setExpanded(false); + + bar.setSpacing(5); + createExpandBarListener(bar, queryText, sashForm); + + super.createPartControl(sashForm); + sashForm.setWeights(DEFAULT_WEIGHTS_HideQuery); + + ITmfTrace activetrace = TmfTraceManager.getInstance().getActiveTrace(); + if (activetrace != null) { + buildDifferentialFlameGraph(); + } + } + + private static void createGroups(Group group, GridLayout gridLayoutG, GridData gridDataG, SashForm density, GridData data, SashForm timeInput, boolean isA) { + if (isA) { + group.setText(Messages.multipleDensityViewGroupA); + } else { + group.setText(Messages.multipleDensityViewGroupB); + } + gridLayoutG.numColumns = 1; + group.setLayout(gridLayoutG); + gridDataG.horizontalSpan = 1; + group.setLayoutData(gridDataG); + data.heightHint = 200; + density.setLayoutData(data); + timeInput.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + } + + private void createResetButtonA(Button resetButton, TmfXYChartViewer chartViewerA, TmfViewer tmfViewerA) { + resetButton.setText("Reset Time IntervalA"); //$NON-NLS-1$ + resetButton.addListener(SWT.Selection, event -> { + ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace(); + if (trace != null) { + /* + * Resets tree viewer checked items. All items should be + * checked. + */ + List treeCheckedElements = ((MultipleEventDensityViewer) chartViewerA).getWholeCheckedItems(); + setCheckedElements(chartViewerA, tmfViewerA, treeCheckedElements, false); + + // Reset start time and end time and relating objects + fStartTimeA = trace.getStartTime(); + fEndTimeA = trace.getEndTime(); + ftextAFrom.setText(fStartTimeA.toString(fFormat)); + ftextATo.setText(fEndTimeA.toString(fFormat)); + if (ftextQuery != null) { + ftextQuery.setText(buildComparisonQuery()); + } + + // Dispatch signal to rebuild differential flame graph + TmfSignalManager.dispatchSignal(new TmfSelectionRangeUpdatedSignal(chartViewerA, fStartTimeA, fEndTimeA, getTrace())); + + } + }); + } + + private void createResetButtonB(Button resetButton, TmfXYChartViewer chartViewerB, TmfViewer tmfViewerB) { + resetButton.setText("Reset Time IntervalB"); //$NON-NLS-1$ + resetButton.addListener(SWT.Selection, event -> { + ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace(); + if (trace != null) { + /* + * Resets tree viewer checked items. All items should be checked + */ + List treeCheckedElements = ((MultipleEventDensityViewer) chartViewerB).getWholeCheckedItems(); + setCheckedElements(chartViewerB, tmfViewerB, treeCheckedElements, false); + + // Reset start time and end time and relating objects + fStartTimeB = trace.getStartTime(); + fEndTimeB = trace.getEndTime(); + ftextBFrom.setText(fStartTimeB.toString(fFormat)); + ftextBTo.setText(fEndTimeB.toString(fFormat)); + if (ftextQuery != null) { + ftextQuery.setText(buildComparisonQuery()); + } + + // Dispatch signal to rebuild differential flame graph + TmfSignalManager.dispatchSignal(new TmfSelectionRangeUpdatedSignal(chartViewerB, fStartTimeB, fEndTimeB, getTrace())); + + } + }); + } + + private void createLabelFromA(java.awt.Frame frameFrom, java.awt.Panel panelFrom, JFormattedTextField textFrom, Color backgroundColor, Color foregroundColor, TmfXYChartViewer chartViewer) { + frameFrom.add(panelFrom); + JLabel labelAFrom = new JLabel(); + labelAFrom.setText(Messages.multipleDensityViewFrom); + + // Set the background and foreground colors + panelFrom.setBackground(backgroundColor); + textFrom.setBackground(backgroundColor); + labelAFrom.setBackground(backgroundColor); + + textFrom.setForeground(foregroundColor); + labelAFrom.setForeground(foregroundColor); + + textFrom.addFocusListener(new java.awt.event.FocusListener() { + private String oldVal = ""; //$NON-NLS-1$ + + @Override + public void focusGained(java.awt.event.@Nullable FocusEvent e) { + String aFrom = textFrom.getText(); + if (aFrom != null) { + oldVal = aFrom; + } + } + + @Override + public void focusLost(java.awt.event.@Nullable FocusEvent e) { + if (!oldVal.equals(textFrom.getText())) { + long newTime = 0; + try { + newTime = fFormat.parseValue(textFrom.getText()); + ITmfTimestamp fromTime = TmfTimestamp.fromNanos(newTime); + fStartTimeA = fromTime; + textFrom.setText(fStartTimeA.toString(fFormat)); + + updateSelectedRange(); + chartViewer.selectionRangeUpdated(new TmfSelectionRangeUpdatedSignal(this, fStartTimeA, fEndTimeA, getTrace())); + + } catch (ParseException e1) { + textFrom.setText(oldVal); + e1.printStackTrace(); + } + } + } + }); + textFrom.setText(fStartTimeA.toString(fFormat)); + panelFrom.add(labelAFrom); + panelFrom.add(textFrom); + ftextAFrom = textFrom; + + } + + private void createLabelFromB(java.awt.Frame frameFrom, java.awt.Panel panelFrom, JFormattedTextField textFrom, Color backgroundColor, Color foregroundColor, TmfXYChartViewer chartViewer) { + frameFrom.add(panelFrom); + JLabel labelBFrom = new JLabel(); + labelBFrom.setText(Messages.multipleDensityViewFrom); + + // Set the background and foreground colors + panelFrom.setBackground(backgroundColor); + textFrom.setBackground(backgroundColor); + labelBFrom.setBackground(backgroundColor); + + textFrom.setForeground(foregroundColor); + labelBFrom.setForeground(foregroundColor); + + textFrom.addFocusListener(new java.awt.event.FocusListener() { + private String oldVal = ""; //$NON-NLS-1$ + + @Override + public void focusGained(java.awt.event.@Nullable FocusEvent e) { + String bFrom = textFrom.getText(); + if (bFrom != null) { + oldVal = bFrom; + } + } + + @Override + public void focusLost(java.awt.event.@Nullable FocusEvent e) { + if (!oldVal.equals(textFrom.getText())) { + long newTime = 0; + try { + newTime = fFormat.parseValue(textFrom.getText()); + ITmfTimestamp fromTime = TmfTimestamp.fromNanos(newTime); + fStartTimeB = fromTime; + textFrom.setText(fStartTimeB.toString(fFormat)); + + updateSelectedRange(); + chartViewer.selectionRangeUpdated(new TmfSelectionRangeUpdatedSignal(this, fStartTimeB, fEndTimeB, getTrace())); + + } catch (ParseException e1) { + textFrom.setText(oldVal); + e1.printStackTrace(); + } + + } + } + }); + + textFrom.setText(fStartTimeB.toString(fFormat)); + panelFrom.add(labelBFrom); + panelFrom.add(textFrom); + ftextBFrom = textFrom; + } + + private void createLabelToA(java.awt.Frame frameTo, java.awt.Panel panelTo, JFormattedTextField textTo, Color backgroundColor, Color foregroundColor, TmfXYChartViewer chartViewer) { + frameTo.add(panelTo); + JLabel labelATo = new JLabel(); + labelATo.setText(Messages.multipleDensityViewTo); + + // Set the background and foreground colors + panelTo.setBackground(backgroundColor); + textTo.setBackground(backgroundColor); + labelATo.setBackground(backgroundColor); + + textTo.setForeground(foregroundColor); + labelATo.setForeground(foregroundColor); + + textTo.addFocusListener(new java.awt.event.FocusListener() { + private String oldVal = ""; //$NON-NLS-1$ + + @Override + public void focusGained(java.awt.event.@Nullable FocusEvent e) { + String aTo = textTo.getText(); + if (aTo != null) { + oldVal = aTo; + } + } + + @Override + public void focusLost(java.awt.event.@Nullable FocusEvent e) { + if (!oldVal.equals(textTo.getText())) { + long newTime = 0; + try { + newTime = fFormat.parseValue(textTo.getText()); + ITmfTimestamp fromTime = TmfTimestamp.fromNanos(newTime); + fEndTimeA = fromTime; + textTo.setText(fEndTimeA.toString(fFormat)); + + updateSelectedRange(); + chartViewer.selectionRangeUpdated(new TmfSelectionRangeUpdatedSignal(this, fStartTimeA, fEndTimeA, getTrace())); + + } catch (ParseException e1) { + textTo.setText(oldVal); + e1.printStackTrace(); + } + } + } + }); + textTo.setText(fEndTimeA.toString(fFormat)); + panelTo.add(labelATo); + panelTo.add(textTo); + ftextATo = textTo; + } + + private void createLabelToB(java.awt.Frame frameTo, java.awt.Panel panelTo, JFormattedTextField textTo, Color backgroundColor, Color foregroundColor, TmfXYChartViewer chartViewer) { + frameTo.add(panelTo); + JLabel labelBTo = new JLabel(); + labelBTo.setText(Messages.multipleDensityViewTo); + + // Set the background and foreground colors + panelTo.setBackground(backgroundColor); + textTo.setBackground(backgroundColor); + labelBTo.setBackground(backgroundColor); + + textTo.setForeground(foregroundColor); + labelBTo.setForeground(foregroundColor); + + textTo.addFocusListener(new java.awt.event.FocusListener() { + + public @Nullable String oldVal = null; + + @Override + public void focusGained(java.awt.event.@Nullable FocusEvent e) { + oldVal = textTo.getText(); + } + + @Override + public void focusLost(java.awt.event.@Nullable FocusEvent e) { + if (oldVal != null && !oldVal.equals(textTo.getText())) { + long newTime = 0; + try { + newTime = fFormat.parseValue(textTo.getText()); + ITmfTimestamp fromTime = TmfTimestamp.fromNanos(newTime); + fEndTimeB = fromTime; + textTo.setText(fEndTimeB.toString(fFormat)); + updateSelectedRange(); + chartViewer.selectionRangeUpdated(new TmfSelectionRangeUpdatedSignal(this, fStartTimeA, fEndTimeA, getTrace())); + + } catch (ParseException e1) { + textTo.setText(oldVal); + e1.printStackTrace(); + } + } + } + + }); + textTo.setText(fEndTimeB.toString(fFormat)); + panelTo.add(labelBTo); + panelTo.add(textTo); + ftextBTo = textTo; + } + + private void createControlPaintListenerA(TmfXYChartViewer chartViewer, SashForm sashFormLeftChildA) { + chartViewer.getControl().addPaintListener(new PaintListener() { + @Override + public void paintControl(@Nullable PaintEvent e) { + /* + * Sashes in a SashForm are being created on layout so we need + * to add the drag listener here. + */ + Listener sashDragListener = fSashDragListener; + if (sashDragListener == null) { + for (Control control : sashFormLeftChildA.getChildren()) { + if (control instanceof Sash) { + sashDragListener = event -> TmfSignalManager.dispatchSignal(new TmfTimeViewAlignmentSignal(sashFormLeftChildA, getTimeViewAlignmentInfo(chartViewer, sashFormLeftChildA))); + fSashDragListener = sashDragListener; + control.removePaintListener(this); + control.addListener(SWT.Selection, sashDragListener); + // There should be only one sash + break; + } + + } + } + } + }); + } + + private void createControlPaintListenerB(TmfXYChartViewer chartViewer, SashForm sashFormLeftChildB) { + chartViewer.getControl().addPaintListener(new PaintListener() { + @Override + public void paintControl(@Nullable PaintEvent e) { + /* + * Sashes in a SashForm are being created on layout so we need + * to add the drag listener here. + */ + Listener sashDragListener = fSashDragListener; + if (sashDragListener == null) { + for (Control control : sashFormLeftChildB.getChildren()) { + if (control instanceof Sash) { + sashDragListener = event -> TmfSignalManager.dispatchSignal(new TmfTimeViewAlignmentSignal(sashFormLeftChildB, getTimeViewAlignmentInfo(chartViewer, sashFormLeftChildB))); + fSashDragListener = sashDragListener; + control.removePaintListener(this); + control.addListener(SWT.Selection, sashDragListener); + // There should be only one sash + break; + } + + } + } + } + }); + } + + private void addTextFocusListener(Text text, TmfXYChartViewer chartViewerA, TmfXYChartViewer chartViewerB, TmfViewer tmfViewerA, TmfViewer tmfViewerB) { + text.addFocusListener(new FocusListener() { + + @Override + public void focusGained(@Nullable FocusEvent e) { + // Does nothing + } + + @Override + public void focusLost(@Nullable FocusEvent e) { + if (ftextQuery != null) { + String query = ftextQuery.getText(); + if (query == null) { + return; + } + boolean parsed = parseComparisonQuery(query); + if (parsed) { + /// Updating blue lines in density chats + chartViewerA.selectionRangeUpdated(new TmfSelectionRangeUpdatedSignal(this, fStartTimeA, fEndTimeA, getTrace())); + chartViewerB.selectionRangeUpdated(new TmfSelectionRangeUpdatedSignal(this, fStartTimeB, fEndTimeB, getTrace())); + + // treeViewerA + List treeWholeElements = ((MultipleEventDensityViewer) chartViewerA).getWholeCheckedItems(); + List treeCheckedElements = updateCheckedElements(treeWholeElements, true); + + setCheckedElements(chartViewerA, tmfViewerA, treeCheckedElements, true); + // treeViewerB + treeWholeElements = ((MultipleEventDensityViewer) chartViewerB).getWholeCheckedItems(); + treeCheckedElements = updateCheckedElements(treeWholeElements, false); + + setCheckedElements(chartViewerB, tmfViewerB, treeCheckedElements, true); + + TmfComparisonFilteringUpdatedSignal rangUpdateSignal = new TmfComparisonFilteringUpdatedSignal(this, fStartTimeA, fEndTimeA, fStartTimeB, fEndTimeB, fStatistic, fTraceListA, fTraceListB); + TmfSignalManager.dispatchSignal(rangUpdateSignal); + buildDifferentialFlameGraph(); + } + } + } + }); + } + + private List updateCheckedElements(List treeWholeElements, boolean isGroupA) { + List treeCheckedElements = new ArrayList<>(); + if (isGroupA) { + for (ITmfTreeViewerEntry trace : treeWholeElements) { + if (fTraceListA.contains(trace.getName())) { + treeCheckedElements.add(trace); + treeCheckedElements.addAll(trace.getChildren()); + } + } + } else { + for (ITmfTreeViewerEntry trace : treeWholeElements) { + if (fTraceListB.contains(trace.getName())) { + treeCheckedElements.add(trace); + treeCheckedElements.addAll(trace.getChildren()); + } + } + } + return treeCheckedElements; + } + + private static void createExpandBarListener(ExpandBar bar, Composite queryText, SashForm sashForm) { + bar.addExpandListener(new ExpandListener() { + + @Override + public void itemExpanded(@Nullable ExpandEvent e) { + Display.getCurrent().asyncExec(() -> { + queryText.pack(true); + sashForm.setWeights(DEFAULT_WEIGHTS_ShowQuery); + + }); + } + + @Override + public void itemCollapsed(@Nullable ExpandEvent e) { + Display.getCurrent().asyncExec(() -> { + queryText.pack(true); + sashForm.setWeights(DEFAULT_WEIGHTS_HideQuery); + }); + } + }); + } + + /** + * Returns the time alignment information + * + * @param chartViewer + * the event distribution viewer + * @param sashFormLeftChild + * the check box viewer + * @return the time alignment information + */ + public TmfTimeViewAlignmentInfo getTimeViewAlignmentInfo(TmfXYChartViewer chartViewer, SashForm sashFormLeftChild) { + return new TmfTimeViewAlignmentInfo(chartViewer.getControl().getShell(), sashFormLeftChild.toDisplay(0, 0), getTimeAxisOffset(chartViewer, sashFormLeftChild)); + } + + private static int getTimeAxisOffset(TmfXYChartViewer chartViewer, SashForm sashFormLeftChild) { + return sashFormLeftChild.getChildren()[0].getSize().x + sashFormLeftChild.getSashWidth() + chartViewer.getPointAreaOffset(); + } + + @Override + @TmfSignalHandler + public void traceSelected(final TmfTraceSelectedSignal signal) { + super.traceSelected(signal); + if (fTmfViewerA instanceof TmfTimeViewer tmfViewerA) { + tmfViewerA.traceSelected(signal); + } + if (fChartViewerA != null) { + fChartViewerA.traceSelected(signal); + } + + if (fTmfViewerB instanceof TmfTimeViewer tmfViewerB) { + tmfViewerB.traceSelected(signal); + } + + if (fChartViewerB != null) { + fChartViewerB.traceSelected(signal); + } + ITmfTrace trace = signal.getTrace(); + fStartTimeA = trace.getStartTime(); + fEndTimeA = trace.getEndTime(); + fStartTimeB = trace.getStartTime(); + fEndTimeB = trace.getEndTime(); + + ftextAFrom.setText(fStartTimeA.toString(fFormat)); + ftextBFrom.setText(fStartTimeB.toString(fFormat)); + ftextATo.setText(fEndTimeA.toString(fFormat)); + ftextBTo.setText(fEndTimeB.toString(fFormat)); + + TmfComparisonFilteringUpdatedSignal rangUpdateSignal = new TmfComparisonFilteringUpdatedSignal(this, fStartTimeA, fEndTimeA, fStartTimeB, fEndTimeB, fStatistic, fTraceListA, fTraceListB); + TmfSignalManager.dispatchSignal(rangUpdateSignal); + if (ftextQuery != null) { + ftextQuery.setText(buildComparisonQuery()); + } + buildDifferentialFlameGraph(); + } + + private Action createStatisticAction(String name) { + return new Action(name, IAction.AS_RADIO_BUTTON) { + @Override + public void run() { + ITmfTrace trace = getTrace(); + if (trace == null) { + return; + } + fStatistic = name; + TmfComparisonFilteringUpdatedSignal rangUpdateSignal = new TmfComparisonFilteringUpdatedSignal(this, fStatistic, null, null); + TmfSignalManager.dispatchSignal(rangUpdateSignal); + if (ftextQuery != null) { + ftextQuery.setText(buildComparisonQuery()); + } + buildDifferentialFlameGraph(); + } + }; + } + + /** + * Signal that the trace was opened + * + * @param signal + * the trace open signal + */ + @TmfSignalHandler + public void traceOpened(TmfTraceOpenedSignal signal) { + if (fChartViewerA != null) { + fChartViewerA.traceOpened(signal); + } + if (fChartViewerB != null) { + fChartViewerB.traceOpened(signal); + } + + } + + private void buildDifferentialFlameGraph() { + + ITmfTrace activetrace = TmfTraceManager.getInstance().getActiveTrace(); + if (activetrace != null) { + Display.getDefault().asyncExec(() -> buildFlameGraph(activetrace, null, null)); + + } + } + + /** + * Creates left child viewer for event density chart + * + * @param parent + * composite + * @return left chart viewer + */ + public TmfViewer createLeftChildViewer(Composite parent) { + EventDensityTreeViewer histogramTreeViewer = new EventDensityTreeViewer(parent); + ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace(); + if (trace != null) { + histogramTreeViewer.traceSelected(new TmfTraceSelectedSignal(this, trace)); + } + return histogramTreeViewer; + } + + private TmfXYChartViewer createChartViewer(Composite parent) { + MultipleEventDensityViewer chartViewer = new MultipleEventDensityViewer(parent, new TmfXYChartSettings(null, null, Y_AXIS_LABEL, 1)); + chartViewer.setSendTimeAlignSignals(true); + chartViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + chartViewer.getControl().addMouseListener(new MouseAdapter() { + @Override + public void mouseDoubleClick(@Nullable MouseEvent e) { + super.mouseDoubleClick(e); + resetStartFinishTime(true, chartViewer); + } + }); + chartViewer.getControl().addFocusListener(new FocusListener() { + @Override + public void focusLost(@Nullable FocusEvent e) { + deactivateContextService(); + } + + @Override + public void focusGained(@Nullable FocusEvent e) { + activateContextService(); + } + }); + + return chartViewer; + } + + /** + * Sets checked for the elements in TreeCheckedElements + * + * @param chart + * the chart viewer + * @param tree + * the tree viewer + * @param treeCheckedElements + * the elements in tree that should be checked + * @param queryUpdate + * updates the check state of the tree viewer if true + */ + public void setCheckedElements(TmfXYChartViewer chart, TmfViewer tree, List treeCheckedElements, boolean queryUpdate) { + if (queryUpdate) { + ((MultipleEventDensityViewer) chart).updateCheckStateChangedEvent(treeCheckedElements); + } else { + ((MultipleEventDensityViewer) chart).handleCheckStateChangedEvent(treeCheckedElements); + } + Object[] treeCheckedElementsObj = new Object[treeCheckedElements.size()]; + + treeCheckedElements.toArray(treeCheckedElementsObj); + ((AbstractSelectTreeViewer2) tree).getTriStateFilteredCheckboxTree().setCheckedElements(treeCheckedElementsObj); + } + + /** + * Resets the start and end times. + * + * @param notify + * indicating if we should broadcast the update signal + * @param chart + * determines which chart to reset start and end times + */ + public void resetStartFinishTime(boolean notify, TmfXYChartViewer chart) { + if (notify) { + TmfWindowRangeUpdatedSignal signal = new TmfWindowRangeUpdatedSignal(this, TmfTimeRange.ETERNITY, getTrace()); + broadcast(signal); + + } + } + + private void deactivateContextService() { + if (fContextService != null) { + fContextService.deactivateContexts(fActiveContexts); + fActiveContexts.clear(); + } + } + + private void activateContextService() { + if (fActiveContexts.isEmpty() && fContextService != null) { + IContextActivation activateContext = fContextService.activateContext(TMF_VIEW_UI_CONTEXT); + Objects.requireNonNull(activateContext); + fActiveContexts.add(activateContext); + } + } + + private static void coupleSelectViewer(TmfViewer tree, TmfXYChartViewer chart) { + if (tree instanceof AbstractSelectTreeViewer2 selectTree && chart instanceof TmfFilteredXYChartViewer chartViewer) { + ILegendImageProvider2 legendImageProvider = new XYChartLegendImageProvider((TmfCommonXAxisChartViewer) chart); + selectTree.addTreeListener(chartViewer); + selectTree.setLegendImageProvider(legendImageProvider); + TriStateFilteredCheckboxTree checkboxTree = selectTree.getTriStateFilteredCheckboxTree(); + checkboxTree.addPreCheckStateListener(new ManyEntriesSelectedDialogPreCheckedListener(checkboxTree)); + } + } + + /** + * @param signal + * TmfSelectionRangeUpdatedSignal signal raised when time ranges + * are updated + */ + @TmfSignalHandler + public void selectionRangeUpdated(TmfSelectionRangeUpdatedSignal signal) { + Object source = signal.getSource(); + if (source == fChartViewerA) { + fStartTimeA = signal.getBeginTime(); + fEndTimeA = signal.getEndTime(); + ftextAFrom.setText(fStartTimeA.toString(fFormat)); + ftextATo.setText(fEndTimeA.toString(fFormat)); + + } else if (source == fChartViewerB) { + fStartTimeB = signal.getBeginTime(); + fEndTimeB = signal.getEndTime(); + ftextBFrom.setText(fStartTimeB.toString(fFormat)); + ftextBTo.setText(fEndTimeB.toString(fFormat)); + } + updateSelectedRange(); + + } + + /** + * Updates the filtering parameters and query and builds flamegraph + */ + public void updateSelectedRange() { + try (ScopeLog sl = new ScopeLog(LOGGER, Level.FINE, "MultiDensityView::SelectionRangeUpdated")) { //$NON-NLS-1$ + TmfComparisonFilteringUpdatedSignal rangUpdateSignal = new TmfComparisonFilteringUpdatedSignal(this, fStartTimeA, fEndTimeA, fStartTimeB, fEndTimeB, null, null, null); + TmfSignalManager.dispatchSignal(rangUpdateSignal); + Display.getDefault().syncExec(() -> { + if (ftextQuery != null) { + ftextQuery.setText(buildComparisonQuery()); + } + }); + buildDifferentialFlameGraph(); + } + } + + /** + * Get the statistic type + * + * @return fStatistic (Duration or Self time) which will be represented in + * the flame graph + */ + public String getStatisticType() { + return fStatistic; + + } + + private Action getAggregateByAction() { + Action configureStatisticAction = new Action(Messages.flameGraphViewGroupByName, IAction.AS_DROP_DOWN_MENU) { + }; + configureStatisticAction.setToolTipText(Messages.flameGraphViewStatisticTooltip); + configureStatisticAction.setMenuCreator(new IMenuCreator() { + @Nullable + Menu menu = null; + + @Override + public void dispose() { + if (menu != null) { + menu.dispose(); + menu = null; + } + } + + @Override + public @Nullable Menu getMenu(@Nullable Control parent) { + return null; + } + + @Override + public @Nullable Menu getMenu(@Nullable Menu parent) { + menu = new Menu(parent); + + Action statisticActionDur = createStatisticAction(Objects.requireNonNull(Messages.multipleDensityViewDuration)); + new ActionContributionItem(statisticActionDur).fill(menu, -1); + + Action statisticActionSelf = createStatisticAction(Objects.requireNonNull(Messages.multipleDensityViewSelfTime)); + new ActionContributionItem(statisticActionSelf).fill(menu, -1); + return menu; + + } + }); + + return Objects.requireNonNull(configureStatisticAction); + } + + /** + * @param signal + * the TmfCheckboxChangedSignal signal + */ + @TmfSignalHandler + public void checkBoxUpdated(TmfCheckboxChangedSignal signal) { + try (ScopeLog sl = new ScopeLog(LOGGER, Level.FINE, "MultiDensityView::CheckBoxUpdated")) {//$NON-NLS-1$ + TmfComparisonFilteringUpdatedSignal rangUpdateSignal = null; + + if (signal.getSource() == fChartViewerA) { + fTraceListA.clear(); + for (String name : signal.getTraceList()) { + fTraceListA.add(name); + } + + rangUpdateSignal = new TmfComparisonFilteringUpdatedSignal(this, null, fTraceListA, null); + TmfSignalManager.dispatchSignal(rangUpdateSignal); + } + + if (signal.getSource() == fChartViewerB) { + fTraceListB.clear(); + for (String name : signal.getTraceList()) { + fTraceListB.add(name); + } + + rangUpdateSignal = new TmfComparisonFilteringUpdatedSignal(this, null, null, fTraceListB); + TmfSignalManager.dispatchSignal(rangUpdateSignal); + + } + if (ftextQuery != null) { + ftextQuery.setText(buildComparisonQuery()); + } + buildDifferentialFlameGraph(); + } + + } + + @Override + public void handleCheckStateChangedEvent(@SuppressWarnings("null") Collection entries) { + // do nothing + } + + @Override + public void dispose() { + super.dispose(); + TmfSignalManager.deregister(this); + + if (fChartViewerA != null) { + fChartViewerA.dispose(); + } + if (fTmfViewerA != null) { + fTmfViewerA.dispose(); + } + if (fChartViewerB != null) { + fChartViewerB.dispose(); + } + if (fTmfViewerB != null) { + fTmfViewerB.dispose(); + } + if (fXYViewerContainerA != null) { + fXYViewerContainerA.dispose(); + } + if (fXYViewerContainerB != null) { + fXYViewerContainerB.dispose(); + } + if (fContextService != null) { + fContextService.dispose(); + } + if (fSashFormLeftChildA != null) { + fSashFormLeftChildA.dispose(); + } + if (fSashFormLeftChildB != null) { + fSashFormLeftChildB.dispose(); + } + if (fsashForm != null) { + fsashForm.dispose(); + } + } + + /* + * Constructs a query string based on the current state of selected traces + * and time ranges + */ + private String buildComparisonQuery() { + StringBuilder query = new StringBuilder(); + /// Query PartA + query.append(TRACE_NAME); + for (String trace : fTraceListA) { + if (!trace.equals("Total")) { //$NON-NLS-1$ + query.append(trace); + query.append(","); //$NON-NLS-1$ + } + } + query.append(System.lineSeparator()); + + query.append(Messages.multipleDensityViewFrom); + query.append(fStartTimeA.toString(fFormat)); + query.append(System.lineSeparator()); + + query.append(Messages.multipleDensityViewTo); + query.append(fEndTimeA.toString(fFormat)); + query.append(System.lineSeparator()); + + query.append(Messages.multipleDensityViewQueryCompare); + query.append(System.lineSeparator()); + + /// Query PartB + query.append(TRACE_NAME); + for (String trace : fTraceListB) { + if (!trace.equals("Total")) { //$NON-NLS-1$ + query.append(trace); + query.append(","); //$NON-NLS-1$ + } + } + query.append(System.lineSeparator()); + + query.append(Messages.multipleDensityViewFrom); + query.append(fStartTimeB.toString(fFormat)); + query.append(System.lineSeparator()); + + query.append(Messages.multipleDensityViewTo); + query.append(fEndTimeB.toString(fFormat)); + query.append(System.lineSeparator()); + + //// Query Statistic Part + query.append(STATISTIC_NAME); + query.append(fStatistic); + + return query.toString(); + } + + /* + * Parses a structured text query into trace and time selection parameters + */ + boolean parseComparisonQuery(String query) { + try { + String lineSeparator = System.lineSeparator(); + if (lineSeparator != null) { + String[] parts = query.split(lineSeparator); + // Times + + if (parts[1].indexOf(Messages.multipleDensityViewFrom) == -1) { + return false; + } + String fromStrA = parts[1].substring(parts[1].indexOf(Messages.multipleDensityViewFrom) + Messages.multipleDensityViewFrom.length(), parts[1].length()); + fStartTimeA = TmfTimestamp.fromNanos(fFormat.parseValue(fromStrA)); + + if (parts[2].indexOf(Messages.multipleDensityViewTo) == -1) { + return false; + } + String toStrA = parts[2].substring(parts[2].indexOf(Messages.multipleDensityViewTo) + Messages.multipleDensityViewTo.length(), parts[2].length()); + fEndTimeA = TmfTimestamp.fromNanos(fFormat.parseValue(toStrA)); + + if (parts[5].indexOf(Messages.multipleDensityViewFrom) == -1) { + return false; + } + String fromStrB = parts[5].substring(parts[5].indexOf(Messages.multipleDensityViewFrom) + Messages.multipleDensityViewFrom.length(), parts[5].length()); + fStartTimeB = TmfTimestamp.fromNanos(fFormat.parseValue(fromStrB)); + + if (parts[6].indexOf(Messages.multipleDensityViewTo) == -1) { + return false; + } + String toStrB = parts[6].substring(parts[6].indexOf(Messages.multipleDensityViewTo) + Messages.multipleDensityViewTo.length(), parts[6].length()); + fEndTimeB = TmfTimestamp.fromNanos(fFormat.parseValue(toStrB)); + + // traceListA + if (parts[0].indexOf(TRACE_NAME) == -1) { + return false; + } + String traceStrtA = parts[0].substring(parts[0].indexOf(TRACE_NAME) + TRACE_NAME.length(), parts[0].length()); + String[] traces = traceStrtA.split(","); //$NON-NLS-1$ + + parseAndAddTraces(fTraceListA, traces); + + // traceListB + String traceStrtB = parts[4].substring(parts[4].indexOf(TRACE_NAME) + TRACE_NAME.length(), parts[4].length()); + String[] tracesB = traceStrtB.split(","); //$NON-NLS-1$ + + parseAndAddTraces(fTraceListB, tracesB); + + //// Statistic + fStatistic = parts[7].substring(parts[7].indexOf(STATISTIC_NAME) + STATISTIC_NAME.length(), parts[7].length()); + + // Set time range related objects + ftextAFrom.setText(fStartTimeA.toString(fFormat)); + ftextATo.setText(fEndTimeA.toString(fFormat)); + + ftextBFrom.setText(fStartTimeB.toString(fFormat)); + ftextBTo.setText(fEndTimeB.toString(fFormat)); + } + } catch (ParseException e) { + e.printStackTrace(); + return false; + } + return true; + } + + private static void parseAndAddTraces(List fTraceList, String[] traces) { + fTraceList.clear(); + for (String trace : traces) { + if (trace != null) { + fTraceList.add(trace); + } + } + } + +} diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/Messages.java b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/Messages.java similarity index 50% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/Messages.java rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/Messages.java index 26174fbdc..12cc4e842 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/Messages.java +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/Messages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2024 École Polytechnique de Montréal + * Copyright (c) 2024 École Polytechnique de Montréal, Ericsson * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License 2.0 which @@ -15,76 +15,118 @@ import org.eclipse.osgi.util.NLS; /** - * @author Fateme Faraji Daneshgar + * Message bundle class + * + * @author Fateme Faraji Daneshgar and Vlad Arama */ @NonNullByDefault({}) public class Messages extends NLS { private static final String BUNDLE_NAME = "org.eclipse.tracecompass.incubator.internal.executioncomparison.ui.messages"; //$NON-NLS-1$ + /** + * The color definition for the tool background. + */ + public static String background; + + /** + * The label for the data selection portion of the execution comparison ui + */ + public static String dataSelection; + /** * The label of GroupA */ - public static String MultipleDensityView_GroupA; + public static String multipleDensityViewGroupA; /** * The label of GroupB */ - public static String MultipleDensityView_GroupB; + public static String multipleDensityViewGroupB; /** * The label of Query Group */ - public static String MultipleDensityView_QueryGroup; + public static String multipleDensityViewQueryGroup; /** * The label of Query expandable item */ - public static String MultipleDensityView_QueryExpandable; + public static String multipleDensityViewQueryExpandable; /** * The label for time range selection (from) */ - public static String MultipleDensityView_From; + public static String multipleDensityViewFrom; /** * The label for time range selection (to) */ - public static String MultipleDensityView_To; + public static String multipleDensityViewTo; /** * The label for "compare to" in query */ - public static String MultipleDensityView_QueryCompare; + public static String multipleDensityViewQueryCompare; /** * The Duration statistics */ - public static String MultipleDensityView_Duration; + public static String multipleDensityViewDuration; /** * The selfTime statistic */ - public static String MultipleDensityView_SelfTime; + public static String multipleDensityViewSelfTime; /** * The title of execution comparison view */ - public static String MultipleDensityView_title; + public static String multipleDensityViewTitle; + + /** + * The id of execution comparison view + */ + public static String multipleDensityViewId; + + /** + * The color definition for the tool foreground. + */ + public static String foreground; /** * The action name for grouping */ - public static String FlameGraphView_GroupByName; + public static String flameGraphViewGroupByName; /** * The action tooltip for selecting between Duration and SelfTime */ - public static String FlameGraphView_StatisticTooltip; + public static String flameGraphViewStatisticTooltip; /** * Execution of the callGraph Analysis */ - public static String FlameGraphView_RetrievingData; + public static String flameGraphViewRetrievingData; + + /** + * Name of the traces + */ + public static String traceName; + + /** + * The context of the TmfView + */ + public static String tmfViewUiContext; + + /** + * Name of the statistics + */ + public static String statisticName; + + /** + * Label for the Y Axis + */ + public static String yAxisLabel; static { // initialize resource bundle @@ -93,4 +135,4 @@ public class Messages extends NLS { private Messages() { } -} \ No newline at end of file +} diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/MultipleEventDensityViewer.java b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/MultipleEventDensityViewer.java new file mode 100644 index 000000000..19a45f162 --- /dev/null +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/MultipleEventDensityViewer.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright (c) 2024 École Polytechnique de Montréal, Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License 2.0 which + * accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ + +package org.eclipse.tracecompass.incubator.internal.executioncomparison.ui; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.tracecompass.incubator.internal.executioncomparison.core.TmfCheckboxChangedSignal; +import org.eclipse.tracecompass.internal.tmf.ui.viewers.eventdensity.EventDensityViewer; +import org.eclipse.tracecompass.tmf.core.model.tree.TmfTreeDataModel; +import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ui.viewers.tree.ITmfTreeViewerEntry; +import org.eclipse.tracecompass.tmf.ui.viewers.tree.TmfGenericTreeEntry; +import org.eclipse.tracecompass.tmf.ui.viewers.xychart.linechart.TmfXYChartSettings; + +/** + * MultipleEventDensityViewer extends EventDensityViewer to override + * handleCheckStateChangedEvent in order to reflect changes to the differential + * flame graph + * + * @author Fateme Faraji Daneshgar and Vlad Arama + * + */ +@SuppressWarnings("restriction") +public class MultipleEventDensityViewer extends EventDensityViewer { + List fWholeTraceList = new ArrayList<>(); + + /** + * Constructor + * + * @param parent + * Composite + * @param settings + * ChartSetting + */ + public MultipleEventDensityViewer(Composite parent, TmfXYChartSettings settings) { + super(parent, settings); + } + + /* + * We override this method to avoid raising a signal for the second group of + * the MultipleEventDensityViewer, when a signal is raised from the first + * group. + */ + @Override + @TmfSignalHandler + public void selectionRangeUpdated(@Nullable TmfSelectionRangeUpdatedSignal signal) { + if (signal == null) { + return; + } + + /* + * Signal sent when changing the text boxes or changing the query from + * the ExecutionComparisonView. The trace context gets updated. + */ + if (!(signal.getSource() instanceof MultipleEventDensityViewer)) { + final ITmfTrace trace = getTrace(); + if (trace != null) { + ITmfTimestamp selectedTime = signal.getBeginTime(); + ITmfTimestamp selectedEndTime = signal.getEndTime(); + TmfTraceManager.getInstance().updateTraceContext(trace, + builder -> builder.setSelection(new TmfTimeRange(selectedTime, selectedEndTime))); + + } + super.selectionRangeUpdated(signal); + } + /* + * Signal being updated is itself, we set the selection range for the + * MultipleEventDensityViewer. + */ + if (signal.getSource() == this) { + final ITmfTrace trace = getTrace(); + if (trace != null) { + long selectedTime = signal.getBeginTime().toNanos(); + long selectedEndTime = signal.getEndTime().toNanos(); + setSelectionRange(selectedTime, selectedEndTime); + } + } + } + + /** + * Handles check state of tree viewer and keeps the list of whole trace + * list. Dispatches TmfCheckboxChangedSignal signal to update the + * differential flame graph + * + * @param entries + * list of entries that should be checked + */ + + @Override + public void handleCheckStateChangedEvent(@SuppressWarnings("null") Collection entries) { + super.handleCheckStateChangedEvent(entries); + updateTraceList(entries); + List traceNames = new ArrayList<>(); + for (ITmfTreeViewerEntry entry : entries) { + if (entry instanceof TmfGenericTreeEntry) { + TmfGenericTreeEntry genericEntry = (TmfGenericTreeEntry) entry; + if (genericEntry.getModel() instanceof TmfTreeDataModel) { + TmfTreeDataModel model = (TmfTreeDataModel) genericEntry.getModel(); + if (model != null) { + String name = model.getName(); + traceNames.add(name); + } + } + } + } + TmfSignalManager.dispatchSignal(new TmfCheckboxChangedSignal(this, traceNames)); + } + + /* + * Keeps fWholeTraceList updated to include all entries for experiment. it + * will be used when the checkedboxtree is reset. + */ + private void updateTraceList(Collection entries) { + for (ITmfTreeViewerEntry entry : entries) { + if (!fWholeTraceList.contains(entry)) { + fWholeTraceList.add(entry); + } + } + + } + + /** + * Get WholeCheckedItems which is the checked item in the tree viewer + * + * @return fWholeTraceList list of checked Items in tree viewer + */ + public List getWholeCheckedItems() { + return fWholeTraceList; + } + + /** + * Handles check state of the treeviewer, used in updating tree viewers with + * query updating + * + * @param entries + * list of entries that should be checked + */ + public void updateCheckStateChangedEvent(Collection entries) { + super.handleCheckStateChangedEvent(entries); + } + +} diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/messages.properties b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/messages.properties new file mode 100644 index 000000000..a5a2d0efd --- /dev/null +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/messages.properties @@ -0,0 +1,31 @@ +############################################################################### + # Copyright (c) 2024 �cole Polytechnique de Montr�al, Ericsson + # + # All rights reserved. This program and the accompanying materials are + # made available under the terms of the Eclipse Public License 2.0 which + # accompanies this distribution, and is available at + # https://www.eclipse.org/legal/epl-2.0/ + # + # SPDX-License-Identifier: EPL-2.0 +############################################################################### +background=org.eclipse.tracecompass.tmf.ui.TOOL_BACKGROUND +dataSelection=Data Selection +foreground=org.eclipse.tracecompass.tmf.ui.TOOL_FOREGROUND +multipleDensityViewGroupA=GroupA +multipleDensityViewGroupB=GroupB +multipleDensityViewQueryGroup=Filtering Query +multipleDensityViewQueryCompare=Compare to: +multipleDensityViewFrom=From: +multipleDensityViewTo=To: +multipleDensityViewDuration=Duration +multipleDensityViewSelfTime=Self Time +multipleDensityViewTitle=Execution Comparison +multipleDensityViewId=org.eclipse.tracecompass.incubator.internal.executioncomparison.ui.execComparison +flameGraphViewRetrievingData=Retrieving Flame Graph Data +flameGraphViewGroupByName=Group by Descriptor +flameGraphViewStatisticTooltip=Select the statistic to represent +multipleDensityViewQueryExpandable=Get filtering query +tmfViewUiContext=org.eclipse.tracecompass.tmf.ui.view.context +traceName=Trace(s): +statisticName=Statistic: +yAxisLabel=Event Count diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/package-info.java b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/package-info.java similarity index 61% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/package-info.java rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/package-info.java index 6d35069a7..030aa9826 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/package-info.java +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison.ui/src/org/eclipse/tracecompass/incubator/internal/executioncomparison/ui/package-info.java @@ -1,15 +1,12 @@ /******************************************************************************* - * Copyright (c) 2024 École Polytechnique de Montréal + * Copyright (c) 2024 École Polytechnique de Montréal, Ericsson * - * All rights reserved. This program and the accompanying materials are - * made available under the terms of the Eclipse Public License 2.0 which - * accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 which accompanies + * this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ @org.eclipse.jdt.annotation.NonNullByDefault package org.eclipse.tracecompass.incubator.internal.executioncomparison.ui; - - diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision/.project b/analyses/org.eclipse.tracecompass.incubator.executioncomparison/.project similarity index 100% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision/.project rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison/.project diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision/build.properties b/analyses/org.eclipse.tracecompass.incubator.executioncomparison/build.properties similarity index 90% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision/build.properties rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison/build.properties index de40c6279..f05b3e5b7 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision/build.properties +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison/build.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2022 École Polytechnique de Montréal +# Copyright (c) 2024 École Polytechnique de Montréal # # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparision/feature.properties b/analyses/org.eclipse.tracecompass.incubator.executioncomparison/feature.properties similarity index 82% rename from analyses/org.eclipse.tracecompass.incubator.executioncomparision/feature.properties rename to analyses/org.eclipse.tracecompass.incubator.executioncomparison/feature.properties index f9f49a686..7e589fd1d 100644 --- a/analyses/org.eclipse.tracecompass.incubator.executioncomparision/feature.properties +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison/feature.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2022 École Polytechnique de Montréal +# Copyright (c) 2024 École Polytechnique de Montréal # # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 @@ -9,7 +9,7 @@ # SPDX-License-Identifier: EPL-2.0 ############################################################################### -featureName=Trace Compass ExecutionComparision (Incubation) +featureName=Trace Compass ExecutionComparison (Incubation) description= diff --git a/analyses/org.eclipse.tracecompass.incubator.executioncomparison/feature.xml b/analyses/org.eclipse.tracecompass.incubator.executioncomparison/feature.xml new file mode 100644 index 000000000..2c677d0e1 --- /dev/null +++ b/analyses/org.eclipse.tracecompass.incubator.executioncomparison/feature.xml @@ -0,0 +1,43 @@ + + + + + %description + + + + %copyright + + + + %license + + + + + + + + + diff --git a/callstack/org.eclipse.tracecompass.incubator.analysis.core.tests/src/org/eclipse/tracecompass/incubator/analysis/core/tests/weighted/diff/WeightedTreeUtilsTest.java b/callstack/org.eclipse.tracecompass.incubator.analysis.core.tests/src/org/eclipse/tracecompass/incubator/analysis/core/tests/weighted/diff/WeightedTreeUtilsTest.java index a5a7bb10d..4c6a0432b 100644 --- a/callstack/org.eclipse.tracecompass.incubator.analysis.core.tests/src/org/eclipse/tracecompass/incubator/analysis/core/tests/weighted/diff/WeightedTreeUtilsTest.java +++ b/callstack/org.eclipse.tracecompass.incubator.analysis.core.tests/src/org/eclipse/tracecompass/incubator/analysis/core/tests/weighted/diff/WeightedTreeUtilsTest.java @@ -115,7 +115,7 @@ public void setupTrees() { } /** - * Test the {@link WeightedTreeUtils#diffTrees(Collection, Collection)} + * Test the {@link WeightedTreeUtils#diffTrees(Collection, Collection, String)} * method with simple trees */ @Test @@ -126,11 +126,11 @@ public void testDiffTree() { assertNotNull(tree2); // Differentiate tree1 and tree2 - Collection> diffTrees = WeightedTreeUtils.diffTrees(tree1, tree2); + Collection> diffTrees = WeightedTreeUtils.diffTrees(tree1, tree2, null); verifyDiffTrees12(diffTrees); // Reverse: Differentiate tree2 and tree1 - diffTrees = WeightedTreeUtils.diffTrees(tree2, tree1); + diffTrees = WeightedTreeUtils.diffTrees(tree2, tree1, null); verifyDiffTrees21(diffTrees); } diff --git a/callstack/org.eclipse.tracecompass.incubator.analysis.core/src/org/eclipse/tracecompass/incubator/analysis/core/weighted/tree/diff/WeightedTreeUtils.java b/callstack/org.eclipse.tracecompass.incubator.analysis.core/src/org/eclipse/tracecompass/incubator/analysis/core/weighted/tree/diff/WeightedTreeUtils.java index 91afdc798..52819dd86 100644 --- a/callstack/org.eclipse.tracecompass.incubator.analysis.core/src/org/eclipse/tracecompass/incubator/analysis/core/weighted/tree/diff/WeightedTreeUtils.java +++ b/callstack/org.eclipse.tracecompass.incubator.analysis.core/src/org/eclipse/tracecompass/incubator/analysis/core/weighted/tree/diff/WeightedTreeUtils.java @@ -22,6 +22,7 @@ import org.eclipse.tracecompass.analysis.profiling.core.tree.IWeightedTreeProvider; import org.eclipse.tracecompass.analysis.profiling.core.tree.IWeightedTreeSet; import org.eclipse.tracecompass.analysis.profiling.core.tree.WeightedTree; +import org.eclipse.tracecompass.internal.analysis.profiling.core.callgraph2.AggregatedCalledFunction; import org.eclipse.tracecompass.tmf.core.util.Pair; import com.google.common.collect.ImmutableList; @@ -31,6 +32,7 @@ * * @author Geneviève Bastien */ +@SuppressWarnings("restriction") public final class WeightedTreeUtils { private WeightedTreeUtils() { @@ -48,26 +50,83 @@ private WeightedTreeUtils() { * The tree that will be differentiated. * @param second * The tree to use as the base + * @param statisticType + * Determines the statistic (duration or self time) that the + * flame graph will represent * @return The differential weighted tree */ - public static <@NonNull T> Collection> diffTrees(Collection> first, Collection> second) { + public static <@NonNull T> Collection> diffTrees(Collection> first, Collection> second, @Nullable String statisticType) { List> diffTrees = new ArrayList<>(); for (WeightedTree base : second) { T object = base.getObject(); // Find the equivalent tree in the first collection WeightedTree other = findObject(first, object); - double diffWeight = other == null ? Double.NaN : (double) (base.getWeight() - other.getWeight()) / other.getWeight(); - DifferentialWeightedTree<@NonNull T> diffTree = new DifferentialWeightedTree<>(base, object, base.getWeight(), diffWeight); + DifferentialWeightedTree<@NonNull T> diffTree = calculateDiffTree(object, base, other, statisticType); diffTrees.add(diffTree); // Make the differential of the children - for (DifferentialWeightedTree childTree : diffTrees(other == null ? Collections.emptyList() : other.getChildren(), base.getChildren())) { + for (DifferentialWeightedTree childTree : diffTrees(other == null ? Collections.> emptyList() : other.getChildren(), base.getChildren(), null)) { diffTree.addChild(childTree); } } return diffTrees; } + private static DifferentialWeightedTree<@NonNull T> calculateDiffTree(@NonNull T object, WeightedTree<@NonNull T> base, @Nullable WeightedTree<@NonNull T> other, @Nullable String statisticType) { + double diffWeight; + double nullDiff = Double.NaN; + DifferentialWeightedTree<@NonNull T> diffTree; + if (statisticType == null) { + diffWeight = other == null ? nullDiff : (double) (base.getWeight() - other.getWeight()) / other.getWeight(); + diffTree = new DifferentialWeightedTree<>(base, object, base.getWeight(), diffWeight); + + } else { + long baseWeight = 0; + long otherWeight = 0; + if (base instanceof AggregatedCalledFunction) { + long[] weightsArray = calculateWeights(base, other, statisticType); + baseWeight = weightsArray[0]; + otherWeight = weightsArray[1]; + } else { + baseWeight = base.getWeight(); + otherWeight = other == null ? 0 : other.getWeight(); + } + if (other == null || otherWeight == 0) { + diffWeight = nullDiff; + } else { + diffWeight = (double) (baseWeight - otherWeight) / otherWeight; + } + diffTree = new DifferentialWeightedTree<>(base, object, base.getWeight(), diffWeight); + + } + return diffTree; + } + + private static long[] calculateWeights(WeightedTree<@NonNull T> base, @Nullable WeightedTree<@NonNull T> other, String statisticType) { + long baseWeight = 0; + long otherWeight = 0; + long[] weightsArray = new long[2]; + switch (statisticType) { + case "Self Time": //$NON-NLS-1$ + { + baseWeight = ((AggregatedCalledFunction) base).getSelfTime(); + otherWeight = other == null ? 0 : ((AggregatedCalledFunction) other).getSelfTime(); + break; + } + case "Duration": //$NON-NLS-1$ + { + baseWeight = ((AggregatedCalledFunction) base).getWeight(); + otherWeight = other == null ? 0 : ((AggregatedCalledFunction) other).getWeight(); + break; + } + default: + break; + } + weightsArray[0] = baseWeight; + weightsArray[1] = otherWeight; + return weightsArray; + } + /** * Does the differential between 2 weighted tree sets, ie for each * comparable elements, what happened in tree set 2 differently than in tree @@ -124,8 +183,8 @@ private WeightedTreeUtils() { for (Pair<@NonNull ?, @NonNull ?> pair : pairedElements) { Collection> trees1 = first.getTreesFor(pair.getFirst()); Collection> trees2 = second.getTreesFor(pair.getSecond()); - Collection> diffTrees = WeightedTreeUtils.diffTrees(trees1, trees2); - for (DifferentialWeightedTree tree: diffTrees) { + Collection> diffTrees = WeightedTreeUtils.diffTrees(trees1, trees2, null); + for (DifferentialWeightedTree tree : diffTrees) { treeSet.addWeightedTree(pair.getFirst(), tree); } } @@ -138,8 +197,10 @@ private WeightedTreeUtils() { Collection<@NonNull ?> elements2 = second.getElements(); // If there is only one element and it is not a tree, pair it if (elements1.size() == 1 && elements2.size() == 1) { - @NonNull Object element1 = elements1.iterator().next(); - @NonNull Object element2 = elements2.iterator().next(); + @NonNull + Object element1 = elements1.iterator().next(); + @NonNull + Object element2 = elements2.iterator().next(); if (!(element1 instanceof ITree) && !(element2 instanceof ITree)) { return ImmutableList.of(new Pair(element1, element2)); } @@ -158,8 +219,10 @@ private WeightedTreeUtils() { private static Collection> pairEqualElements(Collection<@NonNull ?> elements1, Collection<@NonNull ?> elements2) { List> pairedElements = new ArrayList<>(); - for (@NonNull Object element1 : elements1) { - for (@NonNull Object element2 : elements2) { + for (@NonNull + Object element1 : elements1) { + for (@NonNull + Object element2 : elements2) { if (element1.equals(element2)) { pairedElements.add(new Pair<>(element1, element1)); if (element1 instanceof ITree && element2 instanceof ITree) { @@ -174,11 +237,13 @@ private WeightedTreeUtils() { private static Collection> pairSameNameElements(Collection<@NonNull ?> elements1, Collection elements2) { List> pairedElements = new ArrayList<>(); - for (@NonNull Object element1 : elements1) { + for (@NonNull + Object element1 : elements1) { if (!(element1 instanceof ITree)) { continue; } - for (@NonNull Object element2 : elements2) { + for (@NonNull + Object element2 : elements2) { if (!(element2 instanceof ITree)) { continue; } diff --git a/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/callgraph/AbstractCalledFunction.java b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/callgraph/AbstractCalledFunction.java new file mode 100644 index 000000000..35850e692 --- /dev/null +++ b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/callgraph/AbstractCalledFunction.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright (c) 2016 Ericsson + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License 2.0 which + * accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ + +package org.eclipse.tracecompass.incubator.internal.callstack.core.instrumented.callgraph; + +import java.util.Comparator; +import java.util.Objects; + +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.common.core.NonNullUtils; +import org.eclipse.tracecompass.incubator.analysis.core.model.IHostModel; +import org.eclipse.tracecompass.incubator.callstack.core.callgraph.SymbolAspect; +import org.eclipse.tracecompass.incubator.callstack.core.instrumented.ICalledFunction; +import org.eclipse.tracecompass.segmentstore.core.ISegment; +import org.eclipse.tracecompass.segmentstore.core.SegmentComparators; + +import com.google.common.collect.Ordering; + +/** + * Called Functuon common class, defines the start, end, depth, parent and + * children. Does not define the symbol + * + * @author Matthew Khouzam + * @author Sonia Farrah + */ +abstract class AbstractCalledFunction implements ICalledFunction { + + static final Comparator COMPARATOR; + static { + /* + * requireNonNull() has to be called separately, or else it breaks the + * type inference. + */ + Comparator comp = Ordering.from(SegmentComparators.INTERVAL_START_COMPARATOR).compound(SegmentComparators.INTERVAL_END_COMPARATOR); + COMPARATOR = Objects.requireNonNull(comp); + } + + /** + * Serial Version UID + */ + private static final long serialVersionUID = 7992199223906717340L; + + protected final long fStart; + protected final long fEnd; + private final @Nullable ICalledFunction fParent; + protected long fSelfTime = 0; + private final int fProcessId; + private final int fThreadId; + + private final transient IHostModel fModel; + private transient long fCpuTime = Long.MIN_VALUE; + + public AbstractCalledFunction(long start, long end, int processId, int threadId, @Nullable ICalledFunction parent, IHostModel model) { + if (start > end) { + throw new IllegalArgumentException(Messages.TimeError + "[" + start + "," + end + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + fStart = start; + fEnd = end; + fParent = parent; + // It'll be modified once we add a child to it + fSelfTime = fEnd - fStart; + fProcessId = processId; + fThreadId = threadId; + if (parent instanceof AbstractCalledFunction) { + ((AbstractCalledFunction) parent).addChild(this); + } + fModel = model; + } + + @Override + public long getStart() { + return fStart; + } + + @Override + public long getEnd() { + return fEnd; + } + + @Override + public @Nullable ICalledFunction getParent() { + return fParent; + } + + @Override + public String getName() { + return NonNullUtils.nullToEmptyString(SymbolAspect.SYMBOL_ASPECT.resolve(this)); + } + + /** + * Add the child to the segment's children, and subtract the child's + * duration to the duration of the segment so we can calculate its self + * time. + * + * @param child + * The child to add to the segment's children + */ + protected void addChild(ICalledFunction child) { + if (child.getParent() != this) { + throw new IllegalArgumentException("Child parent not the same as child being added to."); //$NON-NLS-1$ + } + substractChildDuration(child.getEnd() - child.getStart()); + } + + /** + * Subtract the child's duration to the duration of the segment. + * + * @param childDuration + * The child's duration + */ + private void substractChildDuration(long childDuration) { + fSelfTime -= childDuration; + } + + @Override + public long getSelfTime() { + return fSelfTime; + } + + @Override + public long getCpuTime() { + long cpuTime = fCpuTime; + if (cpuTime == Long.MIN_VALUE) { + cpuTime = fModel.getCpuTime(fThreadId, fStart, fEnd); + fCpuTime = cpuTime; + } + return cpuTime; + } + + @Override + public int getProcessId() { + return fProcessId; + } + + @Override + public int getThreadId() { + return fThreadId; + } + + @Override + public int compareTo(@Nullable ISegment o) { + if (o == null) { + throw new IllegalArgumentException(); + } + return COMPARATOR.compare(this, o); + } + + @Override + public String toString() { + return '[' + String.valueOf(fStart) + ", " + String.valueOf(fEnd) + ']' + " Duration: " + getLength() + ", Self Time: " + fSelfTime; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + @Override + public int hashCode() { + return Objects.hash(fEnd, fParent, fSelfTime, fStart, getSymbol()); + } + + @Override + public boolean equals(@Nullable Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + AbstractCalledFunction other = (AbstractCalledFunction) obj; + return (fEnd == other.fEnd && + fSelfTime == other.fSelfTime && + fStart == other.fStart && + Objects.equals(fParent, other.getParent()) && + Objects.equals(getSymbol(), other.getSymbol())); + } + +} \ No newline at end of file diff --git a/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/callgraph/AggregatedCalledFunction.java b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/callgraph/AggregatedCalledFunction.java new file mode 100644 index 000000000..e9d1d540f --- /dev/null +++ b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/callgraph/AggregatedCalledFunction.java @@ -0,0 +1,345 @@ +/******************************************************************************* + * Copyright (c) 2016 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 which + * accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ + +package org.eclipse.tracecompass.incubator.internal.callstack.core.instrumented.callgraph; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.analysis.os.linux.core.model.ProcessStatus; +import org.eclipse.tracecompass.analysis.timing.core.statistics.IStatistics; +import org.eclipse.tracecompass.incubator.analysis.core.concepts.AggregatedCallSite; +import org.eclipse.tracecompass.incubator.analysis.core.concepts.ICallStackSymbol; +import org.eclipse.tracecompass.incubator.analysis.core.concepts.ProcessStatusInterval; +import org.eclipse.tracecompass.incubator.analysis.core.model.IHostModel; +import org.eclipse.tracecompass.incubator.analysis.core.weighted.tree.WeightedTree; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +/** + * This class represents a function call in a certain level in the call stack. + * It's used to build an aggregation segment tree (aggregated by depth and + * callers). Per example,the two calls to the function A() in the call graph + * below will be combined into one node in the generated tree: + * + *
+ *   (Depth=0)      main              main
+ *               ↓↑  ↓↑   ↓↑    =>   ↓↑   ↓↑
+ *   (Depth=1)  A()  B()  A()       A()   B()
+ * 
+ * + * @author Sonia Farrah + * + */ +public class AggregatedCalledFunction extends AggregatedCallSite { + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private final AggregatedCalledFunctionStatistics fStatistics; + private long fDuration = 0; + private long fSelfTime = 0; + private long fCpuTime = IHostModel.TIME_UNKNOWN; + private int fProcessId; + private Map fProcessStatuses = new HashMap<>(); + + /** + * Constructor, parent is not null + * + * @param symbol + * The symbol of the function + */ + public AggregatedCalledFunction(ICallStackSymbol symbol) { + super(symbol, 0); + fStatistics = new AggregatedCalledFunctionStatistics(); + fProcessId = -1; + } + + /** + * copy constructor + * + * @param toCopy Object to copy + */ + public AggregatedCalledFunction(AggregatedCalledFunction toCopy) { + super(toCopy); + fStatistics = new AggregatedCalledFunctionStatistics(); + fStatistics.merge(toCopy.fStatistics); + fProcessId = toCopy.fProcessId; + fDuration = toCopy.fDuration; + fSelfTime = toCopy.fSelfTime; + fCpuTime = toCopy.fCpuTime; + mergeProcessStatuses(toCopy); + } + + @Override + public long getWeight() { + return fDuration; + } + + @Override + public AggregatedCalledFunction copyOf() { + return new AggregatedCalledFunction(this); + } + + @Override + protected void mergeData(@NonNull WeightedTree other) { + if (!(other instanceof AggregatedCalledFunction)) { + return; + } + AggregatedCalledFunction otherFct = (AggregatedCalledFunction) other; + + addToDuration(otherFct.getDuration()); + addToSelfTime(otherFct.getSelfTime()); + addToCpuTime(otherFct.getCpuTime()); + getFunctionStatistics().merge(otherFct.getFunctionStatistics(), true); + mergeProcessStatuses(otherFct); + } + + private void mergeProcessStatuses(AggregatedCalledFunction other) { + Map processStatuses = other.fProcessStatuses; + for (Entry entry : processStatuses.entrySet()) { + AggregatedThreadStatus status = fProcessStatuses.get(entry.getKey()); + if (status == null) { + status = new AggregatedThreadStatus(entry.getKey()); + } + status.merge(entry.getValue()); + fProcessStatuses.put(entry.getKey(), status); + } + } + + @Override + public Map> getStatistics() { + ImmutableMap.Builder> builder = new ImmutableMap.Builder<>(); + builder.put(String.valueOf(Messages.CallGraphStats_Duration), getFunctionStatistics().getDurationStatistics()); + builder.put(String.valueOf(Messages.CallGraphStats_SelfTime), getFunctionStatistics().getSelfTimeStatistics()); + builder.put(String.valueOf(Messages.CallGraphStats_CpuTime), getFunctionStatistics().getCpuTimesStatistics()); + return builder.build(); + } + + /** + * Add a new callee into the Callees list. If the function exists in the + * callees list, the new callee's duration will be added to its duration and + * it'll combine their callees. + * + * @param child + * The callee to add to this function + * @param aggregatedChild + * The aggregated data of the callee + */ + public synchronized void addChild(AbstractCalledFunction child, AggregatedCalledFunction aggregatedChild) { + // Update the child's statistics with itself + fSelfTime -= aggregatedChild.getDuration(); + aggregatedChild.addFunctionCall(child); + super.addChild(aggregatedChild); + } + + /** + * Adds a function call to this aggregated called function data. The called + * function must have the same symbol as this aggregate data and its + * statistics will be added to this one. This should be a function at the + * same level as this one. + * + * @param function + * The function that was called + */ + public synchronized void addFunctionCall(AbstractCalledFunction function) { + // FIXME: Aren't the statistics enough? Do we really need duration, self + // time and cpu time here? + addToDuration(function.getLength()); + addToSelfTime(function.getSelfTime()); + addToCpuTime(function.getCpuTime()); + fProcessId = function.getProcessId(); + getFunctionStatistics().update(function); + } + + /** + * Modify the function's duration + * + * @param duration + * The amount to increment the duration by + */ + private void addToDuration(long duration) { + fDuration += duration; + } + + // /** + // * Merge the callees of two functions. + // * + // * @param firstNode + // * The first parent secondNode The second parent + // */ + // private static void mergeChildren(AggregatedCalledFunction firstNode, + // AggregatedCalledFunction secondNode) { + // for (Map.Entry FunctionEntry : + // secondNode.fChildren.entrySet()) { + // Object childSymbol = Objects.requireNonNull(FunctionEntry.getKey()); + // AggregatedCalledFunction secondNodeChild = + // Objects.requireNonNull(FunctionEntry.getValue()); + // AggregatedCalledFunction aggregatedCalledFunction = + // firstNode.fChildren.get(childSymbol); + // if (aggregatedCalledFunction == null) { + // firstNode.fChildren.put(secondNodeChild.getSymbol(), secondNodeChild); + // } else { + // // combine children + // AggregatedCalledFunction firstNodeChild = aggregatedCalledFunction; + // merge(firstNodeChild, secondNodeChild, true); + // firstNode.fChildren.replace(firstNodeChild.getSymbol(), firstNodeChild); + // } + // } + // } + // + // /** + // * Merge two functions, add durations, self times, increment the calls, + // * update statistics and merge children. + // * + // * @param destination + // * the node to merge to + // * @param source + // * the node to merge + // */ + // private static void merge(AggregatedCalledFunction destination, + // AggregatedCalledFunction source, boolean isGroup) { + // long sourceDuration = source.getDuration(); + // long sourceSelfTime = source.getSelfTime(); + // destination.addToDuration(sourceDuration); + // destination.addToSelfTime(sourceSelfTime); + // destination.addToCpuTime(source.getCpuTime()); + // destination.getFunctionStatistics().merge(source.getFunctionStatistics(), + // isGroup); + // // merge the children callees. + // mergeChildren(destination, source); + // } + + private void addToCpuTime(long cpuTime) { + if (cpuTime != IHostModel.TIME_UNKNOWN) { + if (fCpuTime < 0) { + fCpuTime = 0; + } + fCpuTime += cpuTime; + } + } + + /** + * The function's duration + * + * @return The duration of the function + */ + public long getDuration() { + return fDuration; + } + + /** + * The number of calls of a function + * + * @return The number of calls of a function + */ + public long getNbCalls() { + return fStatistics.getDurationStatistics().getNbElements(); + } + + /** + * The self time of an aggregated function + * + * @return The self time + */ + public long getSelfTime() { + return fSelfTime; + } + + /** + * Add to the self time of an aggregated function + * + * @param selfTime + * The amount of self time to add + */ + private void addToSelfTime(long selfTime) { + fSelfTime += selfTime; + } + + /** + * The CPU time of an aggregated function + * + * @return The CPU time, or {@link IHostModel#TIME_UNKNOWN} if the CPU time + * is not known + */ + public long getCpuTime() { + return fCpuTime; + } + + /** + * The process ID of the trace application. + * + * @return The process Id + */ + public int getProcessId() { + return fProcessId; + } + + /** + * Add a process status interval tot his called function + * + * @param interval + * The process status interval + */ + public void addKernelStatus(ProcessStatusInterval interval) { + ProcessStatus processStatus = interval.getProcessStatus(); + AggregatedThreadStatus status = fProcessStatuses.get(processStatus); + if (status == null) { + status = new AggregatedThreadStatus(processStatus); + fProcessStatuses.put(processStatus, status); + } + status.update(interval); + } + + @Override + public @NonNull Collection<@NonNull WeightedTree<@NonNull ICallStackSymbol>> getExtraDataTrees(int index) { + if (index == 0) { + return ImmutableList.copyOf(fProcessStatuses.values()); + } + return Collections.emptyList(); + } + + @Override + public @Nullable IStatistics getStatistics(int metricIndex) { + if (metricIndex < 0) { + return getFunctionStatistics().getDurationStatistics(); + } + if (metricIndex == CallGraphAnalysis.SELF_TIME_METRIC_INDEX) { + return getFunctionStatistics().getSelfTimeStatistics(); + } + if (metricIndex == CallGraphAnalysis.CPU_TIME_METRIC_INDEX) { + return getFunctionStatistics().getCpuTimesStatistics(); + } + return null; + } + + /** + * The function's statistics + * + * @return The function's statistics + */ + public AggregatedCalledFunctionStatistics getFunctionStatistics() { + return fStatistics; + } + + @Override + public String toString() { + return "Aggregate Function: " + getObject() + ", Duration: " + getDuration() + ", Self Time: " + fSelfTime + " on " + getNbCalls() + " calls"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ + } + +}