tmf: Add an ID to each state system that gets built
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / statistics / TmfStatistics.java
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
13 package org.eclipse.linuxtools.tmf.core.statistics;
14
15 import java.io.File;
16 import java.util.HashMap;
17 import java.util.List;
18 import java.util.Map;
19
20 import org.eclipse.core.resources.IResource;
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.linuxtools.tmf.core.TmfCommonConstants;
23 import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
24 import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
25 import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
26 import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
27 import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
28 import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval;
29 import org.eclipse.linuxtools.tmf.core.statesystem.IStateChangeInput;
30 import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
31 import org.eclipse.linuxtools.tmf.core.statesystem.StateSystemManager;
32 import 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
42 public class TmfStatistics implements ITmfStatistics {
43
44 /** ID for the statistics state system */
45 public static final String STATE_ID = "org.eclipse.linuxtools.tmf.statistics"; //$NON-NLS-1$
46
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
57 /**
58 * Constructor
59 *
60 * @param trace
61 * The trace for which we build these statistics
62 * @throws TmfTraceException
63 * If something went wrong trying to initialize the statistics
64 */
65 public TmfStatistics(ITmfTrace trace) throws TmfTraceException {
66 /* Set up the path to the history tree file we'll use */
67 IResource resource = trace.getResource();
68 String supplDirectory = null;
69
70 try {
71 // get the directory where the history file will be stored.
72 supplDirectory = resource.getPersistentProperty(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER);
73 } catch (CoreException e) {
74 throw new TmfTraceException(e.toString(), e);
75 }
76
77 final File htFile = new File(supplDirectory + File.separator + STATS_STATE_FILENAME);
78 final IStateChangeInput htInput = new StatsStateProvider(trace);
79
80 this.stats = StateSystemManager.loadStateHistory(htFile, htInput, STATE_ID, false);
81 }
82
83 // ------------------------------------------------------------------------
84 // ITmfStatisticsProvider
85 // ------------------------------------------------------------------------
86
87 @Override
88 public long getEventsTotal() {
89 /*
90 * The total itself is not stored in the state, so we will do a
91 * "event types" query then add the contents manually.
92 */
93 Map<String, Long> map = getEventTypesTotal();
94 long total = 0;
95 for (long count : map.values()) {
96 total += count;
97 }
98 return total;
99 }
100
101 @Override
102 public Map<String, Long> getEventTypesTotal() {
103 Map<String, Long> map = new HashMap<String, Long>();
104 long endTime = stats.getCurrentEndTime(); //shouldn't need to check it...
105
106 try {
107 /* Get the list of quarks, one for each even type in the database */
108 int quark = stats.getQuarkAbsolute(Attributes.EVENT_TYPES);
109 List<Integer> quarks = stats.getSubAttributes(quark, false);
110
111 /* Since we want the total we can look only at the end */
112 List<ITmfStateInterval> endState = stats.queryFullState(endTime);
113
114 String curEventName;
115 long eventCount;
116 for (int typeQuark : quarks) {
117 curEventName = stats.getAttributeName(typeQuark);
118 eventCount = endState.get(typeQuark).getStateValue().unboxInt();
119 map.put(curEventName, eventCount);
120 }
121
122 } catch (TimeRangeException e) {
123 /* Ignore silently */
124 } catch (AttributeNotFoundException e) {
125 e.printStackTrace();
126 } catch (StateValueTypeException e) {
127 e.printStackTrace();
128 }
129 return map;
130 }
131
132 @Override
133 public long getEventsInRange(ITmfTimestamp start, ITmfTimestamp end) {
134 /*
135 * The total itself is not stored in the state, so we will do a
136 * "event types" query then add the contents manually.
137 */
138 Map<String, Long> map = getEventTypesInRange(start, end);
139 long total = 0;
140 for (long count : map.values()) {
141 total += count;
142 }
143 return total;
144 }
145
146 @Override
147 public Map<String, Long> getEventTypesInRange(ITmfTimestamp start, ITmfTimestamp end) {
148 Map<String, Long> map = new HashMap<String, Long>();
149
150 /* Make sure the start/end times are within the state history, so we
151 * don't get TimeRange exceptions.
152 */
153 long startTimestamp = checkStartTime(start.getValue());
154 long endTimestamp = checkEndTime(end.getValue());
155
156 try {
157 /* Get the list of quarks, one for each even type in the database */
158 int quark = stats.getQuarkAbsolute(Attributes.EVENT_TYPES);
159 List<Integer> quarks = stats.getSubAttributes(quark, false);
160
161 /*
162 * Get the complete states (in our case, event counts) at the start
163 * time and end time of the requested time range.
164 */
165 List<ITmfStateInterval> startState = stats.queryFullState(startTimestamp);
166 List<ITmfStateInterval> endState = stats.queryFullState(endTimestamp);
167
168 /* Save the relevant information in the map we will be returning */
169 String curEventName;
170 long countAtStart, countAtEnd, eventCount;
171 for (int typeQuark : quarks) {
172 curEventName = stats.getAttributeName(typeQuark);
173 countAtStart = startState.get(typeQuark).getStateValue().unboxInt();
174 countAtEnd = endState.get(typeQuark).getStateValue().unboxInt();
175
176 /*
177 * The default value for the statistics is 0, rather than the
178 * value -1 used by the state system for non-initialized state.
179 */
180 if (startTimestamp == stats.getStartTime() || countAtStart == -1) {
181 countAtStart = 0;
182 }
183
184 /*
185 * Workaround a bug in the state system where requests for the
186 * very last state change will give -1. Send the request 1ns
187 * before the end of the trace and add the last event to the
188 * count.
189 */
190 if (countAtEnd < 0) {
191 ITmfStateInterval realInterval = stats.querySingleState(endTimestamp - 1, typeQuark);
192 countAtEnd = realInterval.getStateValue().unboxInt() + 1;
193 }
194
195 /*
196 * If after this it is still at -1, it's because no event of
197 * this type happened during the requested time range.
198 */
199 if (countAtEnd < 0) {
200 countAtEnd = 0;
201 }
202
203 eventCount = countAtEnd - countAtStart;
204 map.put(curEventName, eventCount);
205 }
206 } catch (TimeRangeException e) {
207 /*
208 * If a request is made for an invalid time range, we will ignore it
209 * silently and not add any information to the map.
210 */
211 } catch (AttributeNotFoundException e) {
212 /*
213 * These other exceptions would show a logic problem however, so
214 * they should not happen.
215 */
216 e.printStackTrace();
217 } catch (StateValueTypeException e) {
218 e.printStackTrace();
219 }
220 return map;
221 }
222
223 private long checkStartTime(long start) {
224 if (start < stats.getStartTime()) {
225 return stats.getStartTime();
226 }
227 return start;
228 }
229
230 private long checkEndTime(long end) {
231 if (end > stats.getCurrentEndTime()) {
232 return stats.getCurrentEndTime();
233 }
234 return end;
235 }
236
237
238 /**
239 * The attribute names that are used in the state provider
240 */
241 public static class Attributes {
242
243 /** event_types */
244 public static final String EVENT_TYPES = "event_types"; //$NON-NLS-1$<
245 }
246 }
This page took 0.036785 seconds and 5 git commands to generate.