Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/backends/historytree/HistoryTree.java')
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/backends/historytree/HistoryTree.java147
1 files changed, 106 insertions, 41 deletions
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/backends/historytree/HistoryTree.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/backends/historytree/HistoryTree.java
index 47c2ba1851..3072d83f21 100644
--- a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/backends/historytree/HistoryTree.java
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/backends/historytree/HistoryTree.java
@@ -1,13 +1,14 @@
/*******************************************************************************
- * Copyright (c) 2012, 2014 Ericsson
- * Copyright (c) 2010, 2011 École Polytechnique de Montréal
- * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
+ * Copyright (c) 2010, 2014 Ericsson, École Polytechnique de Montréal, and others
*
* 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
*
+ * Contributors:
+ * Alexandre Montplaisir - Initial API and implementation
+ * Florian Wininger - Add Extension and Leaf Node
*******************************************************************************/
package org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.historytree;
@@ -24,6 +25,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import org.eclipse.linuxtools.internal.tmf.core.Activator;
import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateProvider;
@@ -45,7 +47,7 @@ public class HistoryTree {
private static final int HISTORY_FILE_MAGIC_NUMBER = 0x05FFA900;
/** File format version. Increment when breaking compatibility. */
- private static final int FILE_VERSION = 3;
+ private static final int FILE_VERSION = 4;
// ------------------------------------------------------------------------
// Tree-specific configuration
@@ -68,7 +70,7 @@ public class HistoryTree {
private int nodeCount;
/** "Cache" to keep the active nodes in memory */
- private final List<CoreNode> latestBranch;
+ private final List<HTNode> latestBranch;
// ------------------------------------------------------------------------
// Constructors/"Destructors"
@@ -86,8 +88,8 @@ public class HistoryTree {
*/
public HistoryTree(HTConfig conf) throws IOException {
/*
- * Simple check to make sure we have enough place in the 0th block
- * for the tree configuration
+ * Simple check to make sure we have enough place in the 0th block for
+ * the tree configuration
*/
if (conf.getBlockSize() < TREE_HEADER_SIZE) {
throw new IllegalArgumentException();
@@ -96,13 +98,13 @@ public class HistoryTree {
config = conf;
treeEnd = conf.getTreeStart();
nodeCount = 0;
- latestBranch = Collections.synchronizedList(new ArrayList<CoreNode>());
+ latestBranch = Collections.synchronizedList(new ArrayList<HTNode>());
/* Prepare the IO object */
treeIO = new HT_IO(config, true);
/* Add the first node to the tree */
- CoreNode firstNode = initNewCoreNode(-1, conf.getTreeStart());
+ LeafNode firstNode = initNewLeafNode(-1, conf.getTreeStart());
latestBranch.add(firstNode);
}
@@ -211,16 +213,16 @@ public class HistoryTree {
* start
* @throws ClosedChannelException
*/
- private List<CoreNode> buildLatestBranch(int rootNodeSeqNb) throws ClosedChannelException {
- HTNode nextChildNode;
+ private List<HTNode> buildLatestBranch(int rootNodeSeqNb) throws ClosedChannelException {
+ List<HTNode> list = new ArrayList<>();
- List<CoreNode> list = new ArrayList<>();
+ HTNode nextChildNode = treeIO.readNode(rootNodeSeqNb);
+ list.add(nextChildNode);
- nextChildNode = treeIO.readNode(rootNodeSeqNb);
- list.add((CoreNode) nextChildNode);
- while (list.get(list.size() - 1).getNbChildren() > 0) {
- nextChildNode = treeIO.readNode(list.get(list.size() - 1).getLatestChild());
- list.add((CoreNode) nextChildNode);
+ /* Follow the last branch up to the leaf */
+ while (nextChildNode.getNodeType() == HTNode.NodeType.CORE) {
+ nextChildNode = treeIO.readNode(((CoreNode) nextChildNode).getLatestChild());
+ list.add(nextChildNode);
}
return Collections.synchronizedList(list);
}
@@ -328,7 +330,7 @@ public class HistoryTree {
*
* @return The root node
*/
- public CoreNode getRootNode() {
+ public HTNode getRootNode() {
return latestBranch.get(0);
}
@@ -487,7 +489,13 @@ public class HistoryTree {
synchronized (latestBranch) {
final long splitTime = treeEnd;
- assert (indexOfNode < latestBranch.size());
+ if (indexOfNode >= latestBranch.size()) {
+ /*
+ * We need to make sure (indexOfNode - 1) doesn't get the last
+ * node in the branch, because that one is a Leaf Node.
+ */
+ throw new IllegalStateException();
+ }
/* Check if we need to add a new root node */
if (indexOfNode == 0) {
@@ -496,7 +504,7 @@ public class HistoryTree {
}
/* Check if we can indeed add a child to the target parent */
- if (latestBranch.get(indexOfNode - 1).getNbChildren() == config.getMaxChildren()) {
+ if (((CoreNode) latestBranch.get(indexOfNode - 1)).getNbChildren() == config.getMaxChildren()) {
/* If not, add a branch starting one level higher instead */
addSiblingNode(indexOfNode - 1);
return;
@@ -507,11 +515,21 @@ public class HistoryTree {
latestBranch.get(i).closeThisNode(splitTime);
treeIO.writeNode(latestBranch.get(i));
- CoreNode prevNode = latestBranch.get(i - 1);
- CoreNode newNode = initNewCoreNode(prevNode.getSequenceNumber(),
- splitTime + 1);
- prevNode.linkNewChild(newNode);
+ CoreNode prevNode = (CoreNode) latestBranch.get(i - 1);
+ HTNode newNode;
+
+ switch (latestBranch.get(i).getNodeType()) {
+ case CORE:
+ newNode = initNewCoreNode(prevNode.getSequenceNumber(), splitTime + 1);
+ break;
+ case LEAF:
+ newNode = initNewLeafNode(prevNode.getSequenceNumber(), splitTime + 1);
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ prevNode.linkNewChild(newNode);
latestBranch.set(i, newNode);
}
}
@@ -524,7 +542,7 @@ public class HistoryTree {
private void addNewRootNode() {
final long splitTime = this.treeEnd;
- CoreNode oldRootNode = latestBranch.get(0);
+ HTNode oldRootNode = latestBranch.get(0);
CoreNode newRootNode = initNewCoreNode(-1, config.getTreeStart());
/* Tell the old root node that it isn't root anymore */
@@ -544,17 +562,25 @@ public class HistoryTree {
int depth = latestBranch.size();
latestBranch.clear();
latestBranch.add(newRootNode);
+
+ // Create new coreNode
for (int i = 1; i < depth + 1; i++) {
- CoreNode prevNode = latestBranch.get(i - 1);
+ CoreNode prevNode = (CoreNode) latestBranch.get(i - 1);
CoreNode newNode = initNewCoreNode(prevNode.getParentSequenceNumber(),
splitTime + 1);
prevNode.linkNewChild(newNode);
latestBranch.add(newNode);
}
+
+ // Create the new leafNode
+ CoreNode prevNode = (CoreNode) latestBranch.get(depth);
+ LeafNode newNode = initNewLeafNode(prevNode.getParentSequenceNumber(), splitTime + 1);
+ prevNode.linkNewChild(newNode);
+ latestBranch.add(newNode);
}
/**
- * Add a new empty node to the tree.
+ * Add a new empty core node to the tree.
*
* @param parentSeqNumber
* Sequence number of this node's parent
@@ -575,6 +601,27 @@ public class HistoryTree {
}
/**
+ * Add a new empty leaf node to the tree.
+ *
+ * @param parentSeqNumber
+ * Sequence number of this node's parent
+ * @param startTime
+ * Start time of the new node
+ * @return The newly created node
+ */
+ private LeafNode initNewLeafNode(int parentSeqNumber, long startTime) {
+ LeafNode newNode = new LeafNode(config, this.nodeCount, parentSeqNumber,
+ startTime);
+ this.nodeCount++;
+
+ /* Update the treeEnd if needed */
+ if (startTime >= this.treeEnd) {
+ this.treeEnd = startTime + 1;
+ }
+ return newNode;
+ }
+
+ /**
* Inner method to select the next child of the current node intersecting
* the given timestamp. Useful for moving down the tree following one
* branch.
@@ -681,8 +728,8 @@ public class HistoryTree {
}
/*
- * Test that the childStartTimes[] array matches the real nodes' start
- * times
+ * 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));
@@ -745,26 +792,44 @@ public class HistoryTree {
/* Only used for debugging, shouldn't be externalized */
@SuppressWarnings("nls")
private void preOrderPrint(PrintWriter writer, boolean printIntervals,
- CoreNode currentNode, int curDepth) {
+ HTNode currentNode, int curDepth) {
writer.println(currentNode.toString());
if (printIntervals) {
currentNode.debugPrintIntervals(writer);
}
- try {
- for (int i = 0; i < currentNode.getNbChildren(); i++) {
- HTNode nextNode = treeIO.readNode(currentNode.getChild(i));
- assert (nextNode instanceof CoreNode); // TODO temporary
- for (int j = 0; j < curDepth; j++) {
- writer.print(" ");
+ switch (currentNode.getNodeType()) {
+ case LEAF:
+ /* Stop if it's the leaf node */
+ return;
+
+ case CORE:
+ try {
+ final CoreNode node = (CoreNode) currentNode;
+ /* Print the extensions, if any */
+ int extension = node.getExtensionSequenceNumber();
+ while (extension != -1) {
+ HTNode nextNode = treeIO.readNode(extension);
+ preOrderPrint(writer, printIntervals, nextNode, curDepth);
+ }
+
+ /* Print the child nodes */
+ for (int i = 0; i < node.getNbChildren(); i++) {
+ HTNode nextNode = treeIO.readNode(node.getChild(i));
+ for (int j = 0; j < curDepth; j++) {
+ writer.print(" ");
+ }
+ writer.print("+-");
+ preOrderPrint(writer, printIntervals, nextNode, curDepth + 1);
}
- writer.print("+-");
- preOrderPrint(writer, printIntervals, (CoreNode) nextNode,
- curDepth + 1);
+ } catch (ClosedChannelException e) {
+ Activator.logError(e.getMessage());
}
- } catch (ClosedChannelException e) {
- e.printStackTrace();
+ break;
+
+ default:
+ break;
}
}

Back to the top