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