ss: History trees can define their own node types
[deliverable/tracecompass.git] / statesystem / org.eclipse.tracecompass.statesystem.core / src / org / eclipse / tracecompass / internal / statesystem / core / backend / historytree / HTNode.java
index b006d190af7412debc039617d4d84f04e6cdfe20..9cada2d4f4e989f8ea981490187fd168b34ba40e 100644 (file)
@@ -104,7 +104,10 @@ public abstract class HTNode {
      *  1 - byte (done or not)
      * </pre>
      */
-    private static final int COMMON_HEADER_SIZE = 34;
+    private static final int COMMON_HEADER_SIZE = Byte.BYTES
+            + 2 * Long.BYTES
+            + 4 * Integer.BYTES
+            + Byte.BYTES;
 
     // ------------------------------------------------------------------------
     // Attributes
@@ -121,9 +124,6 @@ public abstract class HTNode {
     private final int fSequenceNumber;
     private int fParentSequenceNumber; /* = -1 if this node is the root node */
 
-    /* Where the Strings section begins (from the start of the node */
-    private int fStringSectionOffset;
-
     /* Sum of bytes of all intervals in the node */
     private int fSizeOfIntervalSection;
 
@@ -154,7 +154,6 @@ public abstract class HTNode {
         fSequenceNumber = seqNumber;
         fParentSequenceNumber = parentSeqNumber;
 
-        fStringSectionOffset = config.getBlockSize();
         fSizeOfIntervalSection = 0;
         fIsOnDisk = false;
         fIntervals = new ArrayList<>();
@@ -169,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;
@@ -193,20 +194,19 @@ public abstract class HTNode {
         int seqNb = buffer.getInt();
         int parentSeqNb = buffer.getInt();
         int intervalCount = buffer.getInt();
-        int stringSectionOffset = buffer.getInt();
         buffer.get(); // TODO Used to be "isDone", to be removed from the header
 
         /* Now the rest of the header depends on the node type */
         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;
 
@@ -222,12 +222,11 @@ public abstract class HTNode {
         for (i = 0; i < intervalCount; i++) {
             HTInterval interval = HTInterval.readFrom(buffer);
             newNode.fIntervals.add(interval);
-            newNode.fSizeOfIntervalSection += HTInterval.DATA_ENTRY_SIZE;
+            newNode.fSizeOfIntervalSection += interval.getSizeOnDisk();
         }
 
         /* Assign the node's other information we have read previously */
         newNode.fNodeEnd = end;
-        newNode.fStringSectionOffset = stringSectionOffset;
         newNode.fIsOnDisk = true;
 
         return newNode;
@@ -250,7 +249,6 @@ public abstract class HTNode {
         fRwl.readLock().lock();
         try {
             final int blockSize = fConfig.getBlockSize();
-            int curStringsEntryEndPos = blockSize;
 
             ByteBuffer buffer = ByteBuffer.allocate(blockSize);
             buffer.order(ByteOrder.LITTLE_ENDIAN);
@@ -263,40 +261,22 @@ public abstract class HTNode {
             buffer.putInt(fSequenceNumber);
             buffer.putInt(fParentSequenceNumber);
             buffer.putInt(fIntervals.size());
-            buffer.putInt(fStringSectionOffset);
             buffer.put((byte) 1); // TODO Used to be "isDone", to be removed from header
 
             /* Now call the inner method to write the specific header part */
             writeSpecificHeader(buffer);
 
             /* Back to us, we write the intervals */
-            for (HTInterval interval : fIntervals) {
-                int size = interval.writeInterval(buffer, curStringsEntryEndPos);
-                curStringsEntryEndPos -= size;
-            }
+            fIntervals.forEach(i -> i.writeInterval(buffer));
 
             /*
-             * Write padding between the end of the Data section and the start
-             * of the Strings section (needed to fill the node in case there is
-             * no Strings section)
+             * Fill the rest with zeros
              */
-            while (buffer.position() < fStringSectionOffset) {
+            while (buffer.position() < blockSize) {
                 buffer.put((byte) 0);
             }
 
-            /*
-             * If the offsets were right, the size of the Strings section should
-             * be == to the expected size
-             */
-            if (curStringsEntryEndPos != fStringSectionOffset) {
-                throw new IllegalStateException("Wrong size of Strings section: Actual: " + curStringsEntryEndPos + ", Expected: " + fStringSectionOffset); //$NON-NLS-1$ //$NON-NLS-2$
-            }
-
             /* Finally, write everything in the Buffer to disk */
-
-            // if we don't do this, flip() will lose what's after.
-            buffer.position(blockSize);
-
             buffer.flip();
             int res = fc.write(buffer);
             if (res != blockSize) {
@@ -391,7 +371,7 @@ public abstract class HTNode {
         fRwl.writeLock().lock();
         try {
             /* Just in case, should be checked before even calling this function */
-            assert (newInterval.getIntervalSize() <= getNodeFreeSpace());
+            assert (newInterval.getSizeOnDisk() <= getNodeFreeSpace());
 
             /* Find the insert position to keep the list sorted */
             int index = fIntervals.size();
@@ -400,10 +380,8 @@ public abstract class HTNode {
             }
 
             fIntervals.add(index, newInterval);
-            fSizeOfIntervalSection += HTInterval.DATA_ENTRY_SIZE;
+            fSizeOfIntervalSection += newInterval.getSizeOnDisk();
 
-            /* Update the in-node offset "pointer" */
-            fStringSectionOffset -= (newInterval.getStringsEntrySize());
         } finally {
             fRwl.writeLock().unlock();
         }
@@ -472,7 +450,7 @@ public abstract class HTNode {
                  * null anyway).
                  */
                 ITmfStateInterval interval = fIntervals.get(i);
-                if (interval.getStartTime() <= t &&
+                if (t >= interval.getStartTime() &&
                         interval.getAttribute() < stateInfo.size()) {
                     stateInfo.set(interval.getAttribute(), interval);
                 }
@@ -577,7 +555,7 @@ public abstract class HTNode {
      */
     public int getNodeFreeSpace() {
         fRwl.readLock().lock();
-        int ret = fStringSectionOffset - getDataSectionEndOffset();
+        int ret = fConfig.getBlockSize() - getDataSectionEndOffset();
         fRwl.readLock().unlock();
 
         return ret;
@@ -631,11 +609,11 @@ public abstract class HTNode {
     @SuppressWarnings("nls")
     public void debugPrintIntervals(PrintWriter writer) {
         /* Only used for debugging, shouldn't be externalized */
-        writer.println("Node #" + fSequenceNumber + ":");
+        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));
This page took 0.128798 seconds and 5 git commands to generate.