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>
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
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.internal
.tmf
.core
.statesystem
.historytree
;
16 import java
.io
.FileInputStream
;
17 import java
.io
.IOException
;
18 import java
.io
.PrintWriter
;
19 import java
.util
.List
;
21 import org
.eclipse
.linuxtools
.internal
.tmf
.core
.statesystem
.IStateHistoryBackend
;
22 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.TimeRangeException
;
23 import org
.eclipse
.linuxtools
.tmf
.core
.interval
.ITmfStateInterval
;
24 import org
.eclipse
.linuxtools
.tmf
.core
.statevalue
.ITmfStateValue
;
25 import org
.eclipse
.linuxtools
.tmf
.core
.statevalue
.TmfStateValue
;
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.
34 public class HistoryTreeBackend
implements IStateHistoryBackend
{
36 protected final HistoryTree sht
;
37 private final HT_IO treeIO
;
39 /** Indicates if the history tree construction is done */
40 protected boolean isFinishedBuilding
= false;
43 * Construtor for new history files. Use this when creating a new history
47 * The filename/location where to store the state history (Should
50 * The size of the blocks in the history file. This should be a
53 * The maximum number of children each core node can have
55 * The earliest time stamp that will be stored in the history
57 * Thrown if we can't create the file for some reason
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();
66 * Construtor for new history files. Use this when creating a new history
67 * from scratch. This version supplies sane defaults for the configuration
71 * The filename/location where to store the state history (Should
74 * The earliest time stamp that will be stored in the history
76 * Thrown if we can't create the file for some reason
78 public HistoryTreeBackend(File newStateFile
, long startTime
)
80 this(newStateFile
, 64 * 1024, 50, startTime
);
84 * Existing history constructor. Use this to open an existing state-file.
86 * @param existingStateFile
87 * Filename/location of the history we want to load
89 * If we can't read the file, if it doesn't exist or is not
92 public HistoryTreeBackend(File existingStateFile
) throws IOException
{
93 sht
= new HistoryTree(existingStateFile
);
94 treeIO
= sht
.getTreeIO();
95 isFinishedBuilding
= true;
99 public long getStartTime() {
100 return sht
.getTreeStart();
104 public long getEndTime() {
105 return sht
.getTreeEnd();
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
);
114 /* Start insertions at the "latest leaf" */
115 sht
.insertInterval(interval
);
119 public void finishedBuilding(long endTime
) {
120 sht
.closeTree(endTime
);
121 isFinishedBuilding
= true;
125 public FileInputStream
supplyAttributeTreeReader() {
126 return treeIO
.supplyATReader();
130 public File
supplyAttributeTreeWriterFile() {
131 return treeIO
.supplyATWriterFile();
135 public long supplyAttributeTreeWriterFilePosition() {
136 return treeIO
.supplyATWriterFilePos();
140 public void removeFiles() {
145 public void dispose() {
146 if (isFinishedBuilding
) {
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)
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();
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
);
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
);
179 * The stateInfo should now be filled with everything needed, we pass
180 * the control back to the State System.
186 public ITmfStateInterval
doSingularQuery(long t
, int attributeQuark
)
187 throws TimeRangeException
{
188 return getRelevantInterval(t
, attributeQuark
);
192 public boolean checkValidTime(long t
) {
193 return (t
>= sht
.getTreeStart() && t
<= sht
.getTreeEnd());
197 * Inner method to find the interval in the tree containing the requested
198 * key/timestamp pair, wherever in which node it is.
202 * @return The node containing the information we want
204 private HTInterval
getRelevantInterval(long t
, int key
)
205 throws TimeRangeException
{
206 if (!checkValidTime(t
)) {
207 throw new TimeRangeException();
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
);
215 while (interval
== null && currentNode
.getNbChildren() > 0) {
216 currentNode
= (CoreNode
) sht
.selectNextChild(currentNode
, t
);
217 interval
= currentNode
.getRelevantInterval(key
, t
);
220 * Since we should now have intervals at every attribute/timestamp
221 * combination, it should NOT be null here.
223 assert (interval
!= null);
228 * Return the size of the tree history file
230 * @return The current size of the history file in bytes
232 public long getFileSize() {
233 return sht
.getFileSize();
237 * Return the current depth of the tree, ie the number of node levels.
239 * @return The tree depth
241 public int getTreeDepth() {
242 return sht
.latestBranch
.size();
246 * Return the average node usage as a percentage (between 0 and 100)
248 * @return Average node usage %
250 public int getAverageNodeUsage() {
255 for (int seq
= 0; seq
< sht
.getNodeCount(); seq
++) {
256 node
= treeIO
.readNode(seq
);
257 total
+= node
.getNodeUsagePRC();
260 ret
= total
/ sht
.getNodeCount();
261 assert (ret
>= 0 && ret
<= 100);
266 public void debugPrint(PrintWriter writer
) {
267 /* By default don't print out all the intervals */
268 this.debugPrint(writer
, false);
272 * The basic debugPrint method will print the tree structure, but not their
275 * This method here print the contents (the intervals) as well.
278 * The PrintWriter to which the debug info will be written
279 * @param printIntervals
280 * Should we also print every contained interval individually?
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$
291 sht
.debugPrintFullTree(writer
, printIntervals
);
This page took 0.038111 seconds and 5 git commands to generate.