Fix for supplementary comments on TmftimestampFormat implementation
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / statistics / TmfStatistics.java
CommitLineData
200789b3
AM
1/*******************************************************************************
2 * Copyright (c) 2012 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 * Alexandre Montplaisir - Initial API and implementation
11 ******************************************************************************/
12
13package org.eclipse.linuxtools.tmf.core.statistics;
14
15import java.io.File;
16import java.util.HashMap;
17import java.util.List;
18import java.util.Map;
19
20import org.eclipse.core.resources.IResource;
21import org.eclipse.core.runtime.CoreException;
22import org.eclipse.linuxtools.tmf.core.TmfCommonConstants;
23import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
24import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
25import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
26import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
27import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
28import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval;
29import org.eclipse.linuxtools.tmf.core.statesystem.IStateChangeInput;
30import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
31import org.eclipse.linuxtools.tmf.core.statesystem.StateSystemManager;
32import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
33
34/**
35 * Default implementation of an ITmfStatisticsProvider. It uses a state system
36 * underneath to store its information.
37 *
38 * @author Alexandre Montplaisir
39 * @since 2.0
40 */
41
42public class TmfStatistics implements ITmfStatistics {
43
a76f1067
AM
44 /** ID for the statistics state system */
45 public static final String STATE_ID = "org.eclipse.linuxtools.tmf.statistics"; //$NON-NLS-1$
46
200789b3
AM
47 /* Filename the "statistics state history" file will have */
48 private static final String STATS_STATE_FILENAME = "statistics.ht"; //$NON-NLS-1$
49
50 /*
51 * The state system that's used to stored the statistics. It's hidden from
52 * the trace, so that it doesn't conflict with ITmfTrace.getStateSystem()
53 * (which is something else!)
54 */
55 private final ITmfStateSystem stats;
56
36033ff0
AM
57 /**
58 * Empty constructor. The resulting TmfStatistics object will not be usable,
59 * but it might be needed for sub-classes.
60 */
89c06060
AM
61 public TmfStatistics() {
62 stats = null;
63 }
64
200789b3
AM
65 /**
66 * Constructor
67 *
68 * @param trace
69 * The trace for which we build these statistics
70 * @throws TmfTraceException
71 * If something went wrong trying to initialize the statistics
72 */
73 public TmfStatistics(ITmfTrace trace) throws TmfTraceException {
74 /* Set up the path to the history tree file we'll use */
75 IResource resource = trace.getResource();
76 String supplDirectory = null;
77
78 try {
79 // get the directory where the history file will be stored.
80 supplDirectory = resource.getPersistentProperty(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER);
81 } catch (CoreException e) {
82 throw new TmfTraceException(e.toString(), e);
83 }
84
85 final File htFile = new File(supplDirectory + File.separator + STATS_STATE_FILENAME);
86 final IStateChangeInput htInput = new StatsStateProvider(trace);
87
a76f1067 88 this.stats = StateSystemManager.loadStateHistory(htFile, htInput, STATE_ID, false);
200789b3
AM
89 }
90
91 // ------------------------------------------------------------------------
92 // ITmfStatisticsProvider
93 // ------------------------------------------------------------------------
94
95 @Override
96 public long getEventsTotal() {
df310609
AM
97 long start = stats.getStartTime();
98 long end = stats.getCurrentEndTime();
99 int countAtStart = 0, countAtEnd = 0;
100
101 try {
102 final int quark = stats.getQuarkAbsolute(Attributes.TOTAL);
103 countAtStart = stats.querySingleState(start, quark).getStateValue().unboxInt();
104 countAtEnd = stats.querySingleState(end, quark).getStateValue().unboxInt();
105 } catch (AttributeNotFoundException e) {
106 e.printStackTrace();
107 } catch (StateValueTypeException e) {
108 e.printStackTrace();
109 } catch (TimeRangeException e) {
110 /* Should not happen, we're clamped to the start and end times */
111 e.printStackTrace();
200789b3 112 }
df310609
AM
113
114 long total = countAtEnd - countAtStart;
200789b3
AM
115 return total;
116 }
117
118 @Override
119 public Map<String, Long> getEventTypesTotal() {
120 Map<String, Long> map = new HashMap<String, Long>();
121 long endTime = stats.getCurrentEndTime(); //shouldn't need to check it...
122
123 try {
124 /* Get the list of quarks, one for each even type in the database */
125 int quark = stats.getQuarkAbsolute(Attributes.EVENT_TYPES);
126 List<Integer> quarks = stats.getSubAttributes(quark, false);
127
128 /* Since we want the total we can look only at the end */
129 List<ITmfStateInterval> endState = stats.queryFullState(endTime);
130
131 String curEventName;
132 long eventCount;
133 for (int typeQuark : quarks) {
134 curEventName = stats.getAttributeName(typeQuark);
135 eventCount = endState.get(typeQuark).getStateValue().unboxInt();
136 map.put(curEventName, eventCount);
137 }
138
139 } catch (TimeRangeException e) {
140 /* Ignore silently */
141 } catch (AttributeNotFoundException e) {
142 e.printStackTrace();
143 } catch (StateValueTypeException e) {
144 e.printStackTrace();
145 }
146 return map;
147 }
148
149 @Override
150 public long getEventsInRange(ITmfTimestamp start, ITmfTimestamp end) {
df310609
AM
151 int countAtStart = 0, countAtEnd = 0;
152 long startTimestamp = checkStartTime(start.getValue());
153 long endTimestamp = checkEndTime(end.getValue());
154
155 try {
156 final int quark = stats.getQuarkAbsolute(Attributes.TOTAL);
157 countAtStart = stats.querySingleState(startTimestamp, quark).getStateValue().unboxInt();
158 countAtEnd = stats.querySingleState(endTimestamp, quark).getStateValue().unboxInt();
159 } catch (AttributeNotFoundException e) {
160 e.printStackTrace();
161 } catch (StateValueTypeException e) {
162 e.printStackTrace();
163 } catch (TimeRangeException e) {
164 /* Should not happen, we're clamped to the start and end times */
165 e.printStackTrace();
200789b3 166 }
df310609
AM
167
168 long total = countAtEnd - countAtStart;
200789b3
AM
169 return total;
170 }
171
172 @Override
173 public Map<String, Long> getEventTypesInRange(ITmfTimestamp start, ITmfTimestamp end) {
174 Map<String, Long> map = new HashMap<String, Long>();
175
176 /* Make sure the start/end times are within the state history, so we
177 * don't get TimeRange exceptions.
178 */
179 long startTimestamp = checkStartTime(start.getValue());
180 long endTimestamp = checkEndTime(end.getValue());
181
182 try {
183 /* Get the list of quarks, one for each even type in the database */
184 int quark = stats.getQuarkAbsolute(Attributes.EVENT_TYPES);
185 List<Integer> quarks = stats.getSubAttributes(quark, false);
186
187 /*
188 * Get the complete states (in our case, event counts) at the start
189 * time and end time of the requested time range.
190 */
191 List<ITmfStateInterval> startState = stats.queryFullState(startTimestamp);
192 List<ITmfStateInterval> endState = stats.queryFullState(endTimestamp);
193
194 /* Save the relevant information in the map we will be returning */
195 String curEventName;
196 long countAtStart, countAtEnd, eventCount;
197 for (int typeQuark : quarks) {
198 curEventName = stats.getAttributeName(typeQuark);
199 countAtStart = startState.get(typeQuark).getStateValue().unboxInt();
200 countAtEnd = endState.get(typeQuark).getStateValue().unboxInt();
201
202 /*
203 * The default value for the statistics is 0, rather than the
204 * value -1 used by the state system for non-initialized state.
205 */
206 if (startTimestamp == stats.getStartTime() || countAtStart == -1) {
207 countAtStart = 0;
208 }
209
210 /*
211 * Workaround a bug in the state system where requests for the
212 * very last state change will give -1. Send the request 1ns
213 * before the end of the trace and add the last event to the
214 * count.
215 */
216 if (countAtEnd < 0) {
217 ITmfStateInterval realInterval = stats.querySingleState(endTimestamp - 1, typeQuark);
218 countAtEnd = realInterval.getStateValue().unboxInt() + 1;
219 }
220
221 /*
222 * If after this it is still at -1, it's because no event of
223 * this type happened during the requested time range.
224 */
225 if (countAtEnd < 0) {
226 countAtEnd = 0;
227 }
228
229 eventCount = countAtEnd - countAtStart;
230 map.put(curEventName, eventCount);
231 }
232 } catch (TimeRangeException e) {
233 /*
234 * If a request is made for an invalid time range, we will ignore it
235 * silently and not add any information to the map.
236 */
237 } catch (AttributeNotFoundException e) {
238 /*
239 * These other exceptions would show a logic problem however, so
240 * they should not happen.
241 */
242 e.printStackTrace();
243 } catch (StateValueTypeException e) {
244 e.printStackTrace();
245 }
246 return map;
247 }
248
89c06060 249 protected long checkStartTime(long start) {
200789b3
AM
250 if (start < stats.getStartTime()) {
251 return stats.getStartTime();
252 }
253 return start;
254 }
255
89c06060 256 protected long checkEndTime(long end) {
200789b3
AM
257 if (end > stats.getCurrentEndTime()) {
258 return stats.getCurrentEndTime();
259 }
260 return end;
261 }
262
263
264 /**
265 * The attribute names that are used in the state provider
266 */
267 public static class Attributes {
268
df310609
AM
269 /** Total nb of events */
270 public static final String TOTAL = "total"; //$NON-NLS-1$
271
200789b3
AM
272 /** event_types */
273 public static final String EVENT_TYPES = "event_types"; //$NON-NLS-1$<
274 }
275}
This page took 0.036507 seconds and 5 git commands to generate.