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