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