From f4baf640acb2940d56ade46f42d7e5cbad0a598f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Genevi=C3=A8ve=20Bastien?= Date: Tue, 2 Aug 2016 09:43:08 -0400 Subject: [PATCH 1/1] ss: History trees can define their own node types MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This patch moves the HistoryTreeClassic to its own package and allows each history tree class to define their own HTNode types. Change-Id: I800469c12fbcaf21156ed340c94b611b59b70ea1 Signed-off-by: Geneviève Bastien Signed-off-by: Alexandre Montplaisir Reviewed-on: https://git.eclipse.org/r/78354 Reviewed-by: Hudson CI --- .../stubs/backend/HistoryTreeClassicStub.java | 13 +-- .../META-INF/MANIFEST.MF | 1 + .../core/backend/historytree/HTNode.java | 12 +-- .../core/backend/historytree/HT_IO.java | 12 ++- .../historytree/HistoryTreeBackend.java | 6 +- .../historytree/HistoryTreeFactory.java | 1 + .../backend/historytree/IHistoryTree.java | 48 ++++++++++- .../core/backend/historytree/ParentNode.java | 85 +++++++++++++++++++ .../historytree/{ => classic}/CoreNode.java | 46 ++++------ .../{ => classic}/HistoryTreeClassic.java | 50 +++++++---- 10 files changed, 211 insertions(+), 63 deletions(-) create mode 100644 statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/ParentNode.java rename statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/{ => classic}/CoreNode.java (88%) rename statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/{ => classic}/HistoryTreeClassic.java (91%) diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core.tests/stubs/org/eclipse/tracecompass/statesystem/core/tests/stubs/backend/HistoryTreeClassicStub.java b/statesystem/org.eclipse.tracecompass.statesystem.core.tests/stubs/org/eclipse/tracecompass/statesystem/core/tests/stubs/backend/HistoryTreeClassicStub.java index 49354ea7db..99a08f2156 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core.tests/stubs/org/eclipse/tracecompass/statesystem/core/tests/stubs/backend/HistoryTreeClassicStub.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core.tests/stubs/org/eclipse/tracecompass/statesystem/core/tests/stubs/backend/HistoryTreeClassicStub.java @@ -20,11 +20,13 @@ import java.io.PrintWriter; import java.nio.channels.ClosedChannelException; import java.util.List; -import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.CoreNode; +import org.eclipse.tracecompass.internal.statesystem.core.Activator; import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTConfig; import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTNode; -import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HistoryTreeClassic; import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.IHistoryTree; +import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.ParentNode; +import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.classic.CoreNode; +import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.classic.HistoryTreeClassic; import com.google.common.collect.Iterables; @@ -178,6 +180,7 @@ public class HistoryTreeClassicStub extends HistoryTreeClassic { preOrderPrint(writer, printIntervals, nextNode, curDepth + 1, ts); } } catch (ClosedChannelException e) { + Activator.getDefault().logError(e.getMessage()); } break; @@ -212,8 +215,8 @@ public class HistoryTreeClassicStub extends HistoryTreeClassic { * The node to check */ private void assertNodeIntegrity(HTNode node) { - if (node instanceof CoreNode) { - assertChildrenIntegrity((CoreNode) node); + if (node instanceof ParentNode) { + assertChildrenIntegrity((ParentNode) node); } /* Check that all intervals are within the node's range */ @@ -221,7 +224,7 @@ public class HistoryTreeClassicStub extends HistoryTreeClassic { } - private void assertChildrenIntegrity(CoreNode node) { + private void assertChildrenIntegrity(ParentNode node) { try { /* * Test that this node's start and end times match the start of the diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/META-INF/MANIFEST.MF b/statesystem/org.eclipse.tracecompass.statesystem.core/META-INF/MANIFEST.MF index 36b4ebb4f3..0404091143 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core/META-INF/MANIFEST.MF +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/META-INF/MANIFEST.MF @@ -15,6 +15,7 @@ Export-Package: org.eclipse.tracecompass.internal.provisional.statesystem.core.s org.eclipse.tracecompass.internal.statesystem.core;x-friends:="org.eclipse.tracecompass.statesystem.core.tests", org.eclipse.tracecompass.internal.statesystem.core.backend;x-internal:=true, org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;x-friends:="org.eclipse.tracecompass.statesystem.core.tests", + org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.classic;x-friends:="org.eclipse.tracecompass.statesystem.core.tests", org.eclipse.tracecompass.internal.statesystem.core.statevalue;x-friends:="org.eclipse.tracecompass.statesystem.core.tests", org.eclipse.tracecompass.statesystem.core, org.eclipse.tracecompass.statesystem.core.backend, diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HTNode.java b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HTNode.java index 9cb7b74572..9cada2d4f4 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HTNode.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HTNode.java @@ -168,11 +168,13 @@ public abstract class HTNode { * @param fc * FileChannel to the history file, ALREADY SEEKED at the start * of the node. + * @param nodeFactory + * The factory to create the nodes for this tree * @return The node object * @throws IOException * If there was an error reading from the file channel */ - public static final @NonNull HTNode readNode(HTConfig config, FileChannel fc) + public static final @NonNull HTNode readNode(HTConfig config, FileChannel fc, IHistoryTree.IHTNodeFactory nodeFactory) throws IOException { HTNode newNode = null; int res, i; @@ -198,13 +200,13 @@ public abstract class HTNode { switch (type) { case CORE: /* Core nodes */ - newNode = new CoreNode(config, seqNb, parentSeqNb, start); + newNode = nodeFactory.createCoreNode(config, seqNb, parentSeqNb, start); newNode.readSpecificHeader(buffer); break; case LEAF: /* Leaf nodes */ - newNode = new LeafNode(config, seqNb, parentSeqNb, start); + newNode = nodeFactory.createLeafNode(config, seqNb, parentSeqNb, start); newNode.readSpecificHeader(buffer); break; @@ -610,8 +612,8 @@ public abstract class HTNode { writer.println("Intervals for node #" + fSequenceNumber + ":"); /* Array of children */ - if (getNodeType() == NodeType.CORE) { /* Only Core Nodes can have children */ - CoreNode thisNode = (CoreNode) this; + if (getNodeType() != NodeType.LEAF) { /* Only Core Nodes can have children */ + ParentNode thisNode = (ParentNode) this; writer.print(" " + thisNode.getNbChildren() + " children"); if (thisNode.getNbChildren() >= 1) { writer.print(": [ " + thisNode.getChild(0)); diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HT_IO.java b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HT_IO.java index 25f7281518..b26225b733 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HT_IO.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HT_IO.java @@ -23,12 +23,13 @@ import java.nio.channels.FileChannel; import java.util.logging.Logger; import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.tracecompass.common.core.log.TraceCompassLog; import java.util.Objects; import java.util.concurrent.ExecutionException; import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.common.core.log.TraceCompassLog; import org.eclipse.tracecompass.internal.statesystem.core.Activator; +import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.IHistoryTree.IHTNodeFactory; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; @@ -100,7 +101,7 @@ public class HT_IO { synchronized (io) { io.seekFCToNodePos(io.fFileChannelIn, seqNb); - return HTNode.readNode(io.fConfig, io.fFileChannelIn); + return HTNode.readNode(io.fConfig, io.fFileChannelIn, key.fStateHistory.fNodeFactory); } } })); @@ -119,6 +120,8 @@ public class HT_IO { private final FileChannel fFileChannelIn; private final FileChannel fFileChannelOut; + private final IHTNodeFactory fNodeFactory; + // ------------------------------------------------------------------------ // Methods // ------------------------------------------------------------------------ @@ -132,11 +135,13 @@ public class HT_IO { * The configuration object for the StateHistoryTree * @param newFile * Flag indicating that the file must be created from scratch + * @param nodeFactory + * The factory to create new nodes for this tree * * @throws IOException * An exception can be thrown when file cannot be accessed */ - public HT_IO(HTConfig config, boolean newFile) throws IOException { + public HT_IO(HTConfig config, boolean newFile, IHTNodeFactory nodeFactory) throws IOException { fConfig = config; File historyTreeFile = config.getStateFile(); @@ -164,6 +169,7 @@ public class HT_IO { } fFileChannelIn = fFileInputStream.getChannel(); fFileChannelOut = fFileOutputStream.getChannel(); + fNodeFactory = nodeFactory; } /** diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HistoryTreeBackend.java b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HistoryTreeBackend.java index 1f5f12a344..2aaa1e390c 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HistoryTreeBackend.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HistoryTreeBackend.java @@ -278,8 +278,8 @@ public class HistoryTreeBackend implements IStateHistoryBackend { while (!queue.isEmpty()) { HTNode currentNode = queue.pop(); if (currentNode.getNodeType() == HTNode.NodeType.CORE) { - /* Here we add the relevant children nodes for BFS */ - queue.addAll(getSHT().selectNextChildren((CoreNode) currentNode, t)); + /*Here we add the relevant children nodes for BFS*/ + queue.addAll(getSHT().selectNextChildren((ParentNode) currentNode, t)); } currentNode.writeInfoFromNode(stateInfo, t); } @@ -326,7 +326,7 @@ public class HistoryTreeBackend implements IStateHistoryBackend { while (interval == null && !queue.isEmpty()) { HTNode currentNode = queue.pop(); if (currentNode.getNodeType() == HTNode.NodeType.CORE) { - queue.addAll(getSHT().selectNextChildren((CoreNode) currentNode, t)); + queue.addAll(getSHT().selectNextChildren((ParentNode) currentNode, t)); } interval = currentNode.getRelevantInterval(key, t); } diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HistoryTreeFactory.java b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HistoryTreeFactory.java index 61aae2307c..31d4487d97 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HistoryTreeFactory.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HistoryTreeFactory.java @@ -18,6 +18,7 @@ import java.nio.file.Path; import java.nio.file.StandardOpenOption; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.classic.HistoryTreeClassic; /** * Class that contains factory methods to build different types of history trees diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/IHistoryTree.java b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/IHistoryTree.java index f1d09a8e5e..51282c0b3a 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/IHistoryTree.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/IHistoryTree.java @@ -11,6 +11,7 @@ package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree; import java.io.File; import java.io.FileInputStream; +import java.io.IOException; import java.nio.channels.ClosedChannelException; import java.util.Collection; @@ -21,9 +22,54 @@ import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException; * high-level data relevant to the tree. * * @author Alexandre Montplaisir + * @author Geneviève Bastien */ public interface IHistoryTree { + /** + * Interface for history to create the various HTNodes + */ + interface IHTNodeFactory { + + /** + * Creates a new core node for the specific history tree + * + * @param config + * Configuration of the History Tree + * @param seqNumber + * The (unique) sequence number assigned to this particular + * node + * @param parentSeqNumber + * The sequence number of this node's parent node + * @param start + * The earliest timestamp stored in this node + * @return The new core node + * @throws IOException + * any exception occurring while trying to read/create the + * node + */ + HTNode createCoreNode(HTConfig config, int seqNumber, int parentSeqNumber, long start) throws IOException; + + /** + * Creates a new core node for the specific history tree + * + * @param config + * Configuration of the History Tree + * @param seqNumber + * The (unique) sequence number assigned to this particular + * node + * @param parentSeqNumber + * The sequence number of this node's parent node + * @param start + * The earliest timestamp stored in this node + * @return The new core node + * @throws IOException + * any exception occurring while trying to read/create the + * node + */ + HTNode createLeafNode(HTConfig config, int seqNumber, int parentSeqNumber, long start) throws IOException; + } + /** * Size of the "tree header" in the tree-file The nodes will use this offset * to know where they should be in the file. This should always be a @@ -158,7 +204,7 @@ public interface IHistoryTree { * @throws ClosedChannelException * If the file channel was closed while we were reading the tree */ - Collection selectNextChildren(CoreNode currentNode, long t) throws ClosedChannelException; + Collection selectNextChildren(ParentNode currentNode, long t) throws ClosedChannelException; /** * Get the current size of the history file. diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/ParentNode.java b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/ParentNode.java new file mode 100644 index 0000000000..34b798d6e3 --- /dev/null +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/ParentNode.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * 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 + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree; + +/** + * A Core node is a first-level node of a History Tree which is not a leaf node. + * + * It extends HTNode by adding support for child nodes, and also extensions. + * + * @author Alexandre Montplaisir + * @author Florian Wininger + */ +public abstract class ParentNode extends HTNode { + + /** + * Initial constructor. Use this to initialize a new EMPTY node. + * + * @param config + * Configuration of the History Tree + * @param seqNumber + * The (unique) sequence number assigned to this particular node + * @param parentSeqNumber + * The sequence number of this node's parent node + * @param start + * The earliest timestamp stored in this node + */ + public ParentNode(HTConfig config, int seqNumber, int parentSeqNumber, + long start) { + super(config, seqNumber, parentSeqNumber, start); + } + + /** + * Return the number of child nodes this node has. + * + * @return The number of child nodes + */ + public abstract int getNbChildren(); + + /** + * Get the child node corresponding to the specified index + * + * @param index The index of the child to lookup + * @return The child node + */ + public abstract int getChild(int index); + + /** + * Get the latest (right-most) child node of this node. + * + * @return The latest child node + */ + public abstract int getLatestChild(); + + /** + * Get the start time of the specified child node. + * + * @param index + * The index of the child node + * @return The start time of the that child node. + */ + public abstract long getChildStart(int index); + + /** + * Get the start time of the latest (right-most) child node. + * + * @return The start time of the latest child + */ + public abstract long getLatestChildStart(); + + /** + * Tell this node that it has a new child (Congrats!) + * + * @param childNode + * The SHTNode object of the new child + */ + public abstract void linkNewChild(HTNode childNode); + +} diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/CoreNode.java b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/classic/CoreNode.java similarity index 88% rename from statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/CoreNode.java rename to statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/classic/CoreNode.java index 480c0d925f..f70365a159 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/CoreNode.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/classic/CoreNode.java @@ -11,12 +11,16 @@ * Florian Wininger - Add Extension and Leaf Node *******************************************************************************/ -package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree; +package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.classic; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.concurrent.locks.ReentrantReadWriteLock; +import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTConfig; +import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTNode; +import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.ParentNode; + /** * A Core node is a first-level node of a History Tree which is not a leaf node. * @@ -24,7 +28,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; * * @author Alexandre Montplaisir */ -public final class CoreNode extends HTNode { +public final class CoreNode extends ParentNode { /** Nb. of children this node has */ private int nbChildren; @@ -120,11 +124,7 @@ public final class CoreNode extends HTNode { } } - /** - * Return the number of child nodes this node has. - * - * @return The number of child nodes - */ + @Override public int getNbChildren() { rwl.readLock().lock(); int ret = nbChildren; @@ -132,12 +132,7 @@ public final class CoreNode extends HTNode { return ret; } - /** - * Get the child node corresponding to the specified index - * - * @param index The index of the child to lookup - * @return The child node - */ + @Override public int getChild(int index) { rwl.readLock().lock(); try { @@ -147,11 +142,7 @@ public final class CoreNode extends HTNode { } } - /** - * Get the latest (right-most) child node of this node. - * - * @return The latest child node - */ + @Override public int getLatestChild() { rwl.readLock().lock(); try { @@ -161,13 +152,7 @@ public final class CoreNode extends HTNode { } } - /** - * Get the start time of the specified child node. - * - * @param index - * The index of the child node - * @return The start time of the that child node. - */ + @Override public long getChildStart(int index) { rwl.readLock().lock(); try { @@ -177,11 +162,7 @@ public final class CoreNode extends HTNode { } } - /** - * Get the start time of the latest (right-most) child node. - * - * @return The start time of the latest child - */ + @Override public long getLatestChildStart() { rwl.readLock().lock(); try { @@ -207,10 +188,13 @@ public final class CoreNode extends HTNode { * @param childNode * The SHTNode object of the new child */ + @Override public void linkNewChild(HTNode childNode) { rwl.writeLock().lock(); try { - assert (nbChildren < getConfig().getMaxChildren()); + if (nbChildren >= getConfig().getMaxChildren()) { + throw new IllegalStateException("Asked to link another child but parent already has maximum number of children"); //$NON-NLS-1$ + } children[nbChildren] = childNode.getSequenceNumber(); childStart[nbChildren] = childNode.getNodeStart(); diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HistoryTreeClassic.java b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/classic/HistoryTreeClassic.java similarity index 91% rename from statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HistoryTreeClassic.java rename to statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/classic/HistoryTreeClassic.java index 461fbf6eb2..7f8c4d4d7c 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HistoryTreeClassic.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/classic/HistoryTreeClassic.java @@ -12,7 +12,7 @@ * Patrick Tasse - Add message to exceptions *******************************************************************************/ -package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree; +package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.classic; import java.io.File; import java.io.FileInputStream; @@ -27,6 +27,13 @@ import java.util.Collections; import java.util.List; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTConfig; +import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTInterval; +import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTNode; +import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HT_IO; +import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.IHistoryTree; +import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.LeafNode; +import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.ParentNode; import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder; import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException; @@ -42,14 +49,27 @@ import com.google.common.collect.ImmutableList; public class HistoryTreeClassic implements IHistoryTree { /** - * The magic number for this file format. Package-private for the factory - * class. + * The magic number for this file format. */ - static final int HISTORY_FILE_MAGIC_NUMBER = 0x05FFA900; + public static final int HISTORY_FILE_MAGIC_NUMBER = 0x05FFA900; /** File format version. Increment when breaking compatibility. */ private static final int FILE_VERSION = 7; + private static final IHTNodeFactory CLASSIC_NODE_FACTORY = new IHTNodeFactory() { + + @Override + public HTNode createCoreNode(HTConfig config, int seqNumber, int parentSeqNumber, long start) { + return new CoreNode(config, seqNumber, parentSeqNumber, start); + } + + @Override + public HTNode createLeafNode(HTConfig config, int seqNumber, int parentSeqNumber, long start) { + return new LeafNode(config, seqNumber, parentSeqNumber, start); + } + + }; + // ------------------------------------------------------------------------ // Tree-specific configuration // ------------------------------------------------------------------------ @@ -102,7 +122,7 @@ public class HistoryTreeClassic implements IHistoryTree { fLatestBranch = Collections.synchronizedList(new ArrayList<>()); /* Prepare the IO object */ - fTreeIO = new HT_IO(fConfig, true); + fTreeIO = new HT_IO(fConfig, true, CLASSIC_NODE_FACTORY); /* Add the first node to the tree */ LeafNode firstNode = initNewLeafNode(-1, conf.getTreeStart()); @@ -193,7 +213,7 @@ public class HistoryTreeClassic implements IHistoryTree { * file, not extremely elegant. But how to pass the information here to * the SHT otherwise? */ - fTreeIO = new HT_IO(fConfig, false); + fTreeIO = new HT_IO(fConfig, false, CLASSIC_NODE_FACTORY); fLatestBranch = buildLatestBranch(rootNodeSeqNb); fTreeEnd = getRootNode().getNodeEnd(); @@ -486,7 +506,7 @@ public class HistoryTreeClassic implements IHistoryTree { } /* Check if we can indeed add a child to the target parent */ - if (((CoreNode) fLatestBranch.get(indexOfNode - 1)).getNbChildren() == fConfig.getMaxChildren()) { + if (((ParentNode) fLatestBranch.get(indexOfNode - 1)).getNbChildren() == fConfig.getMaxChildren()) { /* If not, add a branch starting one level higher instead */ addSiblingNode(indexOfNode - 1); return; @@ -497,7 +517,7 @@ public class HistoryTreeClassic implements IHistoryTree { fLatestBranch.get(i).closeThisNode(splitTime); fTreeIO.writeNode(fLatestBranch.get(i)); - CoreNode prevNode = (CoreNode) fLatestBranch.get(i - 1); + ParentNode prevNode = (ParentNode) fLatestBranch.get(i - 1); HTNode newNode; switch (fLatestBranch.get(i).getNodeType()) { @@ -525,7 +545,7 @@ public class HistoryTreeClassic implements IHistoryTree { final long splitTime = fTreeEnd; HTNode oldRootNode = fLatestBranch.get(0); - CoreNode newRootNode = initNewCoreNode(-1, fConfig.getTreeStart()); + ParentNode newRootNode = initNewCoreNode(-1, fConfig.getTreeStart()); /* Tell the old root node that it isn't root anymore */ oldRootNode.setParentSequenceNumber(newRootNode.getSequenceNumber()); @@ -547,15 +567,15 @@ public class HistoryTreeClassic implements IHistoryTree { // Create new coreNode for (int i = 1; i < depth; i++) { - CoreNode prevNode = (CoreNode) fLatestBranch.get(i - 1); - CoreNode newNode = initNewCoreNode(prevNode.getSequenceNumber(), + ParentNode prevNode = (ParentNode) fLatestBranch.get(i - 1); + ParentNode newNode = initNewCoreNode(prevNode.getSequenceNumber(), splitTime + 1); prevNode.linkNewChild(newNode); fLatestBranch.add(newNode); } // Create the new leafNode - CoreNode prevNode = (CoreNode) fLatestBranch.get(depth - 1); + ParentNode prevNode = (ParentNode) fLatestBranch.get(depth - 1); LeafNode newNode = initNewLeafNode(prevNode.getSequenceNumber(), splitTime + 1); prevNode.linkNewChild(newNode); fLatestBranch.add(newNode); @@ -570,8 +590,8 @@ public class HistoryTreeClassic implements IHistoryTree { * Start time of the new node * @return The newly created node */ - private @NonNull CoreNode initNewCoreNode(int parentSeqNumber, long startTime) { - CoreNode newNode = new CoreNode(fConfig, fNodeCount, parentSeqNumber, + private @NonNull ParentNode initNewCoreNode(int parentSeqNumber, long startTime) { + ParentNode newNode = new CoreNode(fConfig, fNodeCount, parentSeqNumber, startTime); fNodeCount++; return newNode; @@ -594,7 +614,7 @@ public class HistoryTreeClassic implements IHistoryTree { } @Override - public Collection selectNextChildren(CoreNode currentNode, long t) throws ClosedChannelException { + public Collection selectNextChildren(ParentNode currentNode, long t) throws ClosedChannelException { assert (currentNode.getNbChildren() > 0); int potentialNextSeqNb = currentNode.getSequenceNumber(); -- 2.34.1