* Copyright (c) 2012 Ericsson
* Copyright (c) 2010, 2011 École Polytechnique de Montréal
* Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
- *
+ *
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
- *
+ *
*******************************************************************************/
package org.eclipse.linuxtools.internal.tmf.core.statesystem.historytree;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
+import java.nio.channels.ClosedChannelException;
import java.nio.channels.FileChannel;
import java.util.Vector;
/**
* Meta-container for the History Tree. This structure contains all the
* high-level data relevant to the tree.
- *
+ *
* @author alexmont
- *
+ *
*/
class HistoryTree {
/**
* Create a new State History from scratch, using a SHTConfig object for
* configuration
- *
+ *
* @param conf
* @throws IOException
*/
/**
* "Reader" constructor : instantiate a SHTree from an existing tree file on
* disk
- *
+ *
* @param existingFileName
* Path/filename of the history-file we are to open
* @throws IOException
* commit all nodes to disk and then return the RandomAccessFile descriptor
* so the Tree object can save its configuration into the header of the
* file.
- *
+ *
* @param requestedEndTime
*/
void closeTree(long requestedEndTime) {
ByteBuffer buffer;
int i, res;
- /*
+ /*
* Work-around the "empty branches" that get created when the root node
* becomes full. Overwrite the tree's end time with the original wanted
* end-time, to ensure no queries are sent into those empty nodes.
- *
+ *
* This won't be needed once extended nodes are implemented.
*/
this.treeEnd = requestedEndTime;
* Rebuild the latestBranch "cache" object by reading the nodes from disk
* (When we are opening an existing file on disk and want to append to it,
* for example).
- *
+ *
* @param rootNodeSeqNb
* The sequence number of the root node, so we know where to
* start
+ * @throws ClosedChannelException
*/
- private void rebuildLatestBranch(int rootNodeSeqNb) {
+ private void rebuildLatestBranch(int rootNodeSeqNb) throws ClosedChannelException {
HTNode nextChildNode;
this.latestBranch = new Vector<CoreNode>();
/**
* Insert an interval in the tree
- *
+ *
* @param interval
*/
void insertInterval(HTInterval interval) throws TimeRangeException {
/**
* Inner method to find in which node we should add the interval.
- *
+ *
* @param interval
* The interval to add to the tree
* @param indexOfNode
/**
* Method to add a sibling to any node in the latest branch. This will add
* children back down to the leaf level, if needed.
- *
+ *
* @param indexOfNode
* The index in latestBranch where we start adding
*/
/**
* Add a new empty node to the tree.
- *
+ *
* @param parentSeqNumber
* Sequence number of this node's parent
* @param startTime
* Inner method to select the next child of the current node intersecting
* the given timestamp. Useful for moving down the tree following one
* branch.
- *
+ *
* @param currentNode
* @param t
* @return The child node intersecting t
+ * @throws ClosedChannelException
+ * If the file channel was closed while we were reading the tree
*/
- HTNode selectNextChild(CoreNode currentNode, long t) {
+ HTNode selectNextChild(CoreNode currentNode, long t) throws ClosedChannelException {
assert (currentNode.getNbChildren() > 0);
int potentialNextSeqNb = currentNode.getSequenceNumber();
return config.stateFile.length();
}
- /**
- * @name Test/debugging functions
- */
+ // ------------------------------------------------------------------------
+ // Test/debugging methods
+ // ------------------------------------------------------------------------
/* Only used for debugging, shouldn't be externalized */
@SuppressWarnings("nls")
node = (CoreNode) zenode;
- /*
- * Test that this node's start and end times match the start of the
- * first child and the end of the last child, respectively
- */
- if (node.getNbChildren() > 0) {
- otherNode = treeIO.readNode(node.getChild(0));
- if (node.getNodeStart() != otherNode.getNodeStart()) {
- buf.append("Start time of node (" + node.getNodeStart() + ") "
- + "does not match start time of first child " + "("
- + otherNode.getNodeStart() + "), " + "node #"
- + otherNode.getSequenceNumber() + ")\n");
- ret = false;
- }
- if (node.isDone()) {
- otherNode = treeIO.readNode(node.getLatestChild());
- if (node.getNodeEnd() != otherNode.getNodeEnd()) {
- buf.append("End time of node (" + node.getNodeEnd()
- + ") does not match end time of last child ("
- + otherNode.getNodeEnd() + ", node #"
+ try {
+ /*
+ * Test that this node's start and end times match the start of the
+ * first child and the end of the last child, respectively
+ */
+ if (node.getNbChildren() > 0) {
+ otherNode = treeIO.readNode(node.getChild(0));
+ if (node.getNodeStart() != otherNode.getNodeStart()) {
+ buf.append("Start time of node (" + node.getNodeStart() + ") "
+ + "does not match start time of first child " + "("
+ + otherNode.getNodeStart() + "), " + "node #"
+ otherNode.getSequenceNumber() + ")\n");
ret = false;
}
+ if (node.isDone()) {
+ otherNode = treeIO.readNode(node.getLatestChild());
+ if (node.getNodeEnd() != otherNode.getNodeEnd()) {
+ buf.append("End time of node (" + node.getNodeEnd()
+ + ") does not match end time of last child ("
+ + otherNode.getNodeEnd() + ", node #"
+ + otherNode.getSequenceNumber() + ")\n");
+ ret = false;
+ }
+ }
}
- }
- /*
- * Test that the childStartTimes[] array matches the real nodes' start
- * times
- */
- for (int i = 0; i < node.getNbChildren(); i++) {
- otherNode = treeIO.readNode(node.getChild(i));
- if (otherNode.getNodeStart() != node.getChildStart(i)) {
- buf.append(" Expected start time of child node #"
- + node.getChild(i) + ": " + node.getChildStart(i)
- + "\n" + " Actual start time of node #"
- + otherNode.getSequenceNumber() + ": "
- + otherNode.getNodeStart() + "\n");
- ret = false;
+ /*
+ * Test that the childStartTimes[] array matches the real nodes' start
+ * times
+ */
+ for (int i = 0; i < node.getNbChildren(); i++) {
+ otherNode = treeIO.readNode(node.getChild(i));
+ if (otherNode.getNodeStart() != node.getChildStart(i)) {
+ buf.append(" Expected start time of child node #"
+ + node.getChild(i) + ": " + node.getChildStart(i)
+ + "\n" + " Actual start time of node #"
+ + otherNode.getSequenceNumber() + ": "
+ + otherNode.getNodeStart() + "\n");
+ ret = false;
+ }
}
+
+ } catch (ClosedChannelException e) {
+ e.printStackTrace();
}
if (!ret) {
}
void checkIntegrity() {
- for (int i = 0; i < nodeCount; i++) {
- checkNodeIntegrity(treeIO.readNode(i));
+ try {
+ for (int i = 0; i < nodeCount; i++) {
+ checkNodeIntegrity(treeIO.readNode(i));
+ }
+ } catch (ClosedChannelException e) {
+ e.printStackTrace();
}
}
}
curDepth++;
- for (i = 0; i < currentNode.getNbChildren(); i++) {
- nextNode = treeIO.readNode(currentNode.getChild(i));
- assert (nextNode instanceof CoreNode); // TODO temporary
- for (j = 0; j < curDepth - 1; j++) {
- writer.print(" ");
+ try {
+ for (i = 0; i < currentNode.getNbChildren(); i++) {
+ nextNode = treeIO.readNode(currentNode.getChild(i));
+ assert (nextNode instanceof CoreNode); // TODO temporary
+ for (j = 0; j < curDepth - 1; j++) {
+ writer.print(" ");
+ }
+ writer.print("+-");
+ preOrderPrint(writer, printIntervals, (CoreNode) nextNode);
}
- writer.print("+-");
- preOrderPrint(writer, printIntervals, (CoreNode) nextNode);
+ } catch (ClosedChannelException e) {
+ e.printStackTrace();
}
curDepth--;
return;
/**
* Print out the full tree for debugging purposes
- *
+ *
* @param writer
* PrintWriter in which to write the output
* @param printIntervals