tmf: Bug 473280: Internalize TMF Statistics UI API
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / internal / tmf / ui / viewers / statistics / StatisticsUpdateJob.java
1 /*******************************************************************************
2 * Copyright (c) 2015 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made 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 * Contributors:
10 * Mathieu Denis - Initial API and implementation
11 * Alexis Cabana-Loriaux - Extract the class in a compilation unit
12 *******************************************************************************/
13
14 package org.eclipse.tracecompass.internal.tmf.ui.viewers.statistics;
15
16 import java.util.Map;
17
18 import org.eclipse.core.runtime.IProgressMonitor;
19 import org.eclipse.core.runtime.IStatus;
20 import org.eclipse.core.runtime.Status;
21 import org.eclipse.core.runtime.jobs.Job;
22 import org.eclipse.tracecompass.internal.tmf.ui.viewers.piecharts.model.TmfPieChartStatisticsModel;
23 import org.eclipse.tracecompass.internal.tmf.ui.viewers.statistics.model.TmfStatisticsTree;
24 import org.eclipse.tracecompass.internal.tmf.ui.viewers.statistics.model.TmfStatisticsTreeManager;
25 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
26 import org.eclipse.tracecompass.tmf.core.statistics.ITmfStatistics;
27 import org.eclipse.tracecompass.tmf.core.statistics.TmfStatisticsEventTypesModule;
28 import org.eclipse.tracecompass.tmf.core.statistics.TmfStatisticsModule;
29 import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
30 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
31 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
32
33 /**
34 * Class used to update the Statistics view. Normally, it should only be used by
35 * this class
36 *
37 * @author Mathieu Denis
38 */
39 class StatisticsUpdateJob extends Job {
40
41 private final ITmfTrace fJobTrace;
42 private final boolean fIsGlobal;
43 private final TmfStatisticsModule fStatsMod;
44 private final TmfStatisticsViewer fViewer;
45
46 /**
47 * The delay (in ms) between each update in live-reading mode
48 */
49 private static final long LIVE_UPDATE_DELAY = 1000;
50
51 /**
52 * Timestamp scale used for all statistics (nanosecond)
53 */
54 private static final byte TIME_SCALE = ITmfTimestamp.NANOSECOND_SCALE;
55 private TmfTimeRange fTimerange;
56
57 /**
58 * @param name
59 * The name of the working job
60 * @param trace
61 * The trace to query
62 * @param isGlobal
63 * If the query is for the global time-range or a selection
64 * time-range
65 * @param timerange
66 * The timerange of
67 * @param statsMod
68 * The statistics module of the trace
69 * @param viewer
70 * The viewer to update
71 */
72 public StatisticsUpdateJob(String name, ITmfTrace trace, boolean isGlobal, TmfTimeRange timerange, TmfStatisticsModule statsMod, TmfStatisticsViewer viewer) {
73 super(name);
74 fJobTrace = trace;
75 fIsGlobal = isGlobal;
76 fTimerange = timerange;
77 fStatsMod = statsMod;
78 fViewer = viewer;
79 }
80
81 @Override
82 protected IStatus run(IProgressMonitor monitor) {
83
84 /* Wait until the analysis is ready to be queried */
85 fStatsMod.waitForInitialization();
86 ITmfStatistics stats = fStatsMod.getStatistics();
87 if (stats == null) {
88 /* It should have worked, but didn't */
89 throw new IllegalStateException();
90 }
91
92 /*
93 * TODO Eventually this could be exposed through the
94 * TmfStateSystemAnalysisModule directly.
95 */
96 ITmfStateSystem ss = fStatsMod.getStateSystem(TmfStatisticsEventTypesModule.ID);
97 if (ss == null) {
98 /*
99 * It should be instantiated after the
100 * statsMod.waitForInitialization() above.
101 */
102 throw new IllegalStateException();
103 }
104
105 /*
106 * Periodically update the statistics while they are being built (or, if
107 * the back-end is already completely built, it will skip over the
108 * while() immediately.
109 */
110 long start = 0;
111 long end = 0;
112 boolean finished = false;
113 do {
114 /* This model update is done every second */
115 if (monitor.isCanceled()) {
116 fViewer.removeFromJobs(fIsGlobal, fJobTrace);
117 return Status.CANCEL_STATUS;
118 }
119 finished = ss.waitUntilBuilt(LIVE_UPDATE_DELAY);
120 TmfTimeRange localtimeRange = fTimerange;
121 /*
122 * The generic statistics are stored in nanoseconds, so we must make
123 * sure the time range is scaled correctly.
124 */
125 start = localtimeRange.getStartTime().normalize(0, TIME_SCALE).getValue();
126 end = localtimeRange.getEndTime().normalize(0, TIME_SCALE).getValue();
127
128 Map<String, Long> map = stats.getEventTypesInRange(start, end);
129 updateStats(map);
130 } while (!finished);
131
132
133 /* Query one last time for the final values */
134 Map<String, Long> map = stats.getEventTypesInRange(start, end);
135 updateStats(map);
136 fViewer.refreshPieCharts(fIsGlobal, !fIsGlobal);
137 /*
138 * Remove job from map so that new range selection updates can be
139 * processed.
140 */
141 fViewer.removeFromJobs(fIsGlobal, fJobTrace);
142 return Status.OK_STATUS;
143 }
144
145 /*
146 * Update the tree for a given trace
147 */
148 private void updateStats(Map<String, Long> eventsPerType) {
149
150 final TmfStatisticsTree statsData = TmfStatisticsTreeManager.getStatTree(fViewer.getTreeID());
151 if (statsData == null) {
152 /* The stat tree has been disposed, abort mission. */
153 return;
154 }
155
156 Map<String, Long> map = eventsPerType;
157 String name = fJobTrace.getName();
158
159 /**
160 * <pre>
161 * "Global", "partial", "total", etc., it's all very confusing...
162 *
163 * The base view shows the total count for the trace and for
164 * each even types, organized in columns like this:
165 *
166 * | Global | Time range |
167 * trace name | A | B |
168 * Event Type | | |
169 * <event 1> | C | D |
170 * <event 2> | ... | ... |
171 * ... | | |
172 *
173 * Here, we called the cells like this:
174 * A : GlobalTotal
175 * B : TimeRangeTotal
176 * C : GlobalTypeCount(s)
177 * D : TimeRangeTypeCount(s)
178 * </pre>
179 */
180
181 /* Fill in an the event counts (either cells C or D) */
182 for (Map.Entry<String, Long> entry : map.entrySet()) {
183 statsData.setTypeCount(name, entry.getKey(), fIsGlobal, entry.getValue());
184 }
185
186 /*
187 * Calculate the totals (cell A or B, depending if isGlobal). We will
188 * use the results of the previous request instead of sending another
189 * one.
190 */
191 long globalTotal = 0;
192 for (long val : map.values()) {
193 globalTotal += val;
194 }
195 /* Update both the tree model and the piechart model */
196 statsData.setTotal(name, fIsGlobal, globalTotal);
197 TmfPieChartStatisticsModel model = fViewer.getPieChartModel();
198 if (model != null) {
199 model.setPieChartTypeCount(fIsGlobal, fJobTrace, eventsPerType);
200 }
201 /* notify that the viewer needs to be refreshed */
202 fViewer.modelComplete(fIsGlobal);
203 }
204 }
This page took 0.054344 seconds and 6 git commands to generate.