tmf/lttng: Fix newly-introduced Javadoc warnings
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / internal / tmf / core / statesystem / historytree / HistoryTreeBackend.java
1 /*******************************************************************************
2 * Copyright (c) 2012 Ericsson
3 * Copyright (c) 2010, 2011 École Polytechnique de Montréal
4 * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
5 *
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
10 *
11 *******************************************************************************/
12
13 package org.eclipse.linuxtools.internal.tmf.core.statesystem.historytree;
14
15 import java.io.File;
16 import java.io.FileInputStream;
17 import java.io.IOException;
18 import java.io.PrintWriter;
19 import java.nio.channels.ClosedChannelException;
20 import java.util.List;
21
22 import org.eclipse.linuxtools.internal.tmf.core.statesystem.IStateHistoryBackend;
23 import org.eclipse.linuxtools.tmf.core.exceptions.StateSystemDisposedException;
24 import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
25 import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval;
26 import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
27 import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue;
28
29 /**
30 * History Tree backend for storing a state history. This is the basic version
31 * that runs in the same thread as the class creating it.
32 *
33 * @author alexmont
34 *
35 */
36 public class HistoryTreeBackend implements IStateHistoryBackend {
37
38 /** The history tree that sits underneath */
39 protected final HistoryTree sht;
40
41 /** Direct reference to the tree's IO object */
42 private final HT_IO treeIO;
43
44 /** Indicates if the history tree construction is done */
45 protected boolean isFinishedBuilding = false;
46
47 /**
48 * Construtor for new history files. Use this when creating a new history
49 * from scratch.
50 *
51 * @param newStateFile
52 * The filename/location where to store the state history (Should
53 * end in .ht)
54 * @param blockSize
55 * The size of the blocks in the history file. This should be a
56 * multiple of 4096.
57 * @param maxChildren
58 * The maximum number of children each core node can have
59 * @param startTime
60 * The earliest time stamp that will be stored in the history
61 * @throws IOException
62 * Thrown if we can't create the file for some reason
63 */
64 public HistoryTreeBackend(File newStateFile, int blockSize,
65 int maxChildren, long startTime) throws IOException {
66 sht = new HistoryTree(newStateFile, blockSize, maxChildren, startTime);
67 treeIO = sht.getTreeIO();
68 }
69
70 /**
71 * Construtor for new history files. Use this when creating a new history
72 * from scratch. This version supplies sane defaults for the configuration
73 * parameters.
74 *
75 * @param newStateFile
76 * The filename/location where to store the state history (Should
77 * end in .ht)
78 * @param startTime
79 * The earliest time stamp that will be stored in the history
80 * @throws IOException
81 * Thrown if we can't create the file for some reason
82 */
83 public HistoryTreeBackend(File newStateFile, long startTime)
84 throws IOException {
85 this(newStateFile, 64 * 1024, 50, startTime);
86 }
87
88 /**
89 * Existing history constructor. Use this to open an existing state-file.
90 *
91 * @param existingStateFile
92 * Filename/location of the history we want to load
93 * @throws IOException
94 * If we can't read the file, if it doesn't exist or is not
95 * recognized
96 */
97 public HistoryTreeBackend(File existingStateFile) throws IOException {
98 sht = new HistoryTree(existingStateFile);
99 treeIO = sht.getTreeIO();
100 isFinishedBuilding = true;
101 }
102
103 @Override
104 public long getStartTime() {
105 return sht.getTreeStart();
106 }
107
108 @Override
109 public long getEndTime() {
110 return sht.getTreeEnd();
111 }
112
113 @Override
114 public void insertPastState(long stateStartTime, long stateEndTime,
115 int quark, ITmfStateValue value) throws TimeRangeException {
116 HTInterval interval = new HTInterval(stateStartTime, stateEndTime,
117 quark, (TmfStateValue) value);
118
119 /* Start insertions at the "latest leaf" */
120 sht.insertInterval(interval);
121 }
122
123 @Override
124 public void finishedBuilding(long endTime) {
125 sht.closeTree(endTime);
126 isFinishedBuilding = true;
127 }
128
129 @Override
130 public FileInputStream supplyAttributeTreeReader() {
131 return treeIO.supplyATReader();
132 }
133
134 @Override
135 public File supplyAttributeTreeWriterFile() {
136 return treeIO.supplyATWriterFile();
137 }
138
139 @Override
140 public long supplyAttributeTreeWriterFilePosition() {
141 return treeIO.supplyATWriterFilePos();
142 }
143
144 @Override
145 public void removeFiles() {
146 treeIO.deleteFile();
147 }
148
149 @Override
150 public void dispose() {
151 if (isFinishedBuilding) {
152 treeIO.closeFile();
153 } else {
154 /*
155 * The build is being interrupted, delete the file we partially
156 * built since it won't be complete, so shouldn't be re-used in the
157 * future (.deleteFile() will close the file first)
158 */
159 treeIO.deleteFile();
160 }
161 }
162
163 @Override
164 public void doQuery(List<ITmfStateInterval> stateInfo, long t)
165 throws TimeRangeException, StateSystemDisposedException {
166 if (!checkValidTime(t)) {
167 /* We can't possibly have information about this query */
168 throw new TimeRangeException();
169 }
170
171 /* We start by reading the information in the root node */
172 // FIXME using CoreNode for now, we'll have to redo this part to handle
173 // different node types
174 CoreNode currentNode = sht.latestBranch.firstElement();
175 currentNode.writeInfoFromNode(stateInfo, t);
176
177 /* Then we follow the branch down in the relevant children */
178 try {
179 while (currentNode.getNbChildren() > 0) {
180 currentNode = (CoreNode) sht.selectNextChild(currentNode, t);
181 currentNode.writeInfoFromNode(stateInfo, t);
182 }
183 } catch (ClosedChannelException e) {
184 throw new StateSystemDisposedException();
185 }
186
187 /*
188 * The stateInfo should now be filled with everything needed, we pass
189 * the control back to the State System.
190 */
191 return;
192 }
193
194 @Override
195 public ITmfStateInterval doSingularQuery(long t, int attributeQuark)
196 throws TimeRangeException, StateSystemDisposedException {
197 return getRelevantInterval(t, attributeQuark);
198 }
199
200 @Override
201 public boolean checkValidTime(long t) {
202 return (t >= sht.getTreeStart() && t <= sht.getTreeEnd());
203 }
204
205 /**
206 * Inner method to find the interval in the tree containing the requested
207 * key/timestamp pair, wherever in which node it is.
208 *
209 * @param t
210 * @param key
211 * @return The node containing the information we want
212 */
213 private HTInterval getRelevantInterval(long t, int key)
214 throws TimeRangeException, StateSystemDisposedException {
215 if (!checkValidTime(t)) {
216 throw new TimeRangeException();
217 }
218
219 // FIXME using CoreNode for now, we'll have to redo this part to handle
220 // different node types
221 CoreNode currentNode = sht.latestBranch.firstElement();
222 HTInterval interval = currentNode.getRelevantInterval(key, t);
223
224 try {
225 while (interval == null && currentNode.getNbChildren() > 0) {
226 currentNode = (CoreNode) sht.selectNextChild(currentNode, t);
227 interval = currentNode.getRelevantInterval(key, t);
228 }
229 } catch (ClosedChannelException e) {
230 throw new StateSystemDisposedException();
231 }
232 /*
233 * Since we should now have intervals at every attribute/timestamp
234 * combination, it should NOT be null here.
235 */
236 assert (interval != null);
237 return interval;
238 }
239
240 /**
241 * Return the size of the tree history file
242 *
243 * @return The current size of the history file in bytes
244 */
245 public long getFileSize() {
246 return sht.getFileSize();
247 }
248
249 /**
250 * Return the current depth of the tree, ie the number of node levels.
251 *
252 * @return The tree depth
253 */
254 public int getTreeDepth() {
255 return sht.latestBranch.size();
256 }
257
258 /**
259 * Return the average node usage as a percentage (between 0 and 100)
260 *
261 * @return Average node usage %
262 */
263 public int getAverageNodeUsage() {
264 HTNode node;
265 long total = 0;
266 long ret;
267
268 try {
269 for (int seq = 0; seq < sht.getNodeCount(); seq++) {
270 node = treeIO.readNode(seq);
271 total += node.getNodeUsagePRC();
272 }
273 } catch (ClosedChannelException e) {
274 e.printStackTrace();
275 }
276
277 ret = total / sht.getNodeCount();
278 assert (ret >= 0 && ret <= 100);
279 return (int) ret;
280 }
281
282 @Override
283 public void debugPrint(PrintWriter writer) {
284 /* By default don't print out all the intervals */
285 this.debugPrint(writer, false);
286 }
287
288 /**
289 * The basic debugPrint method will print the tree structure, but not their
290 * contents.
291 *
292 * This method here print the contents (the intervals) as well.
293 *
294 * @param writer
295 * The PrintWriter to which the debug info will be written
296 * @param printIntervals
297 * Should we also print every contained interval individually?
298 */
299 public void debugPrint(PrintWriter writer, boolean printIntervals) {
300 /* Only used for debugging, shouldn't be externalized */
301 writer.println("------------------------------"); //$NON-NLS-1$
302 writer.println("State History Tree:\n"); //$NON-NLS-1$
303 writer.println(sht.toString());
304 writer.println("Average node utilization: " //$NON-NLS-1$
305 + this.getAverageNodeUsage());
306 writer.println(""); //$NON-NLS-1$
307
308 sht.debugPrintFullTree(writer, printIntervals);
309 }
310 }
This page took 0.041628 seconds and 5 git commands to generate.