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
.Collection
;
12 import java
.util
.Collections
;
13 import java
.util
.HashMap
;
14 import java
.util
.Iterator
;
17 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
18 import org
.eclipse
.jdt
.annotation
.NonNull
;
19 import org
.eclipse
.jdt
.annotation
.Nullable
;
20 import org
.eclipse
.tracecompass
.analysis
.timing
.core
.segmentstore
.ISegmentStoreProvider
;
21 import org
.eclipse
.tracecompass
.segmentstore
.core
.ISegment
;
22 import org
.eclipse
.tracecompass
.segmentstore
.core
.ISegmentStore
;
23 import org
.eclipse
.tracecompass
.tmf
.core
.analysis
.IAnalysisModule
;
24 import org
.eclipse
.tracecompass
.tmf
.core
.analysis
.TmfAbstractAnalysisModule
;
25 import org
.eclipse
.tracecompass
.tmf
.core
.exceptions
.TmfAnalysisException
;
26 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimeRange
;
27 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
29 import com
.google
.common
.collect
.ImmutableList
;
32 * Abstract analysis to build statistics data for a segment store
34 * @author Jean-Christian Kouame
36 public abstract class AbstractSegmentStatisticsAnalysis
extends TmfAbstractAnalysisModule
{
38 private @Nullable IAnalysisModule fSegmentStoreProviderModule
;
40 private @Nullable SegmentStoreStatistics fTotalStats
;
42 private Map
<String
, SegmentStoreStatistics
> fPerSegmentTypeStats
= new HashMap
<>();
45 protected Iterable
<IAnalysisModule
> getDependentAnalyses() {
46 ITmfTrace trace
= getTrace();
48 ISegmentStoreProvider provider
= getSegmentProviderAnalysis(trace
);
49 if (provider
instanceof IAnalysisModule
) {
50 fSegmentStoreProviderModule
= (IAnalysisModule
) provider
;
51 return ImmutableList
.of((IAnalysisModule
) provider
);
54 return super.getDependentAnalyses();
58 protected boolean executeAnalysis(IProgressMonitor monitor
) throws TmfAnalysisException
{
59 if (monitor
.isCanceled()) {
62 @Nullable SegmentStoreStatistics totalStats
= getTotalStats(TmfTimeRange
.ETERNITY
.getStartTime().toNanos(), TmfTimeRange
.ETERNITY
.getEndTime().toNanos(), monitor
);
63 if (totalStats
== null) {
67 @Nullable Map
<@NonNull String
, @NonNull SegmentStoreStatistics
> perTypeStats
= getPerTypeStats(TmfTimeRange
.ETERNITY
.getStartTime().toNanos(), TmfTimeRange
.ETERNITY
.getEndTime().toNanos(), monitor
);
68 if (perTypeStats
== null) {
71 fTotalStats
= totalStats
;
72 fPerSegmentTypeStats
= perTypeStats
;
76 private @Nullable SegmentStoreStatistics
getTotalStats(long start
, long end
, IProgressMonitor monitor
) {
77 Collection
<@NonNull ISegment
> store
= getSegmentStore(start
, end
);
81 if (monitor
.isCanceled()) {
84 return calculateTotalManual(store
, monitor
);
88 * Get the total statistics for a specific range. If the range start is
89 * TmfTimeRange.ETERNITY.getStartTime().toNanos() and the range end is
90 * TmfTimeRange.ETERNITY.getEndTime().toNanos(), it will return the
91 * statistics for the whole trace.
94 * The start time of the range
96 * The end time of the range
98 * The progress monitor
99 * @return The total statistics, or null if segment store is not valid or if
100 * the request is canceled
103 public @Nullable SegmentStoreStatistics
getTotalStatsForRange(long start
, long end
, IProgressMonitor monitor
) {
104 @Nullable ITmfTrace trace
= getTrace();
105 if (trace
!= null && (start
== TmfTimeRange
.ETERNITY
.getStartTime().toNanos() && end
== TmfTimeRange
.ETERNITY
.getEndTime().toNanos())) {
107 return getTotalStats();
109 return getTotalStats(start
, end
, monitor
);
112 private @Nullable Map
<@NonNull String
, @NonNull SegmentStoreStatistics
> getPerTypeStats(long start
, long end
, IProgressMonitor monitor
) {
113 Collection
<@NonNull ISegment
> store
= getSegmentStore(start
, end
);
114 if (monitor
.isCanceled()) {
115 return Collections
.EMPTY_MAP
;
117 return calculateTotalPerType(store
, monitor
);
121 * Get the per segment type statistics for a specific range. If the range
122 * start is TmfTimeRange.ETERNITY.getStartTime().toNanos() and the range end
123 * is TmfTimeRange.ETERNITY.getEndTime().toNanos(), it will return the
124 * statistics for the whole trace.
127 * The start time of the range
129 * The end time of the range
131 * The progress monitor
132 * @return The per segment type statistics, or null if segment store is not
133 * valid or if the request is canceled
136 public @Nullable Map
<@NonNull String
, @NonNull SegmentStoreStatistics
> getPerSegmentTypeStatsForRange(long start
, long end
, IProgressMonitor monitor
) {
137 @Nullable ITmfTrace trace
= getTrace();
138 if (trace
!= null && (start
== TmfTimeRange
.ETERNITY
.getStartTime().toNanos() && end
== TmfTimeRange
.ETERNITY
.getEndTime().toNanos())) {
140 return getPerSegmentTypeStats();
142 return getPerTypeStats(start
, end
, monitor
);
146 * Get the segment store from which we want the statistics
148 * @return The segment store
150 private @Nullable Collection
<@NonNull ISegment
> getSegmentStore(long start
, long end
) {
151 IAnalysisModule segmentStoreProviderModule
= fSegmentStoreProviderModule
;
152 if (!(segmentStoreProviderModule
instanceof ISegmentStoreProvider
)) {
155 segmentStoreProviderModule
.waitForCompletion();
157 @Nullable ISegmentStore
<@NonNull ISegment
> segmentStore
= ((ISegmentStoreProvider
) segmentStoreProviderModule
).getSegmentStore();
158 return segmentStore
!= null ?
159 start
!= TmfTimeRange
.ETERNITY
.getStartTime().toNanos() || end
!= TmfTimeRange
.ETERNITY
.getEndTime().toNanos() ?
(Collection
<@NonNull ISegment
>) segmentStore
.getIntersectingElements(start
, end
) : segmentStore
160 : Collections
.EMPTY_LIST
;
163 private static @Nullable SegmentStoreStatistics
calculateTotalManual(Collection
<@NonNull ISegment
> segments
, IProgressMonitor monitor
) {
164 SegmentStoreStatistics total
= new SegmentStoreStatistics();
165 Iterator
<@NonNull ISegment
> iter
= segments
.iterator();
166 while (iter
.hasNext()) {
167 if (monitor
.isCanceled()) {
170 @NonNull ISegment segment
= iter
.next();
171 total
.update(segment
);
176 private Map
<@NonNull String
, @NonNull SegmentStoreStatistics
> calculateTotalPerType(Collection
<ISegment
> segments
, IProgressMonitor monitor
) {
177 Map
<String
, SegmentStoreStatistics
> perSegmentTypeStats
= new HashMap
<>();
179 Iterator
<ISegment
> iter
= segments
.iterator();
180 while (iter
.hasNext()) {
181 if (monitor
.isCanceled()) {
182 return Collections
.EMPTY_MAP
;
184 ISegment segment
= iter
.next();
185 String segmentType
= getSegmentType(segment
);
186 if (segmentType
!= null) {
187 SegmentStoreStatistics values
= perSegmentTypeStats
.get(segmentType
);
188 if (values
== null) {
189 values
= new SegmentStoreStatistics();
191 values
.update(segment
);
192 perSegmentTypeStats
.put(segmentType
, values
);
195 return perSegmentTypeStats
;
199 * Get the type of a segment. Statistics per type will use this type as a
203 * the segment for which to get the type
204 * @return The type of the segment
206 protected abstract @Nullable String
getSegmentType(ISegment segment
);
209 * Find the segment store provider used for this analysis
214 * @return The segment store provider
216 protected abstract @Nullable ISegmentStoreProvider
getSegmentProviderAnalysis(ITmfTrace trace
);
219 protected void canceling() {
223 * The total statistics
225 * @return the total statistics
227 public @Nullable SegmentStoreStatistics
getTotalStats() {
232 * The per syscall statistics
234 * @return the per syscall statistics
236 public @Nullable Map
<String
, SegmentStoreStatistics
> getPerSegmentTypeStats() {
237 return fPerSegmentTypeStats
;