tmf: Update comments in HistoryTree
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / internal / tmf / core / statesystem / backends / historytree / HistoryTreeBackend.java
CommitLineData
a52fde77
AM
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>
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
f9a76cac 13package org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.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
f9a76cac 22import org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.IStateHistoryBackend;
3b7f5abe 23import org.eclipse.linuxtools.tmf.core.exceptions.StateSystemDisposedException;
6d08acca 24import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
a52fde77 25import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval;
a52fde77
AM
26import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
27import 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.
5df842b3 32 *
a52fde77 33 * @author alexmont
5df842b3 34 *
a52fde77
AM
35 */
36public class HistoryTreeBackend implements IStateHistoryBackend {
37
6f4e8ec0 38 /** The history tree that sits underneath */
a52fde77 39 protected final HistoryTree sht;
6f4e8ec0
AM
40
41 /** Direct reference to the tree's IO object */
a52fde77
AM
42 private final HT_IO treeIO;
43
1a4205d9
AM
44 /** Indicates if the history tree construction is done */
45 protected boolean isFinishedBuilding = false;
46
a52fde77
AM
47 /**
48 * Construtor for new history files. Use this when creating a new history
49 * from scratch.
5df842b3 50 *
a52fde77
AM
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.
5df842b3 74 *
a52fde77
AM
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.
5df842b3 90 *
0d9a6d76 91 * @param existingStateFile
b255ae4b
AM
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
a52fde77
AM
96 */
97 public HistoryTreeBackend(File existingStateFile) throws IOException {
98 sht = new HistoryTree(existingStateFile);
99 treeIO = sht.getTreeIO();
1a4205d9 100 isFinishedBuilding = true;
a52fde77
AM
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
b33c7369 124 public void finishedBuilding(long endTime) {
6a1074ce 125 sht.closeTree(endTime);
1a4205d9 126 isFinishedBuilding = true;
a52fde77
AM
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
36bf82a2
AM
144 @Override
145 public void removeFiles() {
146 treeIO.deleteFile();
147 }
148
1a4205d9
AM
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
a52fde77
AM
163 @Override
164 public void doQuery(List<ITmfStateInterval> stateInfo, long t)
3b7f5abe 165 throws TimeRangeException, StateSystemDisposedException {
a52fde77
AM
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 */
3b7f5abe
AM
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();
a52fde77
AM
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)
3b7f5abe 196 throws TimeRangeException, StateSystemDisposedException {
a52fde77
AM
197 return getRelevantInterval(t, attributeQuark);
198 }
199
b255ae4b
AM
200 @Override
201 public boolean checkValidTime(long t) {
a52fde77
AM
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.
5df842b3 208 *
a52fde77
AM
209 * @param t
210 * @param key
211 * @return The node containing the information we want
212 */
213 private HTInterval getRelevantInterval(long t, int key)
3b7f5abe 214 throws TimeRangeException, StateSystemDisposedException {
a52fde77
AM
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
3b7f5abe
AM
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();
a52fde77
AM
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
5df842b3 242 *
a52fde77
AM
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.
5df842b3 251 *
a52fde77
AM
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)
5df842b3 260 *
a52fde77
AM
261 * @return Average node usage %
262 */
263 public int getAverageNodeUsage() {
264 HTNode node;
265 long total = 0;
266 long ret;
267
3b7f5abe
AM
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();
a52fde77
AM
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 /**
b255ae4b
AM
289 * The basic debugPrint method will print the tree structure, but not their
290 * contents.
5df842b3 291 *
a52fde77 292 * This method here print the contents (the intervals) as well.
5df842b3 293 *
a52fde77 294 * @param writer
5df842b3 295 * The PrintWriter to which the debug info will be written
a52fde77 296 * @param printIntervals
5df842b3 297 * Should we also print every contained interval individually?
a52fde77
AM
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.048359 seconds and 5 git commands to generate.