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