/*******************************************************************************
- * Copyright (c) 2010, 2015 Ericsson, École Polytechnique de Montréal, and others
+ * Copyright (c) 2010, 2016 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
import java.util.Collections;
import java.util.List;
+import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.internal.statesystem.core.Activator;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
+import com.google.common.collect.ImmutableList;
+
/**
* Meta-container for the History Tree. This structure contains all the
* high-level data relevant to the tree.
private static final int HISTORY_FILE_MAGIC_NUMBER = 0x05FFA900;
/** File format version. Increment when breaking compatibility. */
- private static final int FILE_VERSION = 5;
+ private static final int FILE_VERSION = 6;
// ------------------------------------------------------------------------
// Tree-specific configuration
private int fNodeCount;
/** "Cache" to keep the active nodes in memory */
- private final List<HTNode> fLatestBranch;
+ private final @NonNull List<@NonNull HTNode> fLatestBranch;
// ------------------------------------------------------------------------
// Constructors/"Destructors"
fConfig = conf;
fTreeEnd = conf.getTreeStart();
fNodeCount = 0;
- fLatestBranch = Collections.synchronizedList(new ArrayList<HTNode>());
+ fLatestBranch = Collections.synchronizedList(new ArrayList<>());
/* Prepare the IO object */
fTreeIO = new HT_IO(fConfig, true);
* start
* @throws ClosedChannelException
*/
- private List<HTNode> buildLatestBranch(int rootNodeSeqNb) throws ClosedChannelException {
- List<HTNode> list = new ArrayList<>();
+ private @NonNull List<@NonNull HTNode> buildLatestBranch(int rootNodeSeqNb) throws ClosedChannelException {
+ List<@NonNull HTNode> list = new ArrayList<>();
HTNode nextChildNode = fTreeIO.readNode(rootNodeSeqNb);
list.add(nextChildNode);
return fLatestBranch.get(0);
}
+ /**
+ * Return the latest branch of the tree. That branch is immutable. Used for
+ * unit testing and debugging.
+ *
+ * @return The immutable latest branch
+ */
+ protected List<@NonNull HTNode> getLatestBranch() {
+ return ImmutableList.copyOf(fLatestBranch);
+ }
+
// ------------------------------------------------------------------------
// HT_IO interface
// ------------------------------------------------------------------------
HTNode targetNode = fLatestBranch.get(indexOfNode);
/* Verify if there is enough room in this node to store this interval */
- if (interval.getIntervalSize() > targetNode.getNodeFreeSpace()) {
+ if (interval.getSizeOnDisk() > targetNode.getNodeFreeSpace()) {
/* Nope, not enough room. Insert in a new sibling instead. */
addSiblingNode(indexOfNode);
tryInsertAtNode(interval, fLatestBranch.size() - 1);
* No, this interval starts before the startTime of this node. We
* need to check recursively in parents if it can fit.
*/
- assert (indexOfNode >= 1);
tryInsertAtNode(interval, indexOfNode - 1);
return;
}
fLatestBranch.add(newRootNode);
// Create new coreNode
- for (int i = 1; i < depth + 1; i++) {
+ for (int i = 1; i < depth; i++) {
CoreNode prevNode = (CoreNode) fLatestBranch.get(i - 1);
- CoreNode newNode = initNewCoreNode(prevNode.getParentSequenceNumber(),
+ CoreNode newNode = initNewCoreNode(prevNode.getSequenceNumber(),
splitTime + 1);
prevNode.linkNewChild(newNode);
fLatestBranch.add(newNode);
}
// Create the new leafNode
- CoreNode prevNode = (CoreNode) fLatestBranch.get(depth);
- LeafNode newNode = initNewLeafNode(prevNode.getParentSequenceNumber(), splitTime + 1);
+ CoreNode prevNode = (CoreNode) fLatestBranch.get(depth - 1);
+ LeafNode newNode = initNewLeafNode(prevNode.getSequenceNumber(), splitTime + 1);
prevNode.linkNewChild(newNode);
fLatestBranch.add(newNode);
}
* Start time of the new node
* @return The newly created node
*/
- private CoreNode initNewCoreNode(int parentSeqNumber, long startTime) {
+ private @NonNull CoreNode initNewCoreNode(int parentSeqNumber, long startTime) {
CoreNode newNode = new CoreNode(fConfig, fNodeCount, parentSeqNumber,
startTime);
fNodeCount++;
-
- /* Update the treeEnd if needed */
- if (startTime >= fTreeEnd) {
- fTreeEnd = startTime + 1;
- }
return newNode;
}
* Start time of the new node
* @return The newly created node
*/
- private LeafNode initNewLeafNode(int parentSeqNumber, long startTime) {
+ private @NonNull LeafNode initNewLeafNode(int parentSeqNumber, long startTime) {
LeafNode newNode = new LeafNode(fConfig, fNodeCount, parentSeqNumber,
startTime);
fNodeCount++;
-
- /* Update the treeEnd if needed */
- if (startTime >= fTreeEnd) {
- fTreeEnd = startTime + 1;
- }
return newNode;
}
* Once we exit this loop, we should have found a children to follow. If
* we didn't, there's a problem.
*/
- assert (potentialNextSeqNb != currentNode.getSequenceNumber());
+ if (potentialNextSeqNb == currentNode.getSequenceNumber()) {
+ throw new IllegalStateException("No next child node found"); //$NON-NLS-1$
+ }
/*
* Since this code path is quite performance-critical, avoid iterating