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