ss: Fix wrong calculation of string size in history tree
authorGeneviève Bastien <gbastien+lttng@versatic.net>
Wed, 28 Oct 2015 03:42:53 +0000 (23:42 -0400)
committerGenevieve Bastien <gbastien+lttng@versatic.net>
Sat, 31 Oct 2015 02:39:19 +0000 (22:39 -0400)
The strings size was calculated twice in the node size. The nodes were
therefore not used at full capacity.

Change-Id: Iea15dfd701859deaaea7857de83c36c3455eefb9
Signed-off-by: Geneviève Bastien <gbastien+lttng@versatic.net>
Reviewed-on: https://git.eclipse.org/r/52755
Reviewed-by: Alexandre Montplaisir <alexmonthy@voxpopuli.im>
Tested-by: Alexandre Montplaisir <alexmonthy@voxpopuli.im>
Reviewed-by: Hudson CI
statesystem/org.eclipse.tracecompass.statesystem.core.tests/.classpath
statesystem/org.eclipse.tracecompass.statesystem.core.tests/META-INF/MANIFEST.MF
statesystem/org.eclipse.tracecompass.statesystem.core.tests/build.properties
statesystem/org.eclipse.tracecompass.statesystem.core.tests/src/org/eclipse/tracecompass/statesystem/core/tests/backend/AllTests.java
statesystem/org.eclipse.tracecompass.statesystem.core.tests/src/org/eclipse/tracecompass/statesystem/core/tests/backend/HistoryTreeTest.java [new file with mode: 0644]
statesystem/org.eclipse.tracecompass.statesystem.core.tests/stubs/org/eclipse/tracecompasss/statesystem/core/tests/stubs/backend/HistoryTreeStub.java [new file with mode: 0644]
statesystem/org.eclipse.tracecompass.statesystem.core.tests/stubs/org/eclipse/tracecompasss/statesystem/core/tests/stubs/backend/package-info.java [new file with mode: 0644]
statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HTInterval.java
statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HTNode.java
statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/backend/historytree/HistoryTree.java

index 5480bc80152d9604a26638ad3345b275e8994da7..aed35557fedd7efa43bfe401b6545ee3cc4ac7fc 100644 (file)
@@ -11,5 +11,6 @@
                </attributes>
        </classpathentry>
        <classpathentry kind="src" path="src"/>
+       <classpathentry kind="src" path="stubs"/>
        <classpathentry kind="output" path="bin"/>
 </classpath>
index fb3530b2ce3230089f29bfa0ef30e879b78b13f5..0c4d83dfa1e735374030333b356b9911b2698216 100644 (file)
@@ -13,3 +13,4 @@ Require-Bundle: org.junit;bundle-version="4.0.0",
  org.eclipse.tracecompass.common.core,
  org.eclipse.tracecompass.statesystem.core
 Export-Package: org.eclipse.tracecompass.statesystem.core.tests
+Import-Package: com.google.common.collect
index 1a4decb3955d2958eedbc4818bf274cfdeb69409..3193c5d94c9c63f65f4d182ac9a063fba6436f99 100644 (file)
@@ -10,7 +10,8 @@
 #     Ericsson - Initial API and implementation
 ###############################################################################
 
-source.. = src/
+source.. = src/,\
+           stubs/
 output.. = bin/
 bin.includes = META-INF/,\
                .,\
diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core.tests/src/org/eclipse/tracecompass/statesystem/core/tests/backend/HistoryTreeTest.java b/statesystem/org.eclipse.tracecompass.statesystem.core.tests/src/org/eclipse/tracecompass/statesystem/core/tests/backend/HistoryTreeTest.java
new file mode 100644 (file)
index 0000000..350227e
--- /dev/null
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright (c) 2015 École Polytechnique de Montréal
+ *
+ * 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.statesystem.core.tests.backend;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+
+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.HistoryTree;
+import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
+import org.eclipse.tracecompasss.statesystem.core.tests.stubs.backend.HistoryTreeStub;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests the history tree
+ *
+ * @author Geneviève Bastien
+ */
+public class HistoryTreeTest {
+
+    /* Minimal allowed blocksize */
+    private static final int BLOCK_SIZE = HistoryTree.TREE_HEADER_SIZE;
+    /* The extra size used by long and double values */
+    private static final int LONG_DOUBLE_SIZE = 8;
+    /* The number of extra characters to store a string interval */
+    private static final int STRING_PADDING = 2;
+
+    /* String with 23 characters, interval in file will be 25 bytes long */
+    private static final String TEST_STRING = "abcdefghifklmnopqrstuvw";
+    private static final TmfStateValue STRING_VALUE = TmfStateValue.newValueString(TEST_STRING);
+    private static final TmfStateValue LONG_VALUE = TmfStateValue.newValueLong(10L);
+    private static final TmfStateValue INT_VALUE = TmfStateValue.newValueInt(1);
+
+    private File fTempFile;
+
+    /**
+     * Create the temporary file for this history tree
+     */
+    @Before
+    public void setupTest() {
+        try {
+            fTempFile = File.createTempFile("tmpStateSystem", null);
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    /**
+     * Delete the temporary history tree file after the test
+     */
+    @After
+    public void cleanup() {
+        fTempFile.delete();
+    }
+
+    private HistoryTreeStub setupSmallTree() {
+        HistoryTreeStub ht = null;
+        try {
+            File newFile = fTempFile;
+            assertNotNull(newFile);
+            HTConfig config = new HTConfig(newFile,
+                    BLOCK_SIZE,
+                    3, /* Number of children */
+                    1, /* Provider version */
+                    1); /* Start time */
+            ht = new HistoryTreeStub(config);
+
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+
+        assertNotNull(ht);
+        return ht;
+    }
+
+    private static long fillValues(HistoryTree ht, TmfStateValue value, int nbValues, long start) {
+        for (int i = 0; i < nbValues; i++) {
+            ht.insertInterval(new HTInterval(start + i, start + i + 1, 1, value));
+        }
+        return start + nbValues;
+    }
+
+    /**
+     * Test that nodes are filled
+     *
+     * It fills nodes with sequential intervals from one attribute only, so that
+     * leafs should be filled.
+     */
+    @Test
+    public void testSequentialFill() {
+        HistoryTreeStub ht = setupSmallTree();
+
+        HTNode node = ht.getLatestLeaf();
+        assertEquals(0, node.getNodeUsagePercent());
+
+        /* Add null intervals up to ~10% */
+        int nodeFreeSpace = node.getNodeFreeSpace();
+        int nbIntervals = nodeFreeSpace / 10 / HTInterval.DATA_ENTRY_SIZE;
+        long start = fillValues(ht, TmfStateValue.nullValue(), nbIntervals, 1);
+        assertEquals(nodeFreeSpace - nbIntervals * HTInterval.DATA_ENTRY_SIZE, node.getNodeFreeSpace());
+
+        /* Add integer intervals up to ~20% */
+        nodeFreeSpace = node.getNodeFreeSpace();
+        nbIntervals = nodeFreeSpace / 10 / HTInterval.DATA_ENTRY_SIZE;
+        start = fillValues(ht, INT_VALUE, nbIntervals, start);
+        assertEquals(nodeFreeSpace - nbIntervals * HTInterval.DATA_ENTRY_SIZE, node.getNodeFreeSpace());
+
+        /* Add long intervals up to ~30% */
+        nodeFreeSpace = node.getNodeFreeSpace();
+        nbIntervals = nodeFreeSpace / 10 / (HTInterval.DATA_ENTRY_SIZE + LONG_DOUBLE_SIZE);
+        start = fillValues(ht, LONG_VALUE, nbIntervals, start);
+        assertEquals(nodeFreeSpace - nbIntervals * (HTInterval.DATA_ENTRY_SIZE + LONG_DOUBLE_SIZE), node.getNodeFreeSpace());
+
+        /* Add string intervals up to ~40% */
+        nodeFreeSpace = node.getNodeFreeSpace();
+        nbIntervals = nodeFreeSpace / 10 / (HTInterval.DATA_ENTRY_SIZE + TEST_STRING.length() + STRING_PADDING);
+        start = fillValues(ht, STRING_VALUE, nbIntervals, start);
+        assertEquals(nodeFreeSpace - nbIntervals * (HTInterval.DATA_ENTRY_SIZE + TEST_STRING.length() + STRING_PADDING), node.getNodeFreeSpace());
+
+    }
+
+}
diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core.tests/stubs/org/eclipse/tracecompasss/statesystem/core/tests/stubs/backend/HistoryTreeStub.java b/statesystem/org.eclipse.tracecompass.statesystem.core.tests/stubs/org/eclipse/tracecompasss/statesystem/core/tests/stubs/backend/HistoryTreeStub.java
new file mode 100644 (file)
index 0000000..75c5929
--- /dev/null
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2015 École Polytechnique de Montréal
+ *
+ * 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.tracecompasss.statesystem.core.tests.stubs.backend;
+
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
+import java.io.IOException;
+import java.util.List;
+
+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.HistoryTree;
+
+import com.google.common.collect.Iterables;
+
+/**
+ * Stub class to unit test the history tree. You can set the size of the
+ * interval section before using the tree, in order to fine-tune the test.
+ *
+ * Note to developers: This tree is not meant to be used with a backend. It just
+ * exposes some info from the history tree.
+ *
+ * @author Geneviève Bastien
+ */
+public class HistoryTreeStub extends HistoryTree {
+
+    /**
+     * Constructor for this history tree stub
+     *
+     * @param conf
+     *            The config to use for this History Tree.
+     * @throws IOException
+     *             If an error happens trying to open/write to the file
+     *             specified in the config
+     */
+    public HistoryTreeStub(HTConfig conf) throws IOException {
+        super(conf);
+    }
+
+    /**
+     * Get the latest leaf of the tree
+     *
+     * @return The current leaf node of the tree
+     */
+    public HTNode getLatestLeaf() {
+        List<HTNode> latest = getLatestBranch();
+        return checkNotNull(Iterables.getLast(latest));
+    }
+
+    /**
+     * Get the node from the latest branch at a given position, 0 being the root
+     * and <size of latest branch - 1> being a leaf node.
+     *
+     * @param pos
+     *            The position at which to return the node
+     * @return The node at position pos
+     */
+    public HTNode getNodeAt(int pos) {
+        List<HTNode> latest = getLatestBranch();
+        return checkNotNull(latest.get(pos));
+    }
+
+}
diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core.tests/stubs/org/eclipse/tracecompasss/statesystem/core/tests/stubs/backend/package-info.java b/statesystem/org.eclipse.tracecompass.statesystem.core.tests/stubs/org/eclipse/tracecompasss/statesystem/core/tests/stubs/backend/package-info.java
new file mode 100644 (file)
index 0000000..5fdeeb7
--- /dev/null
@@ -0,0 +1,11 @@
+/*******************************************************************************
+ * Copyright (c) 2015 École Polytechnique de Montréal
+ *
+ * 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
+ *******************************************************************************/
+
+@org.eclipse.jdt.annotation.NonNullByDefault
+package org.eclipse.tracecompasss.statesystem.core.tests.stubs.backend;
index 2b48afb811d6c99cb6ff8d886b666f505fb65224..c7ca11f8da0b376048b56039c3e3cdcbf9a4e23c 100644 (file)
@@ -44,7 +44,7 @@ public final class HTInterval implements ITmfStateInterval, Comparable<HTInterva
      * +  4  int (valueOffset)
      * </pre>
      */
-    private static final int DATA_ENTRY_SIZE = 25;
+    public static final int DATA_ENTRY_SIZE = 25;
 
     /* 'Byte' equivalent for state values types */
     private static final byte TYPE_NULL = -1;
index f8d1bc1ed6e736aaba436e5a81c989ea86cda74a..95a1f002dfb2c740bb8c7c68780a7280378fc007 100644 (file)
@@ -219,7 +219,7 @@ public abstract class HTNode {
         for (i = 0; i < intervalCount; i++) {
             HTInterval interval = HTInterval.readFrom(buffer);
             newNode.fIntervals.add(interval);
-            newNode.fSizeOfIntervalSection += interval.getIntervalSize();
+            newNode.fSizeOfIntervalSection += HTInterval.DATA_ENTRY_SIZE;
         }
 
         /* Assign the node's other information we have read previously */
@@ -393,7 +393,7 @@ public abstract class HTNode {
             }
 
             fIntervals.add(index, newInterval);
-            fSizeOfIntervalSection += newInterval.getIntervalSize();
+            fSizeOfIntervalSection += HTInterval.DATA_ENTRY_SIZE;
 
             /* Update the in-node offset "pointer" */
             fStringSectionOffset -= (newInterval.getStringsEntrySize());
index be301016682fb5fceb477e411d636b7067a4e900..1cc3785e02731bacb5594d799aa506854c58f1a9 100644 (file)
@@ -30,6 +30,8 @@ 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.
@@ -335,6 +337,16 @@ public class HistoryTree {
         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<HTNode> getLatestBranch() {
+        return ImmutableList.copyOf(fLatestBranch);
+    }
+
     // ------------------------------------------------------------------------
     // HT_IO interface
     // ------------------------------------------------------------------------
This page took 0.044167 seconds and 5 git commands to generate.