1 /*******************************************************************************
2 * Copyright (c) 2016 Ericsson
4 * All rights reserved. This program and the accompanying materials are made
5 * available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
9 package org
.eclipse
.tracecompass
.analysis
.timing
.core
.segmentstore
.statistics
;
11 import java
.util
.Collections
;
12 import java
.util
.HashMap
;
13 import java
.util
.Iterator
;
15 import java
.util
.Map
.Entry
;
16 import java
.util
.function
.Function
;
18 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
19 import org
.eclipse
.jdt
.annotation
.NonNull
;
20 import org
.eclipse
.jdt
.annotation
.Nullable
;
21 import org
.eclipse
.tracecompass
.analysis
.timing
.core
.segmentstore
.ISegmentStoreProvider
;
22 import org
.eclipse
.tracecompass
.analysis
.timing
.core
.statistics
.IStatistics
;
23 import org
.eclipse
.tracecompass
.analysis
.timing
.core
.statistics
.Statistics
;
24 import org
.eclipse
.tracecompass
.segmentstore
.core
.ISegment
;
25 import org
.eclipse
.tracecompass
.segmentstore
.core
.ISegmentStore
;
26 import org
.eclipse
.tracecompass
.tmf
.core
.analysis
.IAnalysisModule
;
27 import org
.eclipse
.tracecompass
.tmf
.core
.analysis
.TmfAbstractAnalysisModule
;
28 import org
.eclipse
.tracecompass
.tmf
.core
.exceptions
.TmfAnalysisException
;
29 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimeRange
;
30 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
32 import com
.google
.common
.collect
.ImmutableList
;
35 * Abstract analysis to build statistics data for a segment store
37 * @author Jean-Christian Kouame
39 public abstract class AbstractSegmentStatisticsAnalysis
extends TmfAbstractAnalysisModule
{
41 private static Function
<ISegment
, Long
> FCT_LENGTH
= s
-> s
.getLength();
43 private @Nullable ISegmentStoreProvider fSegmentStoreProviderModule
;
45 private @Nullable IStatistics
<ISegment
> fTotalStats
;
47 private Map
<String
, IStatistics
<ISegment
>> fPerSegmentTypeStats
= new HashMap
<>();
50 protected Iterable
<IAnalysisModule
> getDependentAnalyses() {
51 ITmfTrace trace
= getTrace();
53 ISegmentStoreProvider provider
= getSegmentProviderAnalysis(trace
);
54 fSegmentStoreProviderModule
= provider
;
55 if (provider
instanceof IAnalysisModule
) {
56 return ImmutableList
.of((IAnalysisModule
) provider
);
59 return super.getDependentAnalyses();
63 protected boolean executeAnalysis(IProgressMonitor monitor
) throws TmfAnalysisException
{
64 if (monitor
.isCanceled()) {
68 IStatistics
<ISegment
> totalStats
= getTotalStats(TmfTimeRange
.ETERNITY
.getStartTime().toNanos(), TmfTimeRange
.ETERNITY
.getEndTime().toNanos(), monitor
);
69 if (totalStats
== null) {
73 Map
<String
, IStatistics
<ISegment
>> perTypeStats
= getPerTypeStats(TmfTimeRange
.ETERNITY
.getStartTime().toNanos(), TmfTimeRange
.ETERNITY
.getEndTime().toNanos(), monitor
);
74 fTotalStats
= totalStats
;
75 fPerSegmentTypeStats
= perTypeStats
;
80 private @Nullable IStatistics
<ISegment
> getTotalStats(long start
, long end
, IProgressMonitor monitor
) {
81 Iterable
<@NonNull ISegment
> store
= getSegmentStore(start
, end
);
85 if (monitor
.isCanceled()) {
88 return calculateTotalManual(store
, monitor
);
92 * Get the total statistics for a specific range. If the range start is
93 * TmfTimeRange.ETERNITY.getStartTime().toNanos() and the range end is
94 * TmfTimeRange.ETERNITY.getEndTime().toNanos(), it will return the
95 * statistics for the whole trace.
98 * The start time of the range
100 * The end time of the range
102 * The progress monitor
103 * @return The total statistics, or null if segment store is not valid or if
104 * the request is canceled
106 * @deprecated use {@link #getStatsForRange(long, long, IProgressMonitor)} instead
109 public @Nullable SegmentStoreStatistics
getTotalStatsForRange(long start
, long end
, IProgressMonitor monitor
) {
110 IStatistics
<@NonNull ISegment
> stats
= getStatsForRange(start
, end
, monitor
);
111 return (stats
== null) ?
null : new SegmentStoreStatistics(stats
);
115 * Get the total statistics for a specific range. If the range start is
116 * TmfTimeRange.ETERNITY.getStartTime().toNanos() and the range end is
117 * TmfTimeRange.ETERNITY.getEndTime().toNanos(), it will return the
118 * statistics for the whole trace.
121 * The start time of the range
123 * The end time of the range
125 * The progress monitor
126 * @return The total statistics, or null if segment store is not valid or if
127 * the request is canceled
130 public @Nullable IStatistics
<ISegment
> getStatsForRange(long start
, long end
, IProgressMonitor monitor
) {
131 ITmfTrace trace
= getTrace();
132 if (trace
!= null && (start
== TmfTimeRange
.ETERNITY
.getStartTime().toNanos() && end
== TmfTimeRange
.ETERNITY
.getEndTime().toNanos())) {
134 return getStatsTotal();
136 return getTotalStats(start
, end
, monitor
);
139 private Map
<@NonNull String
, org
.eclipse
.tracecompass
.analysis
.timing
.core
.statistics
.IStatistics
<ISegment
>> getPerTypeStats(long start
, long end
, IProgressMonitor monitor
) {
140 Iterable
<@NonNull ISegment
> store
= getSegmentStore(start
, end
);
141 if (monitor
.isCanceled() || store
== null) {
142 return Collections
.EMPTY_MAP
;
144 return calculateTotalPerType(store
, monitor
);
148 * Get the per segment type statistics for a specific range. If the range
149 * start is TmfTimeRange.ETERNITY.getStartTime().toNanos() and the range end
150 * is TmfTimeRange.ETERNITY.getEndTime().toNanos(), it will return the
151 * statistics for the whole trace.
154 * The start time of the range
156 * The end time of the range
158 * The progress monitor
159 * @return The per segment type statistics, or null if segment store is not
160 * valid or if the request is canceled
162 * @deprecated use {@link #getStatsPerTypeForRange(long, long, IProgressMonitor)} instead
165 public @Nullable Map
<String
, SegmentStoreStatistics
> getPerSegmentTypeStatsForRange(long start
, long end
, IProgressMonitor monitor
) {
166 Map
<String
, IStatistics
<ISegment
>> stats
= getStatsPerTypeForRange(start
, end
, monitor
);
167 Map
<String
, SegmentStoreStatistics
> map
= new HashMap
<>();
168 for (Entry
<String
, IStatistics
<ISegment
>> entry
: stats
.entrySet()) {
169 map
.put(entry
.getKey(), new SegmentStoreStatistics(entry
.getValue()));
175 * Get the per segment type statistics for a specific range. If the range
176 * start is TmfTimeRange.ETERNITY.getStartTime().toNanos() and the range end
177 * is TmfTimeRange.ETERNITY.getEndTime().toNanos(), it will return the
178 * statistics for the whole trace.
181 * The start time of the range
183 * The end time of the range
185 * The progress monitor
186 * @return The per segment type statistics, or null if segment store is not
187 * valid or if the request is canceled
190 public Map
<@NonNull String
, org
.eclipse
.tracecompass
.analysis
.timing
.core
.statistics
.IStatistics
<ISegment
>> getStatsPerTypeForRange(long start
, long end
, IProgressMonitor monitor
) {
191 ITmfTrace trace
= getTrace();
192 if (trace
!= null && (start
== TmfTimeRange
.ETERNITY
.getStartTime().toNanos() && end
== TmfTimeRange
.ETERNITY
.getEndTime().toNanos())) {
194 return getStatsPerType();
196 return getPerTypeStats(start
, end
, monitor
);
200 * Get the segment store from which we want the statistics
202 * @return The segment store
204 private @Nullable Iterable
<@NonNull ISegment
> getSegmentStore(long start
, long end
) {
205 ISegmentStoreProvider segmentStoreProviderModule
= fSegmentStoreProviderModule
;
206 if (segmentStoreProviderModule
== null) {
209 if (segmentStoreProviderModule
instanceof IAnalysisModule
) {
210 ((IAnalysisModule
) segmentStoreProviderModule
).waitForCompletion();
213 ISegmentStore
<@NonNull ISegment
> segmentStore
= segmentStoreProviderModule
.getSegmentStore();
214 return segmentStore
!= null ? start
!= TmfTimeRange
.ETERNITY
.getStartTime().toNanos() || end
!= TmfTimeRange
.ETERNITY
.getEndTime().toNanos() ?
(Iterable
<@NonNull ISegment
>) segmentStore
.getIntersectingElements(start
, end
) : segmentStore
215 : Collections
.EMPTY_LIST
;
218 private static @Nullable IStatistics
<ISegment
> calculateTotalManual(Iterable
<@NonNull ISegment
> segments
, IProgressMonitor monitor
) {
219 IStatistics
<ISegment
> total
= new Statistics
<>(FCT_LENGTH
);
220 Iterator
<@NonNull ISegment
> iter
= segments
.iterator();
221 while (iter
.hasNext()) {
222 if (monitor
.isCanceled()) {
225 ISegment segment
= iter
.next();
226 total
.update(segment
);
231 private Map
<@NonNull String
, org
.eclipse
.tracecompass
.analysis
.timing
.core
.statistics
.IStatistics
<ISegment
>> calculateTotalPerType(Iterable
<ISegment
> segments
, IProgressMonitor monitor
) {
232 Map
<String
, IStatistics
<ISegment
>> perSegmentTypeStats
= new HashMap
<>();
234 Iterator
<ISegment
> iter
= segments
.iterator();
235 while (iter
.hasNext()) {
236 if (monitor
.isCanceled()) {
237 return Collections
.EMPTY_MAP
;
239 ISegment segment
= iter
.next();
240 String segmentType
= getSegmentType(segment
);
241 if (segmentType
!= null) {
242 IStatistics
<ISegment
> values
= perSegmentTypeStats
.get(segmentType
);
243 if (values
== null) {
244 values
= new Statistics
<>(FCT_LENGTH
);
246 values
.update(segment
);
247 perSegmentTypeStats
.put(segmentType
, values
);
250 return perSegmentTypeStats
;
254 * Get the type of a segment. Statistics per type will use this type as a
258 * the segment for which to get the type
259 * @return The type of the segment
261 protected abstract @Nullable String
getSegmentType(ISegment segment
);
264 * Find the segment store provider used for this analysis
269 * @return The segment store provider
271 protected abstract @Nullable ISegmentStoreProvider
getSegmentProviderAnalysis(ITmfTrace trace
);
274 protected void canceling() {
278 * The total statistics
280 * @return the total statistics
281 * @deprecated use {@link #getStatsTotal()} instead
284 public @Nullable SegmentStoreStatistics
getTotalStats() {
285 IStatistics
<@NonNull ISegment
> totalStats
= fTotalStats
;
286 return totalStats
== null ?
null : new SegmentStoreStatistics(totalStats
);
290 * Get the statistics for the full segment store
292 * @return The complete statistics
295 public @Nullable IStatistics
<ISegment
> getStatsTotal() {
300 * The per syscall statistics
302 * @return the per syscall statistics
303 * @deprecated use {@link #getStatsPerType()} instead
306 public @Nullable Map
<String
, SegmentStoreStatistics
> getPerSegmentTypeStats() {
307 Map
<String
, SegmentStoreStatistics
> map
= new HashMap
<>();
308 for (Entry
<String
, IStatistics
<ISegment
>> entry
: fPerSegmentTypeStats
.entrySet()) {
309 map
.put(entry
.getKey(), new SegmentStoreStatistics(entry
.getValue()));
315 * Get the statistics for each type of segment in this segment store
317 * @return the map of statistics per type
320 public Map
<String
, IStatistics
<ISegment
>> getStatsPerType() {
321 return fPerSegmentTypeStats
;