Fix references to linuxtools in comments, examples and unused code
[deliverable/tracecompass.git] / org.eclipse.tracecompass.statesystem.core / src / org / eclipse / tracecompass / statesystem / core / backend / historytree / HistoryTreeBackend.java
CommitLineData
a52fde77 1/*******************************************************************************
60ae41e1 2 * Copyright (c) 2012, 2014 Ericsson
a52fde77
AM
3 * Copyright (c) 2010, 2011 École Polytechnique de Montréal
4 * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
5df842b3 5 *
a52fde77
AM
6 * All rights reserved. This program and the accompanying materials are
7 * made available under the terms of the Eclipse Public License v1.0 which
8 * accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
5df842b3 10 *
a52fde77
AM
11 *******************************************************************************/
12
e894a508 13package org.eclipse.tracecompass.statesystem.core.backend.historytree;
a52fde77
AM
14
15import java.io.File;
16import java.io.FileInputStream;
17import java.io.IOException;
18import java.io.PrintWriter;
3b7f5abe 19import java.nio.channels.ClosedChannelException;
a52fde77
AM
20import java.util.List;
21
b2f62cb5 22import org.eclipse.jdt.annotation.NonNull;
e894a508
AM
23import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.CoreNode;
24import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTConfig;
25import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTInterval;
26import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTNode;
27import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HistoryTree;
28import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
29import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
30import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
31import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
32import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
33import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
a52fde77
AM
34
35/**
36 * History Tree backend for storing a state history. This is the basic version
37 * that runs in the same thread as the class creating it.
5df842b3 38 *
360f899e 39 * @author Alexandre Montplaisir
a52fde77
AM
40 */
41public class HistoryTreeBackend implements IStateHistoryBackend {
42
b2f62cb5
AM
43 private final @NonNull String ssid;
44
bcec0116
AM
45 /**
46 * The history tree that sits underneath.
bcec0116 47 */
e62a23a9 48 private final HistoryTree sht;
6f4e8ec0 49
1a4205d9 50 /** Indicates if the history tree construction is done */
d740e018
MK
51 private volatile boolean fFinishedBuilding = false;
52
53 /**
54 * Indicates if the history tree construction is done
55 *
56 * @return if the history tree construction is done
dbc7991d 57 * @since 1.0
d740e018
MK
58 */
59 protected boolean isFinishedBuilding() {
60 return fFinishedBuilding;
61 }
62
63 /**
64 * Sets if the history tree is finished building
65 *
66 * @param isFinishedBuilding
67 * is the history tree finished building
dbc7991d 68 * @since 1.0
d740e018
MK
69 */
70 protected void setFinishedBuilding(boolean isFinishedBuilding) {
71 this.fFinishedBuilding = isFinishedBuilding;
72 }
1a4205d9 73
a52fde77 74 /**
7453b40e 75 * Constructor for new history files. Use this when creating a new history
a52fde77 76 * from scratch.
5df842b3 77 *
b2f62cb5
AM
78 * @param ssid
79 * The state system's ID
a52fde77
AM
80 * @param newStateFile
81 * The filename/location where to store the state history (Should
82 * end in .ht)
83 * @param blockSize
84 * The size of the blocks in the history file. This should be a
85 * multiple of 4096.
86 * @param maxChildren
87 * The maximum number of children each core node can have
a96cc6be
AM
88 * @param providerVersion
89 * Version of of the state provider. We will only try to reopen
90 * existing files if this version matches the one in the
91 * framework.
a52fde77
AM
92 * @param startTime
93 * The earliest time stamp that will be stored in the history
94 * @throws IOException
95 * Thrown if we can't create the file for some reason
dbc7991d 96 * @since 1.0
a52fde77 97 */
b2f62cb5 98 public HistoryTreeBackend(@NonNull String ssid, File newStateFile, int blockSize,
a96cc6be 99 int maxChildren, int providerVersion, long startTime) throws IOException {
b2f62cb5 100 this.ssid = ssid;
a96cc6be
AM
101 final HTConfig conf = new HTConfig(newStateFile, blockSize, maxChildren,
102 providerVersion, startTime);
7453b40e 103 sht = new HistoryTree(conf);
a52fde77
AM
104 }
105
106 /**
7453b40e 107 * Constructor for new history files. Use this when creating a new history
a52fde77
AM
108 * from scratch. This version supplies sane defaults for the configuration
109 * parameters.
5df842b3 110 *
b2f62cb5
AM
111 * @param ssid
112 * The state system's id
a52fde77
AM
113 * @param newStateFile
114 * The filename/location where to store the state history (Should
115 * end in .ht)
a96cc6be
AM
116 * @param providerVersion
117 * Version of of the state provider. We will only try to reopen
118 * existing files if this version matches the one in the
119 * framework.
a52fde77
AM
120 * @param startTime
121 * The earliest time stamp that will be stored in the history
122 * @throws IOException
123 * Thrown if we can't create the file for some reason
dbc7991d 124 * @since 1.0
a52fde77 125 */
b2f62cb5 126 public HistoryTreeBackend(@NonNull String ssid, File newStateFile, int providerVersion, long startTime)
a52fde77 127 throws IOException {
b2f62cb5 128 this(ssid, newStateFile, 64 * 1024, 50, providerVersion, startTime);
a52fde77
AM
129 }
130
131 /**
132 * Existing history constructor. Use this to open an existing state-file.
5df842b3 133 *
b2f62cb5
AM
134 * @param ssid
135 * The state system's id
0d9a6d76 136 * @param existingStateFile
b255ae4b 137 * Filename/location of the history we want to load
a96cc6be
AM
138 * @param providerVersion
139 * Expected version of of the state provider plugin.
b255ae4b 140 * @throws IOException
a96cc6be
AM
141 * If we can't read the file, if it doesn't exist, is not
142 * recognized, or if the version of the file does not match the
143 * expected providerVersion.
dbc7991d 144 * @since 1.0
a52fde77 145 */
b2f62cb5 146 public HistoryTreeBackend(@NonNull String ssid, File existingStateFile, int providerVersion)
a96cc6be 147 throws IOException {
b2f62cb5 148 this.ssid = ssid;
a96cc6be 149 sht = new HistoryTree(existingStateFile, providerVersion);
d740e018 150 fFinishedBuilding = true;
a52fde77
AM
151 }
152
e62a23a9
AM
153 /**
154 * Get the History Tree built by this backend.
155 *
156 * @return The history tree
157 */
158 protected HistoryTree getSHT() {
159 return sht;
160 }
161
dbc7991d
AM
162 /**
163 * @since 1.0
164 */
b2f62cb5
AM
165 @Override
166 public String getSSID() {
167 return ssid;
168 }
169
a52fde77
AM
170 @Override
171 public long getStartTime() {
172 return sht.getTreeStart();
173 }
174
175 @Override
176 public long getEndTime() {
177 return sht.getTreeEnd();
178 }
179
180 @Override
181 public void insertPastState(long stateStartTime, long stateEndTime,
182 int quark, ITmfStateValue value) throws TimeRangeException {
183 HTInterval interval = new HTInterval(stateStartTime, stateEndTime,
184 quark, (TmfStateValue) value);
185
186 /* Start insertions at the "latest leaf" */
187 sht.insertInterval(interval);
188 }
189
190 @Override
b33c7369 191 public void finishedBuilding(long endTime) {
6a1074ce 192 sht.closeTree(endTime);
d740e018 193 fFinishedBuilding = true;
a52fde77
AM
194 }
195
196 @Override
197 public FileInputStream supplyAttributeTreeReader() {
360f899e 198 return sht.supplyATReader();
a52fde77
AM
199 }
200
201 @Override
202 public File supplyAttributeTreeWriterFile() {
360f899e 203 return sht.supplyATWriterFile();
a52fde77
AM
204 }
205
206 @Override
207 public long supplyAttributeTreeWriterFilePosition() {
360f899e 208 return sht.supplyATWriterFilePos();
a52fde77
AM
209 }
210
36bf82a2
AM
211 @Override
212 public void removeFiles() {
360f899e 213 sht.deleteFile();
36bf82a2
AM
214 }
215
1a4205d9
AM
216 @Override
217 public void dispose() {
d740e018 218 if (fFinishedBuilding) {
360f899e 219 sht.closeFile();
1a4205d9
AM
220 } else {
221 /*
222 * The build is being interrupted, delete the file we partially
223 * built since it won't be complete, so shouldn't be re-used in the
224 * future (.deleteFile() will close the file first)
225 */
360f899e 226 sht.deleteFile();
1a4205d9
AM
227 }
228 }
229
a52fde77
AM
230 @Override
231 public void doQuery(List<ITmfStateInterval> stateInfo, long t)
3b7f5abe 232 throws TimeRangeException, StateSystemDisposedException {
a52fde77
AM
233 if (!checkValidTime(t)) {
234 /* We can't possibly have information about this query */
235 throw new TimeRangeException();
236 }
237
238 /* We start by reading the information in the root node */
bb7f92ce 239 HTNode currentNode = sht.getRootNode();
a52fde77
AM
240 currentNode.writeInfoFromNode(stateInfo, t);
241
242 /* Then we follow the branch down in the relevant children */
3b7f5abe 243 try {
bb7f92ce
FW
244 while (currentNode.getNodeType() == HTNode.NodeType.CORE) {
245 currentNode = sht.selectNextChild((CoreNode) currentNode, t);
3b7f5abe
AM
246 currentNode.writeInfoFromNode(stateInfo, t);
247 }
248 } catch (ClosedChannelException e) {
cb42195c 249 throw new StateSystemDisposedException(e);
a52fde77
AM
250 }
251
252 /*
253 * The stateInfo should now be filled with everything needed, we pass
254 * the control back to the State System.
255 */
256 return;
257 }
258
259 @Override
260 public ITmfStateInterval doSingularQuery(long t, int attributeQuark)
3b7f5abe 261 throws TimeRangeException, StateSystemDisposedException {
a52fde77
AM
262 return getRelevantInterval(t, attributeQuark);
263 }
264
0d26a9d0 265 private boolean checkValidTime(long t) {
a52fde77
AM
266 return (t >= sht.getTreeStart() && t <= sht.getTreeEnd());
267 }
268
269 /**
270 * Inner method to find the interval in the tree containing the requested
271 * key/timestamp pair, wherever in which node it is.
5df842b3 272 *
a52fde77
AM
273 * @param t
274 * @param key
275 * @return The node containing the information we want
276 */
277 private HTInterval getRelevantInterval(long t, int key)
3b7f5abe 278 throws TimeRangeException, StateSystemDisposedException {
a52fde77
AM
279 if (!checkValidTime(t)) {
280 throw new TimeRangeException();
281 }
282
bb7f92ce 283 HTNode currentNode = sht.getRootNode();
a52fde77
AM
284 HTInterval interval = currentNode.getRelevantInterval(key, t);
285
3b7f5abe 286 try {
bb7f92ce 287 while (interval == null && currentNode.getNodeType() == HTNode.NodeType.CORE) {
d740e018 288 currentNode = sht.selectNextChild((CoreNode) currentNode, t);
3b7f5abe
AM
289 interval = currentNode.getRelevantInterval(key, t);
290 }
291 } catch (ClosedChannelException e) {
cb42195c 292 throw new StateSystemDisposedException(e);
a52fde77 293 }
a52fde77
AM
294 return interval;
295 }
296
297 /**
298 * Return the size of the tree history file
5df842b3 299 *
a52fde77
AM
300 * @return The current size of the history file in bytes
301 */
302 public long getFileSize() {
303 return sht.getFileSize();
304 }
305
a52fde77
AM
306 /**
307 * Return the average node usage as a percentage (between 0 and 100)
5df842b3 308 *
a52fde77
AM
309 * @return Average node usage %
310 */
311 public int getAverageNodeUsage() {
312 HTNode node;
313 long total = 0;
314 long ret;
315
3b7f5abe
AM
316 try {
317 for (int seq = 0; seq < sht.getNodeCount(); seq++) {
360f899e 318 node = sht.readNode(seq);
8d47cc34 319 total += node.getNodeUsagePercent();
3b7f5abe
AM
320 }
321 } catch (ClosedChannelException e) {
322 e.printStackTrace();
a52fde77
AM
323 }
324
325 ret = total / sht.getNodeCount();
326 assert (ret >= 0 && ret <= 100);
327 return (int) ret;
328 }
329
330 @Override
331 public void debugPrint(PrintWriter writer) {
332 /* By default don't print out all the intervals */
333 this.debugPrint(writer, false);
334 }
335
336 /**
b255ae4b
AM
337 * The basic debugPrint method will print the tree structure, but not their
338 * contents.
5df842b3 339 *
a52fde77 340 * This method here print the contents (the intervals) as well.
5df842b3 341 *
a52fde77 342 * @param writer
5df842b3 343 * The PrintWriter to which the debug info will be written
a52fde77 344 * @param printIntervals
5df842b3 345 * Should we also print every contained interval individually?
a52fde77
AM
346 */
347 public void debugPrint(PrintWriter writer, boolean printIntervals) {
348 /* Only used for debugging, shouldn't be externalized */
349 writer.println("------------------------------"); //$NON-NLS-1$
350 writer.println("State History Tree:\n"); //$NON-NLS-1$
351 writer.println(sht.toString());
352 writer.println("Average node utilization: " //$NON-NLS-1$
353 + this.getAverageNodeUsage());
354 writer.println(""); //$NON-NLS-1$
355
356 sht.debugPrintFullTree(writer, printIntervals);
357 }
358}
This page took 0.078465 seconds and 5 git commands to generate.