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