From abda4cb06e8bf72d0cd717e43420afb527f953d7 Mon Sep 17 00:00:00 2001 From: Jean-Christian Kouame Date: Fri, 4 Mar 2016 16:23:34 -0500 Subject: [PATCH] analysis : Abstract the latency statistics analysis Change-Id: I452cf2f165ea74522dbd3cb98547ad2784324a73 Signed-off-by: Jean-Christian Kouame Reviewed-on: https://git.eclipse.org/r/67841 Reviewed-by: Genevieve Bastien Tested-by: Genevieve Bastien Reviewed-by: Hudson CI Reviewed-by: Matthew Khouzam --- ...emCallLatencyStatisticsAnalysisModule.java | 124 ++------------ .../SystemCallLatencyStatisticsViewer.java | 2 +- .../AbstractSegmentStatisticsAnalysis.java | 161 ++++++++++++++++++ 3 files changed, 174 insertions(+), 113 deletions(-) create mode 100644 analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/statistics/AbstractSegmentStatisticsAnalysis.java diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/latency/statistics/SystemCallLatencyStatisticsAnalysisModule.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/latency/statistics/SystemCallLatencyStatisticsAnalysisModule.java index f7e97cb5ee..7408a5865a 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/latency/statistics/SystemCallLatencyStatisticsAnalysisModule.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.core/src/org/eclipse/tracecompass/internal/analysis/os/linux/core/latency/statistics/SystemCallLatencyStatisticsAnalysisModule.java @@ -11,138 +11,38 @@ *******************************************************************************/ package org.eclipse.tracecompass.internal.analysis.os.linux.core.latency.statistics; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.tracecompass.analysis.os.linux.core.latency.SystemCall; import org.eclipse.tracecompass.analysis.os.linux.core.latency.SystemCallLatencyAnalysis; -import org.eclipse.tracecompass.internal.analysis.timing.core.segmentstore.statistics.SegmentStoreStatistics; +import org.eclipse.tracecompass.analysis.timing.core.segmentstore.ISegmentStoreProvider; +import org.eclipse.tracecompass.internal.analysis.timing.core.segmentstore.statistics.AbstractSegmentStatisticsAnalysis; import org.eclipse.tracecompass.segmentstore.core.ISegment; -import org.eclipse.tracecompass.segmentstore.core.ISegmentStore; -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.trace.ITmfTrace; import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils; -import com.google.common.collect.ImmutableList; - /** * Analysis module to calculate statistics of a latency analysis * * @author Bernd Hufmann */ -public class SystemCallLatencyStatisticsAnalysisModule extends TmfAbstractAnalysisModule { +public class SystemCallLatencyStatisticsAnalysisModule extends AbstractSegmentStatisticsAnalysis { /** The analysis module ID */ public static final String ID = "org.eclipse.tracecompass.analysis.os.linux.core.latency.statistics.syscall"; //$NON-NLS-1$ - private @Nullable SystemCallLatencyAnalysis fLatencyModule; - - private @Nullable SegmentStoreStatistics fTotalStats; - - private @Nullable Map fPerSyscallStats; - @Override - protected Iterable getDependentAnalyses() { - ITmfTrace trace = getTrace(); - if (trace != null) { - SystemCallLatencyAnalysis module = TmfTraceUtils.getAnalysisModuleOfClass(trace, SystemCallLatencyAnalysis.class, SystemCallLatencyAnalysis.ID); - if (module != null) { - fLatencyModule = module; - return ImmutableList.of((IAnalysisModule) module); - } - } - return super.getDependentAnalyses(); - } - - @Override - protected boolean executeAnalysis(IProgressMonitor monitor) throws TmfAnalysisException { - SystemCallLatencyAnalysis latency = fLatencyModule; - ITmfTrace trace = getTrace(); - if ((latency == null) || (trace == null)) { - return false; - } - latency.waitForCompletion(); - - ISegmentStore segStore = latency.getSegmentStore(); - - if (segStore != null) { - - boolean result = calculateTotalManual(segStore, monitor); - - if (!result) { - return false; - } - - result = calculateTotalPerSyscall(segStore, monitor); - if (!result) { - return false; - } + protected @Nullable String getSegmentType(@NonNull ISegment segment) { + if (segment instanceof SystemCall) { + SystemCall syscall = (SystemCall) segment; + return syscall.getName(); } - return true; - } - - private boolean calculateTotalManual(ISegmentStore store, IProgressMonitor monitor) { - SegmentStoreStatistics total = new SegmentStoreStatistics(); - Iterator iter = store.iterator(); - while (iter.hasNext()) { - if (monitor.isCanceled()) { - return false; - } - ISegment segment = iter.next(); - total.update(segment); - } - fTotalStats = total; - return true; - } - - private boolean calculateTotalPerSyscall(ISegmentStore store, IProgressMonitor monitor) { - Map perSyscallStats = new HashMap<>(); - - Iterator iter = store.iterator(); - while (iter.hasNext()) { - if (monitor.isCanceled()) { - return false; - } - ISegment segment = iter.next(); - if (segment instanceof SystemCall) { - SystemCall syscall = (SystemCall) segment; - SegmentStoreStatistics values = perSyscallStats.get(syscall.getName()); - if (values == null) { - values = new SegmentStoreStatistics(); - } - values.update(segment); - perSyscallStats.put(syscall.getName(), values); - } - } - fPerSyscallStats = perSyscallStats; - return true; + return null; } @Override - protected void canceling() { - } - - /** - * The total statistics - * - * @return the total statistics - */ - public @Nullable SegmentStoreStatistics getTotalStats() { - return fTotalStats; - } - - /** - * The per syscall statistics - * - * @return the per syscall statistics - */ - public @Nullable Map getPerSyscallStats() { - return fPerSyscallStats; + protected @Nullable ISegmentStoreProvider getSegmentProviderAnalysis(@NonNull ITmfTrace trace) { + return TmfTraceUtils.getAnalysisModuleOfClass(trace, SystemCallLatencyAnalysis.class, SystemCallLatencyAnalysis.ID); } - } +} diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/statistics/SystemCallLatencyStatisticsViewer.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/statistics/SystemCallLatencyStatisticsViewer.java index 45e28fcf5f..013b5c5fbd 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/statistics/SystemCallLatencyStatisticsViewer.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/latency/statistics/SystemCallLatencyStatisticsViewer.java @@ -84,7 +84,7 @@ public class SystemCallLatencyStatisticsViewer extends AbstractSegmentStoreStati HiddenTreeViewerEntry syscalls = new HiddenTreeViewerEntry(SYSCALL_LEVEL); child.addChild(syscalls); - Map perSyscallStats = module.getPerSyscallStats(); + Map perSyscallStats = module.getPerSegmentTypeStats(); if (perSyscallStats != null) { for (Entry statsEntry : perSyscallStats.entrySet()) { syscalls.addChild(new SegmentStoreStatisticsEntry(statsEntry.getKey(), statsEntry.getValue())); diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/statistics/AbstractSegmentStatisticsAnalysis.java b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/statistics/AbstractSegmentStatisticsAnalysis.java new file mode 100644 index 0000000000..7a79a340f9 --- /dev/null +++ b/analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/segmentstore/statistics/AbstractSegmentStatisticsAnalysis.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright (c) 2016 Ericsson + * + * All rights reserved. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ +package org.eclipse.tracecompass.internal.analysis.timing.core.segmentstore.statistics; + +import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.analysis.timing.core.segmentstore.ISegmentStoreProvider; +import org.eclipse.tracecompass.segmentstore.core.ISegment; +import org.eclipse.tracecompass.segmentstore.core.ISegmentStore; +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.trace.ITmfTrace; + +import com.google.common.collect.ImmutableList; + +/** + * Abstract analysis to build statistics data for a segment store + * + * @author Jean-Christian Kouame + */ +public abstract class AbstractSegmentStatisticsAnalysis extends TmfAbstractAnalysisModule { + + private @Nullable IAnalysisModule fSegmentStoreProviderModule; + + private @Nullable SegmentStoreStatistics fTotalStats; + + private @Nullable Map fPerSegmentTypeStats; + + @Override + protected Iterable getDependentAnalyses() { + ITmfTrace trace = getTrace(); + if (trace != null) { + ISegmentStoreProvider provider = getSegmentProviderAnalysis(trace); + if (provider instanceof IAnalysisModule) { + fSegmentStoreProviderModule = (IAnalysisModule) provider; + return ImmutableList.of((IAnalysisModule) provider); + } + } + return super.getDependentAnalyses(); + } + + @Override + protected boolean executeAnalysis(IProgressMonitor monitor) throws TmfAnalysisException { + IAnalysisModule segmentStoreProviderModule = fSegmentStoreProviderModule; + ITmfTrace trace = getTrace(); + if (!(segmentStoreProviderModule instanceof ISegmentStoreProvider) || (trace == null)) { + return false; + } + segmentStoreProviderModule.waitForCompletion(); + + ISegmentStore segStore = ((ISegmentStoreProvider) segmentStoreProviderModule).getSegmentStore(); + + if (segStore != null) { + + boolean result = calculateTotalManual(segStore, monitor); + + if (!result) { + return false; + } + + result = calculateTotalPerType(segStore, monitor); + if (!result) { + return false; + } + } + return true; + } + + private boolean calculateTotalManual(ISegmentStore store, IProgressMonitor monitor) { + SegmentStoreStatistics total = new SegmentStoreStatistics(); + Iterator iter = store.iterator(); + while (iter.hasNext()) { + if (monitor.isCanceled()) { + return false; + } + ISegment segment = iter.next(); + total.update(checkNotNull(segment)); + } + fTotalStats = total; + return true; + } + + private boolean calculateTotalPerType(ISegmentStore store, IProgressMonitor monitor) { + Map perSegmentTypeStats = new HashMap<>(); + + Iterator iter = store.iterator(); + while (iter.hasNext()) { + if (monitor.isCanceled()) { + return false; + } + ISegment segment = iter.next(); + String segmentType = getSegmentType(segment); + if (segmentType != null) { + SegmentStoreStatistics values = perSegmentTypeStats.get(segmentType); + if (values == null) { + values = new SegmentStoreStatistics(); + } + values.update(segment); + perSegmentTypeStats.put(segmentType, values); + } + } + fPerSegmentTypeStats = perSegmentTypeStats; + return true; + } + + /** + * Get the type of a segment. Statistics per type will use this type as a + * key + * + * @param segment + * the segment for which to get the type + * @return The type of the segment + */ + protected abstract @Nullable String getSegmentType(ISegment segment); + + /** + * Find the segment store provider used for this analysis + * + * @param trace + * The active trace + * + * @return The segment store provider + */ + protected abstract @Nullable ISegmentStoreProvider getSegmentProviderAnalysis(ITmfTrace trace); + + @Override + protected void canceling() { + } + + /** + * The total statistics + * + * @return the total statistics + */ + public @Nullable SegmentStoreStatistics getTotalStats() { + return fTotalStats; + } + + /** + * The per syscall statistics + * + * @return the per syscall statistics + */ + public @Nullable Map getPerSegmentTypeStats() { + return fPerSegmentTypeStats; + } + +} -- 2.34.1