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
.tmf
.core
.statesystem
.backend
.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
.tmf
.core
.interval
.ITmfStateInterval
;
22 import org
.eclipse
.linuxtools
.tmf
.core
.statesystem
.TimeRangeException
;
23 import org
.eclipse
.linuxtools
.tmf
.core
.statesystem
.helpers
.IStateHistoryBackend
;
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
;
40 * Construtor for new history files. Use this when creating a new history
44 * The filename/location where to store the state history (Should
47 * The size of the blocks in the history file. This should be a
50 * The maximum number of children each core node can have
52 * The earliest time stamp that will be stored in the history
54 * Thrown if we can't create the file for some reason
56 public HistoryTreeBackend(File newStateFile
, int blockSize
,
57 int maxChildren
, long startTime
) throws IOException
{
58 sht
= new HistoryTree(newStateFile
, blockSize
, maxChildren
, startTime
);
59 treeIO
= sht
.getTreeIO();
63 * Construtor for new history files. Use this when creating a new history
64 * from scratch. This version supplies sane defaults for the configuration
68 * The filename/location where to store the state history (Should
71 * The earliest time stamp that will be stored in the history
73 * Thrown if we can't create the file for some reason
75 public HistoryTreeBackend(File newStateFile
, long startTime
)
77 this(newStateFile
, 64 * 1024, 50, startTime
);
81 * Existing history constructor. Use this to open an existing state-file.
83 * @param existingFileName Filename/location of the history we want to load
84 * @throws IOException If we can't read the file, if it doesn't exist or is not recognized
86 public HistoryTreeBackend(File existingStateFile
) throws IOException
{
87 sht
= new HistoryTree(existingStateFile
);
88 treeIO
= sht
.getTreeIO();
92 public long getStartTime() {
93 return sht
.getTreeStart();
97 public long getEndTime() {
98 return sht
.getTreeEnd();
102 public void insertPastState(long stateStartTime
, long stateEndTime
,
103 int quark
, ITmfStateValue value
) throws TimeRangeException
{
104 HTInterval interval
= new HTInterval(stateStartTime
, stateEndTime
,
105 quark
, (TmfStateValue
) value
);
107 /* Start insertions at the "latest leaf" */
108 sht
.insertInterval(interval
);
112 public void finishedBuilding(long endTime
) throws TimeRangeException
{
117 public FileInputStream
supplyAttributeTreeReader() {
118 return treeIO
.supplyATReader();
122 public File
supplyAttributeTreeWriterFile() {
123 return treeIO
.supplyATWriterFile();
127 public long supplyAttributeTreeWriterFilePosition() {
128 return treeIO
.supplyATWriterFilePos();
132 public void doQuery(List
<ITmfStateInterval
> stateInfo
, long t
)
133 throws TimeRangeException
{
134 if (!checkValidTime(t
)) {
135 /* We can't possibly have information about this query */
136 throw new TimeRangeException();
139 /* We start by reading the information in the root node */
140 // FIXME using CoreNode for now, we'll have to redo this part to handle
141 // different node types
142 CoreNode currentNode
= sht
.latestBranch
.firstElement();
143 currentNode
.writeInfoFromNode(stateInfo
, t
);
145 /* Then we follow the branch down in the relevant children */
146 while (currentNode
.getNbChildren() > 0) {
147 currentNode
= (CoreNode
) sht
.selectNextChild(currentNode
, t
);
148 currentNode
.writeInfoFromNode(stateInfo
, t
);
152 * The stateInfo should now be filled with everything needed, we pass
153 * the control back to the State System.
159 public ITmfStateInterval
doSingularQuery(long t
, int attributeQuark
)
160 throws TimeRangeException
{
161 return getRelevantInterval(t
, attributeQuark
);
165 * Simple check to make sure the requested timestamps are within the borders
169 * The queried timestamp
170 * @return True if it's within range, false if not.
172 private boolean checkValidTime(long t
) {
173 return (t
>= sht
.getTreeStart() && t
<= sht
.getTreeEnd());
177 * Inner method to find the interval in the tree containing the requested
178 * key/timestamp pair, wherever in which node it is.
182 * @return The node containing the information we want
184 private HTInterval
getRelevantInterval(long t
, int key
)
185 throws TimeRangeException
{
186 if (!checkValidTime(t
)) {
187 throw new TimeRangeException();
190 // FIXME using CoreNode for now, we'll have to redo this part to handle
191 // different node types
192 CoreNode currentNode
= sht
.latestBranch
.firstElement();
193 HTInterval interval
= currentNode
.getRelevantInterval(key
, t
);
195 while (interval
== null && currentNode
.getNbChildren() > 0) {
196 currentNode
= (CoreNode
) sht
.selectNextChild(currentNode
, t
);
197 interval
= currentNode
.getRelevantInterval(key
, t
);
200 * Since we should now have intervals at every attribute/timestamp
201 * combination, it should NOT be null here.
203 assert (interval
!= null);
208 * Return the size of the tree history file
210 * @return The current size of the history file in bytes
212 public long getFileSize() {
213 return sht
.getFileSize();
217 * Return the current depth of the tree, ie the number of node levels.
219 * @return The tree depth
221 public int getTreeDepth() {
222 return sht
.latestBranch
.size();
226 * Return the average node usage as a percentage (between 0 and 100)
228 * @return Average node usage %
230 public int getAverageNodeUsage() {
235 for (int seq
= 0; seq
< sht
.getNodeCount(); seq
++) {
236 node
= treeIO
.readNode(seq
);
237 total
+= node
.getNodeUsagePRC();
240 ret
= total
/ sht
.getNodeCount();
241 assert (ret
>= 0 && ret
<= 100);
246 public void debugPrint(PrintWriter writer
) {
247 /* By default don't print out all the intervals */
248 this.debugPrint(writer
, false);
252 * The basic debugPrint method will print the tree structure, but not
255 * This method here print the contents (the intervals) as well.
258 * @param printIntervals
260 public void debugPrint(PrintWriter writer
, boolean printIntervals
) {
261 /* Only used for debugging, shouldn't be externalized */
262 writer
.println("------------------------------"); //$NON-NLS-1$
263 writer
.println("State History Tree:\n"); //$NON-NLS-1$
264 writer
.println(sht
.toString());
265 writer
.println("Average node utilization: " //$NON-NLS-1$
266 + this.getAverageNodeUsage());
267 writer
.println(""); //$NON-NLS-1$
269 sht
.debugPrintFullTree(writer
, printIntervals
);
This page took 0.038343 seconds and 5 git commands to generate.