ctf: Don't include all test traces in jar
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / internal / tmf / core / statesystem / backends / historytree / HTInterval.java
index 49100da9b3b1aa6d4610e4450d065aeeadf56fc7..f99cb8b5b39a5e6300748351ea0b26d4643953c3 100644 (file)
@@ -1,6 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2013 Ericsson
- * Copyright (c) 2010, 2011 École Polytechnique de Montréal
+ * Copyright (c) 2012, 2014 Ericsson, École Polytechnique de Montréal
  * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
  *
  * All rights reserved. This program and the accompanying materials are
@@ -8,6 +7,9 @@
  * accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  *
+ * Contributors:
+ *    Alexandre Montplaisir - Initial API and implementation
+ *    Florian Wininger - Allow to change the size of a interval
  *******************************************************************************/
 
 package org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.historytree;
@@ -25,18 +27,36 @@ import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue;
  * The interval component, which will be contained in a node of the History
  * Tree.
  *
- * @author alexmont
- *
+ * @author Alexandre Montplaisir
  */
-final class HTInterval implements ITmfStateInterval, Comparable<HTInterval> {
+public final class HTInterval implements ITmfStateInterval, Comparable<HTInterval> {
 
     private static final String errMsg = "Invalid interval data. Maybe your file is corrupt?"; //$NON-NLS-1$
 
+    /**
+     * Size of an entry in the data section.
+     *
+     * <pre>
+     *   16  2 x Timevalue/long (interval start + end)
+     * +  4  int (key)
+     * +  1  byte (type)
+     * +  4  int (valueOffset)
+     * </pre>
+     */
+    private static final int DATA_ENTRY_SIZE = 25;
+
     /* 'Byte' equivalent for state values types */
     private static final byte TYPE_NULL = -1;
     private static final byte TYPE_INTEGER = 0;
     private static final byte TYPE_STRING = 1;
     private static final byte TYPE_LONG = 2;
+    private static final byte TYPE_DOUBLE = 3;
+
+    /* String entry sizes of different state values */
+    private static final int NO_ENTRY_SIZE = 0;
+    private static final int LONG_ENTRY_SIZE = 8;
+    private static final int DOUBLE_ENTRY_SIZE = 8;
+    // sizes of string values depend on the string itself
 
     private final long start;
     private final long end;
@@ -52,12 +72,18 @@ final class HTInterval implements ITmfStateInterval, Comparable<HTInterval> {
      * Standard constructor
      *
      * @param intervalStart
+     *            Start time of the interval
      * @param intervalEnd
+     *            End time of the interval
      * @param attribute
+     *            Attribute (quark) to which the state represented by this
+     *            interval belongs
      * @param value
+     *            State value represented by this interval
      * @throws TimeRangeException
+     *             If the start time or end time are invalid
      */
-    HTInterval(long intervalStart, long intervalEnd, int attribute,
+    public HTInterval(long intervalStart, long intervalEnd, int attribute,
             TmfStateValue value) throws TimeRangeException {
         if (intervalStart > intervalEnd) {
             throw new TimeRangeException();
@@ -71,14 +97,35 @@ final class HTInterval implements ITmfStateInterval, Comparable<HTInterval> {
     }
 
     /**
-     * Reader constructor. Builds the interval using an already-allocated
+     * "Faster" constructor for inner use only. When we build an interval when
+     * reading it from disk (with {@link #readFrom}), we already know the size
+     * of the strings entry, so there is no need to call
+     * {@link #computeStringsEntrySize()} and do an extra copy.
+     */
+    private HTInterval(long intervalStart, long intervalEnd, int attribute,
+            TmfStateValue value, int size) throws TimeRangeException {
+        if (intervalStart > intervalEnd) {
+            throw new TimeRangeException();
+        }
+
+        this.start = intervalStart;
+        this.end = intervalEnd;
+        this.attribute = attribute;
+        this.sv = value;
+        this.stringsEntrySize = size;
+    }
+
+    /**
+     * Reader factory method. Builds the interval using an already-allocated
      * ByteBuffer, which normally comes from a NIO FileChannel.
      *
      * @param buffer
      *            The ByteBuffer from which to read the information
+     * @return The interval object
      * @throws IOException
+     *             If there was an error reading from the buffer
      */
-    final static HTInterval readFrom(ByteBuffer buffer) throws IOException {
+    public static final HTInterval readFrom(ByteBuffer buffer) throws IOException {
         HTInterval interval;
         long intervalStart, intervalEnd;
         int attribute;
@@ -99,11 +146,13 @@ final class HTInterval implements ITmfStateInterval, Comparable<HTInterval> {
 
         case TYPE_NULL:
             value = TmfStateValue.nullValue();
+            valueSize = NO_ENTRY_SIZE;
             break;
 
         case TYPE_INTEGER:
             /* "ValueOrOffset" is the straight value */
             value = TmfStateValue.newValueInt(valueOrOffset);
+            valueSize = NO_ENTRY_SIZE;
             break;
 
         case TYPE_STRING:
@@ -142,6 +191,21 @@ final class HTInterval implements ITmfStateInterval, Comparable<HTInterval> {
             buffer.mark();
             buffer.position(valueOrOffset);
             value = TmfStateValue.newValueLong(buffer.getLong());
+            valueSize = LONG_ENTRY_SIZE;
+
+            /*
+             * Restore the file pointer's position (so we can read the next
+             * interval)
+             */
+            buffer.reset();
+            break;
+
+        case TYPE_DOUBLE:
+            /* Go read the matching entry in the Strings section of the block */
+            buffer.mark();
+            buffer.position(valueOrOffset);
+            value = TmfStateValue.newValueDouble(buffer.getDouble());
+            valueSize = DOUBLE_ENTRY_SIZE;
 
             /*
              * Restore the file pointer's position (so we can read the next
@@ -149,13 +213,14 @@ final class HTInterval implements ITmfStateInterval, Comparable<HTInterval> {
              */
             buffer.reset();
             break;
+
         default:
             /* Unknown data, better to not make anything up... */
             throw new IOException(errMsg);
         }
 
         try {
-            interval = new HTInterval(intervalStart, intervalEnd, attribute, value);
+            interval = new HTInterval(intervalStart, intervalEnd, attribute, value, valueSize);
         } catch (TimeRangeException e) {
             throw new IOException(errMsg);
         }
@@ -176,7 +241,7 @@ final class HTInterval implements ITmfStateInterval, Comparable<HTInterval> {
      *            StateValues.
      * @return The size of the Strings Entry that was written, if any.
      */
-    int writeInterval(ByteBuffer buffer, int endPosOfStringEntry) {
+    public int writeInterval(ByteBuffer buffer, int endPosOfStringEntry) {
         buffer.putLong(start);
         buffer.putLong(end);
         buffer.putInt(attribute);
@@ -186,8 +251,7 @@ final class HTInterval implements ITmfStateInterval, Comparable<HTInterval> {
 
         case TYPE_NULL:
         case TYPE_INTEGER:
-            /* We write the 'valueOffset' field as a straight value. In the case
-             * of a null value, it will be unboxed as -1 */
+            /* We write the 'valueOffset' field as a straight value. */
             try {
                 buffer.putInt(sv.unboxInt());
             } catch (StateValueTypeException e) {
@@ -245,6 +309,28 @@ final class HTInterval implements ITmfStateInterval, Comparable<HTInterval> {
             buffer.reset();
             break;
 
+        case TYPE_DOUBLE:
+            /* we use the valueOffset as an offset. */
+            buffer.putInt(endPosOfStringEntry - stringsEntrySize);
+            buffer.mark();
+            buffer.position(endPosOfStringEntry - stringsEntrySize);
+
+            /* Write the Double in the Strings section */
+            try {
+                buffer.putDouble(sv.unboxDouble());
+            } catch (StateValueTypeException e) {
+                /*
+                 * This should not happen, since the value told us it was of
+                 * type Double (corrupted value?)
+                 */
+                e.printStackTrace();
+            }
+            if (buffer.position() != endPosOfStringEntry) {
+                throw new IllegalStateException();
+            }
+            buffer.reset();
+            break;
+
         default:
             break;
         }
@@ -293,10 +379,10 @@ final class HTInterval implements ITmfStateInterval, Comparable<HTInterval> {
     /**
      * Total serialized size of this interval
      *
-     * @return
+     * @return The interval size
      */
-    int getIntervalSize() {
-        return stringsEntrySize + HTNode.getDataEntrySize();
+    public int getIntervalSize() {
+        return stringsEntrySize + DATA_ENTRY_SIZE;
     }
 
     private int computeStringsEntrySize() {
@@ -304,22 +390,25 @@ final class HTInterval implements ITmfStateInterval, Comparable<HTInterval> {
         case NULL:
         case INTEGER:
             /* Those don't use the strings section at all */
-            return 0;
+            return NO_ENTRY_SIZE;
         case LONG:
             /* The value's bytes are written directly into the strings section */
-            return 8;
+            return LONG_ENTRY_SIZE;
+        case DOUBLE:
+            /* The value is also written directly into the strings section */
+            return DOUBLE_ENTRY_SIZE;
         case STRING:
             try {
                 /* String's length + 2 (1 byte for size, 1 byte for \0 at the end */
                 return sv.unboxStr().getBytes().length + 2;
             } catch (StateValueTypeException e) {
                 /* We're inside a switch/case for the string type, can't happen */
-                throw new RuntimeException();
+                throw new IllegalStateException(e);
             }
         default:
             /* It's very important that we know how to write the state value in
              * the file!! */
-            throw new RuntimeException();
+            throw new IllegalStateException();
         }
     }
 
@@ -340,10 +429,9 @@ final class HTInterval implements ITmfStateInterval, Comparable<HTInterval> {
 
     @Override
     public boolean equals(Object other) {
-        if (other instanceof HTInterval) {
-            if (this.compareTo((HTInterval) other) == 0) {
-                return true;
-            }
+        if (other instanceof HTInterval &&
+                this.compareTo((HTInterval) other) == 0) {
+            return true;
         }
         return false;
     }
@@ -386,9 +474,11 @@ final class HTInterval implements ITmfStateInterval, Comparable<HTInterval> {
             return TYPE_STRING;
         case LONG:
             return TYPE_LONG;
+        case DOUBLE:
+            return TYPE_DOUBLE;
         default:
             /* Should not happen if the switch is fully covered */
-            throw new RuntimeException();
+            throw new IllegalStateException();
         }
     }
 }
This page took 0.028632 seconds and 5 git commands to generate.