Commit | Line | Data |
---|---|---|
9dbeec54 FC |
1 | /******************************************************************************* |
2 | * Copyright (c) 2010 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 | * Francois Godin (copelnug@gmail.com) - Initial design and implementation | |
11 | *******************************************************************************/ | |
12 | ||
13 | package org.eclipse.linuxtools.lttng.ui.views.statistics.model; | |
14 | ||
15 | import java.util.Collection; | |
b12f4544 | 16 | import java.util.HashMap; |
9dbeec54 FC |
17 | import java.util.HashSet; |
18 | import java.util.LinkedList; | |
19 | import java.util.Set; | |
20 | import java.util.Map; | |
21 | ||
b12f4544 | 22 | import org.eclipse.linuxtools.lttng.LttngConstants; |
9dbeec54 FC |
23 | import org.eclipse.linuxtools.lttng.event.LttngEvent; |
24 | import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionMode; | |
25 | import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus; | |
26 | import org.eclipse.linuxtools.lttng.state.model.LttngProcessState; | |
27 | import org.eclipse.linuxtools.lttng.state.model.LttngTraceState; | |
28 | ||
29 | /** | |
30 | * <h4>Class that process the LTTng kernel events.</h4> | |
31 | */ | |
32 | public class KernelStatisticsData extends StatisticsData { | |
a2e53983 | 33 | /** |
b12f4544 | 34 | * <h4>Header for the CPU categories.</h4> |
a2e53983 | 35 | */ |
b12f4544 FC |
36 | public static final String HEADER_CPUS = Messages.KernelStatisticsData_CPUs; |
37 | public static final int HEADER_CPUS_INT = 256 | LttngConstants.STATS_CATEGORY_ID; | |
a2e53983 FC |
38 | /** |
39 | * <h4>Header for the event types categories.</h4> | |
40 | */ | |
b12f4544 FC |
41 | public static final String HEADER_EVENT_TYPES = Messages.KernelStatisticsData_EventTypes; |
42 | public static final int HEADER_EVENT_TYPES_INT = (HEADER_CPUS_INT + 1) | LttngConstants.STATS_CATEGORY_ID; | |
a2e53983 FC |
43 | /** |
44 | * <h4>Header for the function categories.</h4> | |
45 | */ | |
b12f4544 FC |
46 | public static final String HEADER_FUNCTIONS = Messages.KernelStatisticsData_Functions; |
47 | public static final int HEADER_FUNCTIONS_INT = (HEADER_EVENT_TYPES_INT + 1) | LttngConstants.STATS_CATEGORY_ID; | |
a2e53983 FC |
48 | /** |
49 | * <h4>Header for the mode categories.</h4> | |
50 | */ | |
b12f4544 FC |
51 | public static final String HEADER_MODES = Messages.KernelStatisticsData_Modes; |
52 | public static final int HEADER_MODES_INT = (HEADER_FUNCTIONS_INT + 1) | LttngConstants.STATS_CATEGORY_ID; | |
a2e53983 FC |
53 | /** |
54 | * <h4>Header for the processes categories.</h4> | |
55 | */ | |
b12f4544 FC |
56 | public static final String HEADER_PROCESSES = Messages.KernelStatisticsData_Processes; |
57 | public static final int HEADER_PROCESSES_INT = (HEADER_MODES_INT + 1) | LttngConstants.STATS_CATEGORY_ID; | |
a2e53983 FC |
58 | /** |
59 | * <h4>Header for the submode categories.</h4> | |
60 | */ | |
b12f4544 FC |
61 | public static final String HEADER_SUBMODES = Messages.KernelStatisticsData_SubModes; |
62 | public static final int HEADER_SUBMODES_INT = (HEADER_PROCESSES_INT + 1) | LttngConstants.STATS_CATEGORY_ID; | |
63 | ||
64 | /** | |
65 | * <h4>Class to generate unique IDs for processes.</h4> | |
66 | */ | |
67 | private KeyProvider fPidKeys = new KeyProvider(LttngConstants.STATS_PROCESS_ID); | |
68 | ||
69 | /** | |
70 | * <h4>Class to generate unique Ids for event types.</h4> | |
71 | */ | |
72 | private KeyProvider fTypeKeys = new KeyProvider(LttngConstants.STATS_TYPE_ID); | |
73 | /** | |
74 | * <h4>Class to generate unique Ids for subModes.</h4> | |
75 | */ | |
76 | private KeyProvider fSubModeKeys = new KeyProvider(); | |
77 | ||
78 | /** | |
79 | * <h4>Place Holder in path.</h4> | |
80 | */ | |
81 | private static final int PLACE_HOLDER = 0; | |
82 | ||
83 | /** | |
84 | * For performance reason the following algorithm is applied to the paths: | |
85 | * | |
86 | * Each array entry has to be unique to form a unique path. To generate | |
87 | * unique entries a bit mask is used, where the bit mask is applied to the | |
88 | * upper N bits of an integer value. It is assumed, that each value that | |
89 | * will be filled in the place holder below is smaller than 2 ^ (32 - N). | |
90 | */ | |
91 | ||
92 | /** | |
93 | * <h4>Pre-created paths for type statistics, which will be filled for each | |
94 | * relevant event.</h4> | |
95 | */ | |
96 | private final FixedArray[] fTypedPaths = { new FixedArray(PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), new FixedArray(PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
97 | new FixedArray(PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_SUBMODES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
98 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
99 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
100 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_FUNCTIONS_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
101 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_FUNCTIONS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
102 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_FUNCTIONS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_SUBMODES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
103 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
104 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_SUBMODES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
105 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
106 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_SUBMODES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
107 | new FixedArray(PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), new FixedArray(PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), | |
108 | new FixedArray(PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_SUBMODES_INT, PLACE_HOLDER, HEADER_EVENT_TYPES_INT, PLACE_HOLDER), }; | |
109 | /** | |
110 | * <h4>Pre-created paths for other statistics, which will be filled for each | |
111 | * relevant event.</h4> | |
112 | */ | |
113 | final FixedArray[] fNormalPaths = { new FixedArray(PLACE_HOLDER), new FixedArray(PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER), new FixedArray(PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_SUBMODES_INT, PLACE_HOLDER), | |
114 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER), new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER), | |
115 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_FUNCTIONS_INT, PLACE_HOLDER), | |
116 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_FUNCTIONS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER), | |
117 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_FUNCTIONS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_SUBMODES_INT, PLACE_HOLDER), | |
118 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER), | |
119 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_SUBMODES_INT, PLACE_HOLDER), | |
120 | new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER), new FixedArray(PLACE_HOLDER, HEADER_PROCESSES_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_SUBMODES_INT, PLACE_HOLDER), | |
121 | new FixedArray(PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER), new FixedArray(PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER), | |
122 | new FixedArray(PLACE_HOLDER, HEADER_CPUS_INT, PLACE_HOLDER, HEADER_MODES_INT, PLACE_HOLDER, HEADER_SUBMODES_INT, PLACE_HOLDER), }; | |
123 | ||
a2e53983 FC |
124 | /** |
125 | * <h4>Indicate that it's a value.</h4> | |
126 | * <p> | |
127 | * Used when checking the possible child node for a node. | |
128 | * </p> | |
129 | * <p> | |
130 | * It differentiate a category of a value by being appended to a value. | |
131 | * </p> | |
132 | */ | |
b12f4544 FC |
133 | private static final Integer NODE = -1; |
134 | private static final Integer ROOT_NODE_KEY = -2; | |
a2e53983 FC |
135 | |
136 | /** | |
137 | * <h4>Constructor.</h4> | |
138 | * | |
139 | * @param traceName | |
140 | */ | |
141 | public KernelStatisticsData(String traceName) { | |
b12f4544 FC |
142 | super(); |
143 | Map<Integer, Set<Integer>> keys = getKeys(); | |
144 | ||
145 | // //////////// Adding category sets | |
146 | keys.put(HEADER_PROCESSES_INT, new HashSet<Integer>()); | |
147 | keys.put(HEADER_MODES_INT, new HashSet<Integer>()); | |
148 | keys.put(HEADER_CPUS_INT, new HashSet<Integer>(4)); // Over 4 CPUs is | |
149 | // not common | |
150 | keys.put(HEADER_SUBMODES_INT, new HashSet<Integer>()); | |
151 | keys.put(HEADER_EVENT_TYPES_INT, new HashSet<Integer>()); | |
152 | keys.put(HEADER_FUNCTIONS_INT, new HashSet<Integer>(4)); // Seems to be | |
153 | // always one. | |
154 | ||
155 | // /////////// Adding value sets | |
156 | // Under a trace | |
157 | Set<Integer> temp = new HashSet<Integer>(8); | |
158 | temp.add(HEADER_PROCESSES_INT); | |
159 | temp.add(HEADER_MODES_INT); | |
160 | temp.add(HEADER_CPUS_INT); | |
161 | temp.add(HEADER_EVENT_TYPES_INT); | |
162 | keys.put(ROOT_NODE_KEY, temp); | |
163 | // Under a process | |
164 | temp = new HashSet<Integer>(4); | |
165 | temp.add(HEADER_MODES_INT); | |
166 | temp.add(HEADER_CPUS_INT); | |
167 | temp.add(HEADER_EVENT_TYPES_INT); | |
168 | keys.put(HEADER_PROCESSES_INT * NODE, temp); | |
169 | // Under a CPUs : Functions is a special case | |
170 | temp = new HashSet<Integer>(4); | |
171 | temp.add(HEADER_MODES_INT); | |
172 | temp.add(HEADER_EVENT_TYPES_INT); | |
173 | keys.put(HEADER_CPUS_INT * NODE, temp); | |
174 | // Under a functions | |
175 | temp = new HashSet<Integer>(4); | |
176 | temp.add(HEADER_MODES_INT); | |
177 | temp.add(HEADER_EVENT_TYPES_INT); | |
178 | keys.put(HEADER_FUNCTIONS_INT * NODE, temp); | |
179 | // Under a mode | |
180 | temp = new HashSet<Integer>(4); | |
181 | temp.add(HEADER_SUBMODES_INT); | |
182 | temp.add(HEADER_EVENT_TYPES_INT); | |
183 | keys.put(HEADER_MODES_INT * NODE, temp); | |
184 | // Under a submodes | |
185 | temp = new HashSet<Integer>(2); | |
186 | temp.add(HEADER_EVENT_TYPES_INT); | |
187 | keys.put(HEADER_SUBMODES_INT * NODE, temp); | |
188 | // Under an event type | |
189 | temp = new HashSet<Integer>(16); | |
190 | keys.put(HEADER_EVENT_TYPES_INT * NODE, temp); | |
191 | ||
192 | // //////////// CREATE root | |
193 | keys.put(ROOT.get(0), new HashSet<Integer>(2)); // 1 trace at the time | |
194 | StatisticsTreeNode node = getOrCreate(ROOT); | |
195 | node.setName("root"); //$NON-NLS-1$ | |
a2e53983 FC |
196 | } |
197 | ||
198 | /* | |
199 | * (non-Javadoc) | |
200 | * | |
201 | * @see | |
202 | * org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData | |
203 | * #endTraceset(org.eclipse.linuxtools.lttng.event.LttngEvent, | |
204 | * org.eclipse.linuxtools.lttng.state.model.LttngTraceState) | |
205 | */ | |
206 | @Override | |
207 | public void endTraceset(LttngEvent event, LttngTraceState traceState) { | |
b12f4544 FC |
208 | // TODO Should we uncomment the rest? |
209 | // It include in the cpu time the time between the last event of each | |
210 | // cpu and the time of the last global event. | |
211 | // Because we know that there won't be a change of mode or process | |
212 | // between those time. | |
213 | /* | |
214 | * if(last_ == null) return; | |
215 | * | |
216 | * LttngProcessState process = traceState.getRunning_process().get(0L); | |
217 | * System.out.println(process.getState().getChange_LttTime()); for(long | |
218 | * cpu : traceState.getRunning_process().keySet()) { LttngEventType | |
219 | * newType = new LttngEventType(last_.getType().getTracefileName(), cpu, | |
220 | * last_.getType().getMarkerName(), last_.getType().getLabels()); | |
221 | * last_.setType(newType); increase(last_, traceState, Values.CPU_TIME | | |
222 | * Values.CUMULATIVE_CPU_TIME | Values.ELAPSED_TIME | | |
223 | * Values.STATE_CUMULATIVE_CPU_TIME); // TODO Are all those values | |
224 | * required? } | |
225 | */ | |
a2e53983 FC |
226 | } |
227 | ||
228 | /* | |
229 | * (non-Javadoc) | |
230 | * | |
231 | * @see | |
232 | * org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData | |
233 | * #getChildren | |
234 | * (org.eclipse.linuxtools.lttng.ui.views.statistics.model.FixedArray) | |
235 | */ | |
236 | @Override | |
b12f4544 FC |
237 | public Collection<StatisticsTreeNode> getChildren(final FixedArray path) { |
238 | LinkedList<StatisticsTreeNode> result = new LinkedList<StatisticsTreeNode>(); | |
239 | ||
240 | if (path.size() % 2 == 0) { // if we are at a Category | |
241 | StatisticsTreeNode current = null; | |
242 | for (int value : getKeys().get(path.get(path.size() - 1))) { | |
243 | current = get(path.append(value)); | |
244 | if (current != null && current.getValue().nbEvents != 0) | |
245 | result.add(current); | |
246 | } | |
247 | } else if (path.size() == 1) { // Special case. | |
248 | if (path.equals(ROOT)) // Asking for the root. | |
249 | for (int value : getKeys().get(ROOT.get(0))) | |
250 | result.add(getOrCreate(new FixedArray(value))); | |
251 | else | |
252 | // Get value under the root | |
253 | for (int value : getKeys().get(ROOT_NODE_KEY)) { | |
254 | StatisticsTreeNode node = getOrCreate(path.append(value)); | |
255 | node.setName(getCategoryFromId(value)); | |
256 | result.add(node); | |
257 | } | |
258 | } else {// If we are at a value | |
259 | for (int value : getKeys().get((path.get(path.size() - 2) * NODE))) { // Search | |
260 | // the | |
261 | // parent | |
262 | // name | |
263 | // + | |
264 | // NODE | |
265 | StatisticsTreeNode node = getOrCreate(path.append(value)); | |
266 | node.setName(getCategoryFromId(value)); | |
267 | result.add(node); | |
268 | } | |
269 | ||
270 | if (path.size() == 5 && path.get(3) == HEADER_CPUS_INT) { // Special | |
271 | // the | |
272 | // Functions | |
273 | // is just | |
274 | // there. | |
275 | // We want | |
276 | // the | |
277 | // fourth | |
278 | // element | |
279 | // but it | |
280 | // start | |
281 | // at 0. | |
282 | // So #3 | |
283 | StatisticsTreeNode node = getOrCreate(path.append(HEADER_FUNCTIONS_INT)); | |
284 | node.setName(getCategoryFromId(HEADER_FUNCTIONS_INT)); | |
285 | result.add(node); | |
286 | } | |
287 | } | |
288 | ||
289 | return result; | |
a2e53983 FC |
290 | } |
291 | ||
292 | /** | |
293 | * <h4>Get the standard paths for an event.</h4> | |
294 | * | |
295 | * @param event | |
296 | * Event to get the path for. | |
297 | * @param traceState | |
298 | * State of the trace for this event. | |
299 | * @return Array of FixedArray representing the paths. | |
300 | */ | |
b12f4544 FC |
301 | private FixedArray[] getNormalPaths(LttngEvent event, LttngTraceState traceState) { |
302 | int trace = (int) traceState.getContext().getIdentifier(); // No need | |
303 | // for the | |
304 | // identifier | |
305 | // (already | |
306 | // applied) | |
307 | Long cpu = event.getCpuId(); | |
308 | int cpus = cpu.intValue() | LttngConstants.STATS_CPU_ID; | |
309 | LttngProcessState process = traceState.getRunning_process().get(cpu); | |
310 | int processName = fPidKeys.getUniqueId(process.getPid().intValue(), process.getName()); | |
311 | int mode = process.getState().getExec_mode().ordinal() | LttngConstants.STATS_MODE_ID; | |
312 | int submode = fSubModeKeys.getUniqueId(process.getState().getExec_submode_id(), process.getState().getExec_submode()); | |
313 | int function = process.getCurrent_function().intValue() | LttngConstants.STATS_FUNCTION_ID; | |
314 | ||
315 | /* | |
316 | * Note that it's faster to re-use the path object, set the relevant | |
317 | * fields and clone the path later when it's time to add to the map | |
318 | */ | |
319 | ||
320 | // FixedArray(trace) | |
321 | fNormalPaths[0].set(0, trace); | |
322 | ||
323 | // FixedArray(trace,HEADER_MODES_INT,mode) | |
324 | fNormalPaths[1].set(0, trace); | |
325 | fNormalPaths[1].set(2, mode); | |
326 | ||
327 | // FixedArray(trace,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode) | |
328 | fNormalPaths[2].set(0, trace); | |
329 | fNormalPaths[2].set(2, mode); | |
330 | fNormalPaths[2].set(4, submode); | |
331 | ||
332 | // FixedArray(trace,HEADER_PROCESSES_INT,processName) | |
333 | fNormalPaths[3].set(0, trace); | |
334 | fNormalPaths[3].set(2, processName); | |
335 | ||
336 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus) | |
337 | fNormalPaths[4].set(0, trace); | |
338 | fNormalPaths[4].set(2, processName); | |
339 | fNormalPaths[4].set(4, cpus); | |
340 | ||
341 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_FUNCTIONS_INT,function) | |
342 | fNormalPaths[5].set(0, trace); | |
343 | fNormalPaths[5].set(2, processName); | |
344 | fNormalPaths[5].set(4, cpus); | |
345 | fNormalPaths[5].set(6, function); | |
346 | ||
347 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_FUNCTIONS_INT,function, | |
348 | // HEADER_MODES_INT, mode) | |
349 | fNormalPaths[6].set(0, trace); | |
350 | fNormalPaths[6].set(2, processName); | |
351 | fNormalPaths[6].set(4, cpus); | |
352 | fNormalPaths[6].set(6, function); | |
353 | fNormalPaths[6].set(8, mode); | |
354 | ||
355 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_FUNCTIONS_INT,function, | |
356 | // HEADER_MODES_INT, mode, HEADER_SUBMODES_INT, submode) | |
357 | fNormalPaths[7].set(0, trace); | |
358 | fNormalPaths[7].set(2, processName); | |
359 | fNormalPaths[7].set(4, cpus); | |
360 | fNormalPaths[7].set(6, function); | |
361 | fNormalPaths[7].set(8, mode); | |
362 | fNormalPaths[7].set(10, submode); | |
363 | ||
364 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode) | |
365 | fNormalPaths[8].set(0, trace); | |
366 | fNormalPaths[8].set(2, processName); | |
367 | fNormalPaths[8].set(4, cpus); | |
368 | fNormalPaths[8].set(6, mode); | |
369 | ||
370 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode) | |
371 | fNormalPaths[9].set(0, trace); | |
372 | fNormalPaths[9].set(2, processName); | |
373 | fNormalPaths[9].set(4, cpus); | |
374 | fNormalPaths[9].set(6, mode); | |
375 | fNormalPaths[9].set(8, submode); | |
376 | ||
377 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_MODES_INT,mode) | |
378 | fNormalPaths[10].set(0, trace); | |
379 | fNormalPaths[10].set(2, processName); | |
380 | fNormalPaths[10].set(4, mode); | |
381 | ||
382 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode) | |
383 | fNormalPaths[11].set(0, trace); | |
384 | fNormalPaths[11].set(2, processName); | |
385 | fNormalPaths[11].set(4, mode); | |
386 | fNormalPaths[11].set(6, submode); | |
387 | ||
388 | // FixedArray(trace,HEADER_CPUS_INT,cpus) | |
389 | fNormalPaths[12].set(0, trace); | |
390 | fNormalPaths[12].set(2, cpus); | |
391 | ||
392 | // FixedArray(trace,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode) | |
393 | fNormalPaths[13].set(0, trace); | |
394 | fNormalPaths[13].set(2, cpus); | |
395 | fNormalPaths[13].set(4, mode); | |
396 | ||
397 | // FixedArray(trace,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode) | |
398 | fNormalPaths[14].set(0, trace); | |
399 | fNormalPaths[14].set(2, cpus); | |
400 | fNormalPaths[14].set(4, mode); | |
401 | fNormalPaths[14].set(6, submode); | |
402 | ||
403 | return fNormalPaths; | |
404 | ||
a2e53983 FC |
405 | } |
406 | ||
407 | /** | |
408 | * <h4>Get the event types paths.</h4> | |
409 | * | |
410 | * @param event | |
411 | * Event to get the path for. | |
412 | * @param traceState | |
413 | * State of the trace for this event. | |
414 | * @return Array of FixedArray representing the paths. | |
415 | */ | |
b12f4544 FC |
416 | private FixedArray[] getTypePaths(LttngEvent event, LttngTraceState traceState) { |
417 | int trace = (int) traceState.getContext().getIdentifier(); // No need | |
418 | // for the | |
419 | // identifier | |
420 | // (already | |
421 | // applied) | |
422 | Long cpu = event.getCpuId(); | |
423 | int cpus = cpu.intValue() | LttngConstants.STATS_CPU_ID; | |
424 | LttngProcessState process = traceState.getRunning_process().get(cpu); | |
425 | int processName = fPidKeys.getUniqueId(process.getPid().intValue(), process.getName()); | |
426 | int mode = process.getState().getExec_mode().ordinal() | LttngConstants.STATS_MODE_ID; | |
427 | int submode = fSubModeKeys.getUniqueId(process.getState().getExec_submode_id(), process.getState().getExec_submode()); | |
428 | int function = process.getCurrent_function().intValue() | LttngConstants.STATS_FUNCTION_ID; | |
429 | int type = fTypeKeys.getUniqueId(event.getMarkerId(), event.getMarkerName()); | |
430 | ||
431 | /* | |
432 | * Note that it's faster to re-use the path object, set the relevant | |
433 | * fields and clone the path later when it's time to add to the map | |
434 | */ | |
435 | ||
436 | // FixedArray(trace,HEADER_EVENT_TYPES_INT,type) | |
437 | fTypedPaths[0].set(0, trace); | |
438 | fTypedPaths[0].set(2, type); | |
439 | ||
440 | // FixedArray(trace,HEADER_MODES_INT,mode,HEADER_EVENT_TYPES_INT,type) | |
441 | fTypedPaths[1].set(0, trace); | |
442 | fTypedPaths[1].set(2, mode); | |
443 | fTypedPaths[1].set(4, type); | |
444 | ||
445 | // FixedArray(trace,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode,HEADER_EVENT_TYPES_INT,type) | |
446 | fTypedPaths[2].set(0, trace); | |
447 | fTypedPaths[2].set(2, mode); | |
448 | fTypedPaths[2].set(4, submode); | |
449 | fTypedPaths[2].set(6, type); | |
450 | ||
451 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_EVENT_TYPES_INT,type) | |
452 | fTypedPaths[3].set(0, trace); | |
453 | fTypedPaths[3].set(2, processName); | |
454 | fTypedPaths[3].set(4, type); | |
455 | ||
456 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_EVENT_TYPES_INT,type) | |
457 | fTypedPaths[4].set(0, trace); | |
458 | fTypedPaths[4].set(2, processName); | |
459 | fTypedPaths[4].set(4, cpus); | |
460 | fTypedPaths[4].set(6, type); | |
461 | ||
462 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_FUNCTIONS_INT,function,HEADER_EVENT_TYPES_INT,type) | |
463 | fTypedPaths[5].set(0, trace); | |
464 | fTypedPaths[5].set(2, processName); | |
465 | fTypedPaths[5].set(4, cpus); | |
466 | fTypedPaths[5].set(6, function); | |
467 | fTypedPaths[5].set(8, type); | |
468 | ||
469 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_FUNCTIONS_INT,function,HEADER_MODES_INT,mode,HEADER_EVENT_TYPES_INT,type) | |
470 | fTypedPaths[6].set(0, trace); | |
471 | fTypedPaths[6].set(2, processName); | |
472 | fTypedPaths[6].set(4, cpus); | |
473 | fTypedPaths[6].set(6, function); | |
474 | fTypedPaths[6].set(8, mode); | |
475 | fTypedPaths[6].set(10, type); | |
476 | ||
477 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_FUNCTIONS_INT,function, | |
478 | // HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode,HEADER_EVENT_TYPES_INT,type) | |
479 | fTypedPaths[7].set(0, trace); | |
480 | fTypedPaths[7].set(2, processName); | |
481 | fTypedPaths[7].set(4, cpus); | |
482 | fTypedPaths[7].set(6, function); | |
483 | fTypedPaths[7].set(8, mode); | |
484 | fTypedPaths[7].set(10, submode); | |
485 | fTypedPaths[7].set(12, type); | |
486 | ||
487 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode,HEADER_EVENT_TYPES_INT,type) | |
488 | fTypedPaths[8].set(0, trace); | |
489 | fTypedPaths[8].set(2, processName); | |
490 | fTypedPaths[8].set(4, cpus); | |
491 | fTypedPaths[8].set(6, mode); | |
492 | fTypedPaths[8].set(8, type); | |
493 | ||
494 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode,HEADER_EVENT_TYPES_INT,type) | |
495 | fTypedPaths[9].set(0, trace); | |
496 | fTypedPaths[9].set(2, processName); | |
497 | fTypedPaths[9].set(4, cpus); | |
498 | fTypedPaths[9].set(6, mode); | |
499 | fTypedPaths[9].set(8, submode); | |
500 | fTypedPaths[9].set(10, type); | |
501 | ||
502 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_MODES_INT,mode,HEADER_EVENT_TYPES_INT,type) | |
503 | fTypedPaths[10].set(0, trace); | |
504 | fTypedPaths[10].set(2, processName); | |
505 | fTypedPaths[10].set(4, mode); | |
506 | fTypedPaths[10].set(6, type); | |
507 | ||
508 | // FixedArray(trace,HEADER_PROCESSES_INT,processName,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode,HEADER_EVENT_TYPES_INT,type) | |
509 | fTypedPaths[11].set(0, trace); | |
510 | fTypedPaths[11].set(2, processName); | |
511 | fTypedPaths[11].set(4, mode); | |
512 | fTypedPaths[11].set(6, submode); | |
513 | fTypedPaths[11].set(8, type); | |
514 | ||
515 | // FixedArray(trace,HEADER_CPUS_INT,cpus,HEADER_EVENT_TYPES_INT,type) | |
516 | fTypedPaths[12].set(0, trace); | |
517 | fTypedPaths[12].set(2, cpus); | |
518 | fTypedPaths[12].set(4, type); | |
519 | ||
520 | // FixedArray(trace,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode,HEADER_EVENT_TYPES_INT,type) | |
521 | fTypedPaths[13].set(0, trace); | |
522 | fTypedPaths[13].set(2, cpus); | |
523 | fTypedPaths[13].set(4, mode); | |
524 | fTypedPaths[13].set(6, type); | |
525 | ||
526 | // FixedArray(trace,HEADER_CPUS_INT,cpus,HEADER_MODES_INT,mode,HEADER_SUBMODES_INT,submode,HEADER_EVENT_TYPES_INT,type) | |
527 | fTypedPaths[14].set(0, trace); | |
528 | fTypedPaths[14].set(2, cpus); | |
529 | fTypedPaths[14].set(4, mode); | |
530 | fTypedPaths[14].set(6, submode); | |
531 | fTypedPaths[14].set(8, type); | |
532 | ||
533 | return fTypedPaths; | |
a2e53983 FC |
534 | } |
535 | ||
536 | /* | |
537 | * (non-Javadoc) | |
538 | * | |
539 | * @see | |
540 | * org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData | |
541 | * #process_exit(org.eclipse.linuxtools.lttng.event.LttngEvent, | |
542 | * org.eclipse.linuxtools.lttng.state.model.LttngTraceState) | |
543 | */ | |
544 | @Override | |
545 | public void process_exit(LttngEvent event, LttngTraceState traceState) { | |
b12f4544 FC |
546 | FixedArray[] paths = getNormalPaths(event, traceState); |
547 | Long cpu = event.getCpuId(); | |
548 | LttngProcessState process = traceState.getRunning_process().get(cpu); | |
a2e53983 | 549 | |
b12f4544 FC |
550 | for (int j = 0; j < paths.length; ++j) { |
551 | StatisticsTreeNode node = getOrCreate(paths[j], event, traceState, j, false); | |
a2e53983 | 552 | |
b12f4544 FC |
553 | if (!process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { |
554 | node.getValue().cpuTime += event.getTimestamp().getValue() - process.getState().getChange_LttTime(); | |
555 | } | |
556 | } | |
557 | // TODO Unstacks cumulative CPU time | |
558 | // TODO Elapsed time? | |
a2e53983 FC |
559 | } |
560 | ||
561 | /* | |
562 | * (non-Javadoc) | |
563 | * | |
564 | * @see | |
565 | * org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData | |
566 | * #increase(org.eclipse.linuxtools.lttng.event.LttngEvent, | |
567 | * org.eclipse.linuxtools.lttng.state.model.LttngTraceState, int) | |
568 | */ | |
569 | @Override | |
570 | public void increase(LttngEvent event, LttngTraceState traceState, int values) { | |
b12f4544 FC |
571 | FixedArray[] paths = getNormalPaths(event, traceState); |
572 | Long cpu = event.getCpuId(); | |
573 | LttngProcessState process = traceState.getRunning_process().get(cpu); | |
574 | ||
575 | for (int j = 0; j < paths.length; ++j) { | |
576 | StatisticsTreeNode node = getOrCreate(paths[j], event, traceState, j, false); | |
577 | ||
578 | if ((values & Values.CPU_TIME) != 0) { | |
579 | // TODO Uncomment if the event after process_exit need to be | |
580 | // count. | |
581 | if ((process.getState().getProc_status().equals(ProcessStatus.LTTV_STATE_RUN) /* | |
582 | * || | |
583 | * process | |
584 | * . | |
585 | * getState | |
586 | * ( | |
587 | * ) | |
588 | * . | |
589 | * getProc_status | |
590 | * ( | |
591 | * ) | |
592 | * . | |
593 | * equals | |
594 | * ( | |
595 | * ProcessStatus | |
596 | * . | |
597 | * LTTV_STATE_EXIT | |
598 | * ) | |
599 | */) && !process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { | |
600 | node.getValue().cpuTime += event.getTimestamp().getValue() - process.getState().getChange_LttTime(); | |
601 | } | |
602 | } | |
603 | if ((values & Values.CUMULATIVE_CPU_TIME) != 0) { | |
604 | if (!process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { | |
605 | long cumulativeCpuTime = process.getState().getCum_cpu_time(); | |
606 | long delta = event.getTimestamp().getValue() - process.getState().getEntry_LttTime(); | |
607 | process.getState().setCum_cpu_time(cumulativeCpuTime + delta); | |
608 | node.getValue().cumulativeCpuTime += process.getState().getCum_cpu_time(); | |
609 | } else if (process.getState().getProc_status().equals(ProcessStatus.LTTV_STATE_RUN) && !process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { | |
610 | long cumulativeCpuTime = process.getState().getCum_cpu_time(); | |
611 | long delta = event.getTimestamp().getValue() - process.getState().getChange_LttTime(); | |
612 | process.getState().setCum_cpu_time(cumulativeCpuTime + delta); | |
613 | node.getValue().cumulativeCpuTime += process.getState().getCum_cpu_time(); | |
614 | } | |
615 | } | |
616 | if ((values & Values.ELAPSED_TIME) != 0) { | |
617 | if (!process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { | |
618 | node.getValue().elapsedTime += event.getTimestamp().getValue() - process.getState().getEntry_LttTime(); | |
619 | } | |
620 | } | |
621 | if ((values & Values.STATE_CUMULATIVE_CPU_TIME) != 0) { | |
622 | if (process.getState().getProc_status().equals(ProcessStatus.LTTV_STATE_RUN) && !process.getState().getExec_mode().equals(ExecutionMode.LTTV_STATE_MODE_UNKNOWN)) { | |
623 | long cumulativeCpuTime = process.getState().getCum_cpu_time(); | |
624 | long delta = event.getTimestamp().getValue() - process.getState().getChange_LttTime(); | |
625 | process.getState().setCum_cpu_time(cumulativeCpuTime + delta); | |
626 | } | |
627 | } | |
628 | } | |
a2e53983 FC |
629 | } |
630 | ||
631 | /* | |
632 | * (non-Javadoc) | |
633 | * | |
634 | * @see | |
635 | * org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData | |
636 | * #registerEvent(org.eclipse.linuxtools.lttng.event.LttngEvent, | |
637 | * org.eclipse.linuxtools.lttng.state.model.LttngTraceState) | |
638 | */ | |
639 | @Override | |
640 | public void registerEvent(LttngEvent event, LttngTraceState traceState) { | |
b12f4544 FC |
641 | FixedArray[] paths = getNormalPaths(event, traceState); |
642 | for (int i = 0; i < paths.length; ++i) | |
643 | ++(getOrCreate(paths[i], event, traceState, i, false).getValue().nbEvents); | |
a2e53983 | 644 | |
b12f4544 FC |
645 | paths = getTypePaths(event, traceState); |
646 | for (int i = 0; i < paths.length; ++i) | |
647 | ++(getOrCreate(paths[i], event, traceState, i, true).getValue().nbEvents); | |
a2e53983 | 648 | |
b12f4544 | 649 | // last_ = event; // TODO Used by endTraceset |
a2e53983 FC |
650 | } |
651 | ||
652 | /* | |
653 | * (non-Javadoc) | |
654 | * | |
655 | * @see | |
656 | * org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsData | |
657 | * #registerName | |
658 | * (org.eclipse.linuxtools.lttng.ui.views.statistics.model.FixedArray) | |
659 | */ | |
660 | @Override | |
b12f4544 FC |
661 | protected void registerName(final FixedArray path) { |
662 | if (path.size() == 1) { | |
663 | if (!path.equals(ROOT)) | |
664 | getKeys().get(ROOT.get(0)).add(path.get(0)); | |
665 | } else if (path.size() % 2 != 0) | |
666 | getKeys().get(path.get(path.size() - 2)).add(path.get(path.size() - 1)); | |
667 | } | |
668 | ||
669 | /** | |
670 | * <h4>Get or create a node.</h4> | |
671 | * | |
672 | * @param path | |
673 | * Path to the node. | |
674 | * @param event | |
675 | * The current event | |
676 | * @param traceState | |
677 | * The current trace state | |
678 | * @param index | |
679 | * The corresponding index of the statistic | |
680 | * @param isType | |
681 | * The type of statistic (type or other) | |
682 | * @return The node. | |
683 | */ | |
684 | public StatisticsTreeNode getOrCreate(final FixedArray path, LttngEvent event, LttngTraceState traceState, int index, boolean isType) { | |
685 | StatisticsTreeNode current = get(path); | |
686 | if (current == null) { | |
687 | // We have to clone the path since the object for the path is | |
688 | // re-used for performance reasons! | |
689 | FixedArray newPath = (FixedArray) path.clone(); | |
690 | ||
691 | // Note that setting of the name is done here only when the node is | |
692 | // created (for performance reasons). | |
693 | String name = (isType) ? getTypeStatsName(event, traceState, index) : getOtherStatsName(event, traceState, index); | |
694 | registerName(path); | |
695 | current = new StatisticsTreeNode(newPath, this, name); | |
696 | put(newPath, current); | |
697 | } | |
698 | return current; | |
699 | } | |
700 | ||
701 | /** | |
702 | * <h4>Get the name to be displayed for other statistics than type | |
703 | * statistics</h4> | |
704 | * | |
705 | * @param event | |
706 | * The current event | |
707 | * @param traceState | |
708 | * The current trace state | |
709 | * @param The | |
710 | * corresponding index of the statistic | |
711 | * @return The name | |
712 | */ | |
713 | private String getOtherStatsName(LttngEvent event, LttngTraceState traceState, int index) { | |
714 | Long cpu = event.getCpuId(); | |
715 | LttngProcessState process = traceState.getRunning_process().get(cpu); | |
716 | ||
717 | switch (index) { | |
718 | case 0: | |
719 | return traceState.getContext().getTraceId(); | |
720 | case 1: | |
721 | return process.getState().getExec_mode().getInName(); | |
722 | case 2: | |
723 | return process.getState().getExec_submode(); | |
724 | case 3: | |
725 | return getProcessName(process); | |
726 | case 4: | |
727 | return String.valueOf(cpu); | |
728 | case 5: | |
729 | return process.getCurrent_function().toString(); | |
730 | case 6: | |
731 | return process.getState().getExec_mode().getInName(); | |
732 | case 7: | |
733 | return process.getState().getExec_submode(); | |
734 | case 8: | |
735 | return process.getState().getExec_mode().getInName(); | |
736 | case 9: | |
737 | return process.getState().getExec_submode(); | |
738 | case 10: | |
739 | return process.getState().getExec_mode().getInName(); | |
740 | case 11: | |
741 | return process.getState().getExec_submode(); | |
742 | case 12: | |
743 | return String.valueOf(cpu); | |
744 | case 13: | |
745 | return process.getState().getExec_mode().getInName(); | |
746 | case 14: | |
747 | return process.getState().getExec_submode(); | |
748 | default: | |
749 | return ""; //$NON-NLS-1$ | |
750 | } | |
751 | } | |
752 | ||
753 | /** | |
754 | * <h4>Get the name to be displayed for type statistics</h4> | |
755 | * | |
756 | * @param event | |
757 | * The current event | |
758 | * @param traceState | |
759 | * The current state | |
760 | * @param index | |
761 | * The corresponding index of the statistic | |
762 | * @return The strings in a array | |
763 | */ | |
764 | private String getTypeStatsName(LttngEvent event, LttngTraceState traceState, int index) { | |
765 | return event.getMarkerName(); | |
766 | } | |
767 | ||
768 | /** | |
769 | * <h4>Get the name of a process.</h4> | |
770 | * | |
771 | * @param process | |
772 | * The process. | |
773 | * @return The name of the process. //TODO Adding the creation time of the | |
774 | * process may be needed to differentiate two process. | |
775 | */ | |
776 | private String getProcessName(LttngProcessState process) { | |
777 | if (process.getPid() == -1) | |
778 | return Messages.StatisticsData_UnknowProcess; | |
779 | if (process.getName() == null) | |
780 | return mergeString(Messages.StatisticsData_UnknowProcess + " - ", String.valueOf(process.getPid())); //$NON-NLS-1$ | |
781 | if (process.getName().equals("")) //$NON-NLS-1$ | |
782 | return process.getPid().toString(); | |
783 | else | |
784 | return mergeString(process.getName(), " - ", String.valueOf(process.getPid())); //$NON-NLS-1$ | |
785 | } | |
786 | ||
787 | /** | |
788 | * <h4>Converts the integer representation of the category to string.</h4> | |
789 | * | |
790 | * @param value | |
791 | * Integer representation of the category. | |
792 | * @return Category as string. | |
793 | */ | |
794 | public static String getCategoryFromId(int value) { | |
795 | switch (value) { | |
796 | case KernelStatisticsData.HEADER_CPUS_INT: | |
797 | return KernelStatisticsData.HEADER_CPUS; | |
798 | case KernelStatisticsData.HEADER_EVENT_TYPES_INT: | |
799 | return KernelStatisticsData.HEADER_EVENT_TYPES; | |
800 | case KernelStatisticsData.HEADER_FUNCTIONS_INT: | |
801 | return KernelStatisticsData.HEADER_FUNCTIONS; | |
802 | case KernelStatisticsData.HEADER_MODES_INT: | |
803 | return KernelStatisticsData.HEADER_MODES; | |
804 | case KernelStatisticsData.HEADER_PROCESSES_INT: | |
805 | return KernelStatisticsData.HEADER_PROCESSES; | |
806 | case KernelStatisticsData.HEADER_SUBMODES_INT: | |
807 | return KernelStatisticsData.HEADER_SUBMODES; | |
808 | } | |
809 | return ""; //$NON-NLS-1$ | |
a2e53983 | 810 | } |
9dbeec54 | 811 | |
b12f4544 FC |
812 | /** |
813 | * <h4>Provides unique keys for String - Integer pairs.</h4> | |
814 | * | |
815 | * @author eedbhu | |
816 | * | |
817 | */ | |
818 | final private class KeyProvider { | |
819 | ||
820 | /** | |
821 | * <h4>Instance counter for unique ID generation.</h4> | |
822 | */ | |
823 | private int fCount = 0; | |
824 | ||
825 | /** | |
826 | * <h4>Attributes to generate unique IDs for processes.</h4> | |
827 | */ | |
828 | private HashMap<KeyHelper, Integer> fKeyMap = new HashMap<KeyHelper, Integer>(65535); | |
829 | private final KeyHelper fHelper = new KeyHelper(); | |
830 | ||
831 | /** | |
832 | * <h4>Bit mask to apply for the key.</h4> | |
833 | */ | |
834 | private int fBitMask = 0; | |
835 | ||
836 | /** | |
837 | * Constructor | |
838 | * | |
839 | * @param bitMask | |
840 | * <h4>Bit mask to apply for the key.</h4> | |
841 | */ | |
842 | KeyProvider(int bitMask) { | |
843 | this.fBitMask = bitMask; | |
844 | } | |
845 | ||
846 | /** | |
847 | * <h4>Standard Constructor</h4> | |
848 | */ | |
849 | KeyProvider() { | |
850 | this(0); | |
851 | } | |
852 | ||
853 | /** | |
854 | * <h4>Creates unique id for the given input data.</h4> | |
855 | * | |
856 | * @param value | |
857 | * Integer value of the data the key is for | |
858 | * @param name | |
859 | * Name of the data the key is for | |
860 | * @param helper | |
861 | * Helper class instance for the data the key is for | |
862 | * @param map | |
863 | * The map the keys are tracked | |
864 | * @param bitMask | |
865 | * The bit mask to apply for the key | |
866 | * | |
867 | * @return Unique id | |
868 | */ | |
869 | public int getUniqueId(int value, String name) { | |
870 | fHelper.setName(name); | |
871 | fHelper.setValue(value); | |
872 | ||
873 | Integer returnKey = fKeyMap.get(fHelper); | |
874 | if (returnKey == null) { | |
875 | returnKey = Integer.valueOf((++fCount) | fBitMask); | |
876 | KeyHelper newHelper = fHelper.clone(); | |
877 | fKeyMap.put(newHelper, returnKey); | |
878 | } | |
879 | return returnKey.intValue(); | |
880 | } | |
881 | } | |
882 | ||
883 | /** | |
884 | * Helper class that provides for keys for HashMaps depending on an integer | |
885 | * - string -pair. It provides better performance than using a string as key | |
886 | * only. However, for optimal performance the integer values should mostly | |
887 | * unique. | |
888 | * | |
889 | * @author eedbhu | |
890 | * | |
891 | */ | |
892 | private class KeyHelper implements Cloneable { | |
893 | ||
894 | // Short pre-fix | |
895 | private final static String UNKNOWN_PREFIX = "P"; //$NON-NLS-1$ | |
896 | ||
897 | private String fName = UNKNOWN_PREFIX; | |
898 | private int fValue = -1; | |
899 | ||
900 | /* | |
901 | * (non-Javadoc) | |
902 | * | |
903 | * @see java.lang.Object#hashCode() | |
904 | */ | |
905 | @Override | |
906 | public int hashCode() { | |
907 | return fValue; | |
908 | } | |
909 | ||
910 | /* | |
911 | * (non-Javadoc) | |
912 | * | |
913 | * @see java.lang.Object#equals(java.lang.Object) | |
914 | */ | |
915 | @Override | |
916 | public boolean equals(Object o) { | |
917 | if (fValue == ((KeyHelper) o).fValue && fName.equals(((KeyHelper) o).fName)) { | |
918 | return true; | |
919 | } | |
920 | return false; | |
921 | } | |
922 | ||
923 | /* | |
924 | * (non-Javadoc) | |
925 | * | |
926 | * @see java.lang.Object#clone() | |
927 | */ | |
928 | @Override | |
929 | public KeyHelper clone() { | |
930 | KeyHelper clone = null; | |
931 | try { | |
932 | clone = (KeyHelper) super.clone(); | |
933 | clone.fName = fName; | |
934 | clone.fValue = fValue; | |
935 | } catch (CloneNotSupportedException e) { | |
936 | e.printStackTrace(); | |
937 | } | |
938 | return clone; | |
939 | } | |
940 | ||
941 | /** | |
942 | * <h4>Set the name of the key.</h4> | |
943 | * | |
944 | * @param name | |
945 | * The name to set. | |
946 | */ | |
947 | public void setName(String name) { | |
948 | if (fName != null) | |
949 | this.fName = name; | |
950 | else | |
951 | this.fName = UNKNOWN_PREFIX; | |
952 | } | |
953 | ||
954 | /** | |
955 | * <h4>Set the value of the key.</h4> | |
956 | * | |
957 | * @param value | |
958 | */ | |
959 | public void setValue(int value) { | |
960 | this.fValue = value; | |
961 | } | |
962 | } | |
963 | } |