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