tmf: Support resuming the trace index
authorMarc-Andre Laperle <marc-andre.laperle@ericsson.com>
Mon, 17 Aug 2015 03:37:19 +0000 (23:37 -0400)
committerMarc-Andre Laperle <marc-andre.laperle@ericsson.com>
Thu, 20 Aug 2015 19:39:26 +0000 (15:39 -0400)
This allows resuming the indexing job after a trace was closed while the
indexing was not finished.
This also allows to index new content that was added to a trace, even if the
content was added after closing the trace and the indexer was finished.

Change-Id: I58296c0114a9f495605836f8c6df6dfceb424654
Signed-off-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/53851
Reviewed-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
Tested-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
Reviewed-by: Hudson CI
13 files changed:
tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/AbstractCheckpointCollectionTest.java
tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/AllBench.java
tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/BTreeTest.java
tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/AbstractIndexTest.java
tmf/org.eclipse.tracecompass.tmf.core.tests/src/org/eclipse/tracecompass/tmf/core/tests/trace/indexer/checkpoint/TmfBTreeIndexTest.java
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/AbstractFileCheckpointCollection.java
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/BTree.java
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/ICheckpointCollection.java
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/trace/indexer/TmfMemoryIndex.java
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/TmfBTreeTraceIndex.java
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/TmfFlatArrayTraceIndex.java
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/checkpoint/ITmfCheckpointIndex.java
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/indexer/checkpoint/TmfCheckpointIndexer.java

index 22fff26e15b19e1af26fcfe9540eb67cfe936c53..8372998b3f1f1a7cc8f8078c123d825967d4fb07 100644 (file)
@@ -126,7 +126,6 @@ public abstract class AbstractCheckpointCollectionTest {
     public void testConstructorExistingFile() {
         if (isPersistableCollection()) {
             assertTrue(fFile.exists());
-            fCheckpointCollection.setIndexComplete();
             fCheckpointCollection.dispose();
 
             fCheckpointCollection = createCollection();
@@ -141,7 +140,6 @@ public abstract class AbstractCheckpointCollectionTest {
     @Test
     public void testIsCreatedFromScratch() {
         assertTrue(fCheckpointCollection.isCreatedFromScratch());
-        fCheckpointCollection.setIndexComplete();
 
         if (isPersistableCollection()) {
             fCheckpointCollection.dispose();
@@ -182,14 +180,14 @@ public abstract class AbstractCheckpointCollectionTest {
     }
 
     /**
-     * Test setSize, size
+     * Test get size
      */
     @Test
-    public void testSetGetSize() {
+    public void testGetSize() {
         assertEquals(0, fCheckpointCollection.size());
         int expected = CHECKPOINTS_INSERT_NUM;
         for (int i = 0; i < expected; ++i) {
-            fCheckpointCollection.insert(new TmfCheckpoint(new TmfTimestamp(0), new TmfLongLocation(0L), 0));
+            fCheckpointCollection.insert(new TmfCheckpoint(new TmfTimestamp(i), new TmfLongLocation(i), i));
         }
         assertEquals(expected, fCheckpointCollection.size());
     }
@@ -214,7 +212,6 @@ public abstract class AbstractCheckpointCollectionTest {
      */
     @Test
     public void testVersionChange() throws IOException {
-        fCheckpointCollection.setIndexComplete();
         fCheckpointCollection.dispose();
         try (RandomAccessFile f = new RandomAccessFile(fFile, "rw");) {
             f.writeInt(-1);
@@ -234,6 +231,7 @@ public abstract class AbstractCheckpointCollectionTest {
 
         long found = fCheckpointCollection.binarySearch(checkpoint);
         assertEquals(0, found);
+        assertEquals(1, fCheckpointCollection.size());
     }
 
     /**
@@ -247,7 +245,7 @@ public abstract class AbstractCheckpointCollectionTest {
             fCheckpointCollection.insert(checkpoint);
         }
 
-        fCheckpointCollection.setIndexComplete();
+        assertEquals(CHECKPOINTS_INSERT_NUM, fCheckpointCollection.size());
         if (isPersistableCollection()) {
             fCheckpointCollection.dispose();
         }
@@ -276,6 +274,7 @@ public abstract class AbstractCheckpointCollectionTest {
         if (isPersistableCollection()) {
             fCheckpointCollection = createCollection();
         }
+        assertEquals(CHECKPOINTS_INSERT_NUM, fCheckpointCollection.size());
 
         for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) {
             Integer randomCheckpoint = list.get(i);
@@ -283,6 +282,8 @@ public abstract class AbstractCheckpointCollectionTest {
             long found = fCheckpointCollection.binarySearch(checkpoint);
             assertEquals(randomCheckpoint.intValue(), found);
         }
+
+        assertEquals(CHECKPOINTS_INSERT_NUM, fCheckpointCollection.size());
     }
 
     /**
@@ -295,8 +296,8 @@ public abstract class AbstractCheckpointCollectionTest {
             TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345), new TmfLongLocation(123456L + i), i);
             fCheckpointCollection.insert(checkpoint);
         }
+        assertEquals(CHECKPOINTS_INSERT_NUM, fCheckpointCollection.size());
 
-        fCheckpointCollection.setIndexComplete();
         if (isPersistableCollection()) {
             fCheckpointCollection.dispose();
         }
@@ -315,6 +316,7 @@ public abstract class AbstractCheckpointCollectionTest {
         if (isPersistableCollection()) {
             fCheckpointCollection = createCollection();
         }
+        assertEquals(CHECKPOINTS_INSERT_NUM, fCheckpointCollection.size());
 
         for (int i = 0; i < CHECKPOINTS_INSERT_NUM; i++) {
             Integer randomCheckpoint = list.get(i);
@@ -334,6 +336,7 @@ public abstract class AbstractCheckpointCollectionTest {
             TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(2 * i), new TmfLongLocation(2 * i), i);
             fCheckpointCollection.insert(checkpoint);
         }
+        assertEquals(CHECKPOINTS_INSERT_NUM, fCheckpointCollection.size());
 
         TmfCheckpoint searchedCheckpoint = new TmfCheckpoint(new TmfTimestamp(123), new TmfLongLocation(123L), 123);
         int expectedInsertionPoint = 61;
@@ -352,23 +355,53 @@ public abstract class AbstractCheckpointCollectionTest {
     @Test
     public void testBinarySearchInBetweenSameTimestamp() {
         int checkpointNum = 0;
-        for (; checkpointNum < 100; checkpointNum++) {
+        for (; checkpointNum < CHECKPOINTS_INSERT_NUM / 2; checkpointNum++) {
             TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(0), new TmfLongLocation(checkpointNum), checkpointNum);
             fCheckpointCollection.insert(checkpoint);
         }
 
-        for (; checkpointNum < 200; checkpointNum++) {
+        for (; checkpointNum < CHECKPOINTS_INSERT_NUM; checkpointNum++) {
             TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(1), new TmfLongLocation(checkpointNum), checkpointNum);
             fCheckpointCollection.insert(checkpoint);
         }
+        assertEquals(CHECKPOINTS_INSERT_NUM, fCheckpointCollection.size());
 
         final TmfCheckpoint searchedCheckpoint = new TmfCheckpoint(new TmfTimestamp(1), null, 0);
 
         long found = fCheckpointCollection.binarySearch(searchedCheckpoint);
 
-        int expectedInsertionPoint = 99;
+        int expectedInsertionPoint = CHECKPOINTS_INSERT_NUM / 2 - 1;
         int expectedRank = -(expectedInsertionPoint + 2);
 
         assertEquals(expectedRank, found);
     }
+
+    /**
+     * Test checkpoint insertions after reopening the file.
+     */
+    @Test
+    public void testInsertAfterReopen() {
+        if (!isPersistableCollection()) {
+            return;
+        }
+
+        fCheckpointCollection.insert(new TmfCheckpoint(new TmfTimestamp(12345), new TmfLongLocation(123456L), 0));
+
+        assertEquals(1, fCheckpointCollection.size());
+
+        fCheckpointCollection.dispose();
+        fCheckpointCollection = createCollection();
+        assertEquals(1, fCheckpointCollection.size());
+
+        TmfCheckpoint checkpoint = new TmfCheckpoint(new TmfTimestamp(12345), new TmfLongLocation(123456L), 0);
+        long found = fCheckpointCollection.binarySearch(checkpoint);
+        assertEquals(0, found);
+
+        fCheckpointCollection.insert(new TmfCheckpoint(new TmfTimestamp(12345 + 1), new TmfLongLocation(123456L + 1), 1));
+        assertEquals(2, fCheckpointCollection.size());
+
+        fCheckpointCollection.dispose();
+        fCheckpointCollection = createCollection();
+        assertEquals(2, fCheckpointCollection.size());
+    }
 }
index 111de2d15ab61d900a07c621336be9a0296e3d16..24aa14253df57bf1406035c1854fb85357355b43 100644 (file)
@@ -157,7 +157,6 @@ public class AllBench {
             }
 
             time += (System.currentTimeMillis() - old);
-            bTree.setIndexComplete();
             bTree.dispose();
             if (j != REPEAT - 1) {
                 file.delete();
@@ -183,7 +182,6 @@ public class AllBench {
             }
 
             time += (System.currentTimeMillis() - old);
-            array.setIndexComplete();
             array.dispose();
             if (j != REPEAT - 1) {
                 file.delete();
index 7763c480c087950e9323b266c4335ad802d86ebf..df4d697a0d4c330500755b916d3c96a792f81d44 100644 (file)
@@ -99,20 +99,4 @@ public class BTreeTest extends AbstractCheckpointCollectionTest {
             assertEquals(checkpoint, treeVisitor.getCheckpoint());
         }
     }
-
-    /**
-     * Test setSize, size
-     */
-    @Override
-    @Test
-    public void testSetGetSize() {
-        assertEquals(0, fBTree.size());
-        int expected = CHECKPOINTS_INSERT_NUM;
-        for (int i = 0; i < expected; ++i) {
-            fBTree.insert(new TmfCheckpoint(new TmfTimestamp(0), new TmfLongLocation(0L), 0));
-            fBTree.setSize(fBTree.size() + 1);
-        }
-        assertEquals(expected, fBTree.size());
-    }
-
 }
index d2bfe3d5eb77fd2ace7b999a2fd244cc5a3a17fc..629b327d414f056725bde3d41d29ee028a0b754f 100644 (file)
@@ -28,6 +28,8 @@ import org.eclipse.core.runtime.FileLocator;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
 import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
+import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
+import org.eclipse.tracecompass.tmf.core.signal.TmfTraceUpdatedSignal;
 import org.eclipse.tracecompass.tmf.core.tests.TmfCoreTestPlugin;
 import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestTrace;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
@@ -58,7 +60,16 @@ public abstract class AbstractIndexTest {
      *
      */
     protected static final int BLOCK_SIZE = 100;
-    private static final int NB_EVENTS = 10000;
+    /**
+     * The expected number of events in the test trace.
+     */
+    protected static final int NB_EVENTS = 10000;
+    /**
+     * Used to dispose the trace once the desired number of events has been
+     * reached in the trace. This has the wanted side effect of stopping the
+     * indexing once a number of events has been reached.
+     */
+    protected long fNbEventsLimit;
     /**
      * The trace being tested
      */
@@ -74,6 +85,7 @@ public abstract class AbstractIndexTest {
      */
     @Before
     public void setUp() {
+        fNbEventsLimit = Long.MAX_VALUE;
         setupTrace(getTracePath());
     }
 
@@ -162,6 +174,20 @@ public abstract class AbstractIndexTest {
         public ITestIndexer getIndexer() {
             return (ITestIndexer) super.getIndexer();
         }
+
+        /**
+         * Track the number of events in the trace in order to stop when the
+         * limit has been reached (fNbEventsLimit).
+         *
+         * @param signal
+         *            the TmfTraceUpdatedSignal
+         */
+        @TmfSignalHandler
+        public void testTraceUpdated(final TmfTraceUpdatedSignal signal) {
+            if (getNbEvents() >= fNbEventsLimit) {
+                dispose();
+            }
+        }
     }
 
     private class EmptyTestTrace extends TmfEmptyTraceStub {
@@ -254,6 +280,7 @@ public abstract class AbstractIndexTest {
         ITmfCheckpointIndex checkpoints = fTrace.getIndexer().getCheckpoints();
         int pageSize = fTrace.getCacheSize();
         assertTrue(checkpoints != null);
+        assertEquals(NB_EVENTS, checkpoints.getNbEvents());
         assertEquals(NB_EVENTS / BLOCK_SIZE, checkpoints.size());
 
         // Validate that each checkpoint points to the right event
index b83cbe8829ac541fee5f726ba679b565b46993aa..06bcc0e724b278fe74003bbf20be9154b63c4c47 100644 (file)
 
 package org.eclipse.tracecompass.tmf.core.tests.trace.indexer.checkpoint;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
+import java.io.File;
+
+import org.eclipse.tracecompass.internal.tmf.core.trace.indexer.BTree;
+import org.eclipse.tracecompass.internal.tmf.core.trace.indexer.FlatArray;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
 import org.eclipse.tracecompass.tmf.core.trace.indexer.TmfBTreeTraceIndexer;
 import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex;
 import org.junit.Test;
@@ -66,4 +73,34 @@ public class TmfBTreeIndexTest extends AbstractIndexTest {
         verifyIndexContent();
     }
 
+    /**
+     * Test that the indexer can resume from a partially built index reloaded
+     * from disk
+     *
+     * @throws Exception
+     *             when error occurs
+     */
+    @Test
+    public void testInsertAfterReopenIndex() throws Exception {
+        // Make sure we start from a completely non-existing index
+        fTrace.dispose();
+        String directory = TmfTraceManager.getSupplementaryFileDir(fTrace);
+        new File(directory + BTree.INDEX_FILE_NAME).delete();
+        new File(directory + FlatArray.INDEX_FILE_NAME).delete();
+
+        // Index half of the trace
+        fNbEventsLimit = NB_EVENTS / 2;
+        fTrace = createTrace(getTracePath());
+        assertTrue(fTrace.getIndexer().getCheckpoints().isCreatedFromScratch());
+        // The trace should not have been indexed completely
+        assertEquals(fNbEventsLimit, fTrace.getNbEvents());
+
+        // Finish indexing the trace
+        fNbEventsLimit = Long.MAX_VALUE;
+        fTrace = createTrace(getTracePath());
+        assertFalse(fTrace.getIndexer().getCheckpoints().isCreatedFromScratch());
+
+        verifyIndexContent();
+    }
+
 }
\ No newline at end of file
index e3a7c2346df565812b245399845b54438bc32d3d..e29997587a02a3babc2a1100855ad0e5450d4787 100644 (file)
@@ -33,7 +33,8 @@ import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfPersistentlyIndexable
  */
 public abstract class AbstractFileCheckpointCollection implements ICheckpointCollection {
 
-    private static final int VERSION = 2;
+    private static final int INVALID_VERSION = -1;
+    private static final int VERSION = 3;
     private static final int SUB_VERSION_NONE = -1;
 
     /**
@@ -43,7 +44,8 @@ public abstract class AbstractFileCheckpointCollection implements ICheckpointCol
         private static final int SIZE = INT_SIZE +
                 INT_SIZE +
                 LONG_SIZE +
-                LONG_SIZE;
+                LONG_SIZE +
+                MAX_TIME_RANGE_SERIALIZE_SIZE;
 
         /**
          * Get the size of the header in bytes. This should be overridden if the
@@ -76,7 +78,11 @@ public abstract class AbstractFileCheckpointCollection implements ICheckpointCol
             fVersion = randomAccessFile.readInt();
             fSize = randomAccessFile.readInt();
             fNbEvents = randomAccessFile.readLong();
-            fTimeRangeOffset = randomAccessFile.readLong();
+            ByteBuffer b = ByteBuffer.allocate(MAX_TIME_RANGE_SERIALIZE_SIZE);
+            b.clear();
+            fFileChannel.read(b);
+            b.flip();
+            fTimeRange = new TmfTimeRange(new TmfTimestamp(b), new TmfTimestamp(b));
         }
 
         /**
@@ -99,10 +105,17 @@ public abstract class AbstractFileCheckpointCollection implements ICheckpointCol
          */
         public void serialize(RandomAccessFile randomAccessFile) throws IOException {
             randomAccessFile.seek(0);
-            randomAccessFile.writeInt(getVersion());
+            // Version is written at the very last on dispose
+            randomAccessFile.writeInt(INVALID_VERSION);
             randomAccessFile.writeInt(fSize);
             randomAccessFile.writeLong(fNbEvents);
-            randomAccessFile.writeLong(fTimeRangeOffset);
+
+            ByteBuffer b = ByteBuffer.allocate(MAX_TIME_RANGE_SERIALIZE_SIZE);
+            b.clear();
+            new TmfTimestamp(fTimeRange.getStartTime()).serialize(b);
+            new TmfTimestamp(fTimeRange.getEndTime()).serialize(b);
+            b.rewind();
+            fFileChannel.write(b);
         }
 
         /**
@@ -114,14 +127,15 @@ public abstract class AbstractFileCheckpointCollection implements ICheckpointCol
          * The size of the collection expressed in a number of checkpoints.
          */
         protected int fSize = 0;
-        /**
-         * Offset in bytes where the time range is store
-         */
-        protected long fTimeRangeOffset;
         /**
          * The total number of events in the trace
          */
         protected long fNbEvents;
+
+        /**
+         * The time range of the trace.
+         */
+        protected TmfTimeRange fTimeRange = new TmfTimeRange(TmfTimestamp.ZERO, TmfTimestamp.ZERO);
     }
 
     /**
@@ -136,7 +150,7 @@ public abstract class AbstractFileCheckpointCollection implements ICheckpointCol
     /**
      * The maximum size of the serialize buffer when writing the time range
      */
-    protected static final int MAX_TIME_RANGE_SERIALIZE_SIZE = 1024;
+    protected static final int MAX_TIME_RANGE_SERIALIZE_SIZE = 128;
 
     /**
      * The originating trace
@@ -162,7 +176,6 @@ public abstract class AbstractFileCheckpointCollection implements ICheckpointCol
 
     // Cached values
     private FileChannel fFileChannel;
-    private TmfTimeRange fTimeRange;
 
     /**
      * Constructs a checkpoint collection for a given trace from scratch or from
@@ -247,9 +260,7 @@ public abstract class AbstractFileCheckpointCollection implements ICheckpointCol
 
             // Reserve space for header
             fRandomAccessFile.setLength(header.getSize());
-
-            fTimeRange = new TmfTimeRange(new TmfTimestamp(0), new TmfTimestamp(0));
-            TmfCoreTracer.traceIndexer(CheckpointCollectionFileHeader.class.getSimpleName() + " initialize " + "nbEvents: " + header.fNbEvents + " fTimeRangeOffset: " + header.fTimeRangeOffset + " fTimeRange: " + fTimeRange); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+            TmfCoreTracer.traceIndexer(CheckpointCollectionFileHeader.class.getSimpleName() + " initialize " + "nbEvents: " + header.fNbEvents + " fTimeRange: " + header.fTimeRange); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
         } catch (IOException e) {
             Activator.logError(MessageFormat.format(Messages.ErrorOpeningIndex, fFile), e);
             return null;
@@ -268,7 +279,7 @@ public abstract class AbstractFileCheckpointCollection implements ICheckpointCol
         CheckpointCollectionFileHeader header = null;
 
         try {
-            fRandomAccessFile = new RandomAccessFile(fFile, "r"); //$NON-NLS-1$
+            fRandomAccessFile = new RandomAccessFile(fFile, "rw"); //$NON-NLS-1$
             fFileChannel = fRandomAccessFile.getChannel();
         } catch (FileNotFoundException e) {
             Activator.logError(MessageFormat.format(Messages.ErrorOpeningIndex, fFile), e);
@@ -280,8 +291,12 @@ public abstract class AbstractFileCheckpointCollection implements ICheckpointCol
             if (header.fVersion != VERSION || header.getSubVersion() != getSubVersion()) {
                 return null;
             }
-            serializeInTimeRange(header);
-            TmfCoreTracer.traceIndexer(CheckpointCollectionFileHeader.class.getSimpleName() + " read " + fFile + " nbEvents: " + header.fNbEvents + " fTimeRangeOffset: " + header.fTimeRangeOffset + " fTimeRange: " + fTimeRange); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+            TmfCoreTracer.traceIndexer(CheckpointCollectionFileHeader.class.getSimpleName() + " read " + fFile + " nbEvents: " + header.fNbEvents + " fTimeRange: " + header.fTimeRange); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+            // Write an invalid version until the very last moment when dispose
+            // the index. This is how we know if it's corrupted or not.
+            fRandomAccessFile.seek(0);
+            fRandomAccessFile.writeInt(INVALID_VERSION);
         } catch (IOException e) {
             Activator.logError(MessageFormat.format(Messages.IOErrorReadingHeader, fFile), e);
             return null;
@@ -290,38 +305,6 @@ public abstract class AbstractFileCheckpointCollection implements ICheckpointCol
         return header;
     }
 
-    private void serializeInTimeRange(CheckpointCollectionFileHeader header) throws IOException {
-        ByteBuffer b = ByteBuffer.allocate(MAX_TIME_RANGE_SERIALIZE_SIZE);
-        b.clear();
-        fFileChannel.read(b, header.fTimeRangeOffset);
-        b.flip();
-        fTimeRange = new TmfTimeRange(new TmfTimestamp(b), new TmfTimestamp(b));
-    }
-
-    private void serializeOutTimeRange() throws IOException {
-        fHeader.fTimeRangeOffset = fRandomAccessFile.length();
-        ByteBuffer b = ByteBuffer.allocate(MAX_TIME_RANGE_SERIALIZE_SIZE);
-        b.clear();
-        new TmfTimestamp(fTimeRange.getStartTime()).serialize(b);
-        new TmfTimestamp(fTimeRange.getEndTime()).serialize(b);
-        b.flip();
-        fFileChannel.write(b, fHeader.fTimeRangeOffset);
-    }
-
-    /**
-     * Set the index as complete. No more checkpoints will be inserted.
-     */
-    @Override
-    public void setIndexComplete() {
-        try {
-            serializeOutTimeRange();
-
-            fHeader.serialize(fRandomAccessFile);
-        } catch (IOException e) {
-            Activator.logError(MessageFormat.format(Messages.IOErrorWritingHeader, fFile), e);
-        }
-    }
-
     /**
      *
      * @return true if the checkpoint collection was created from scratch, false
@@ -375,7 +358,7 @@ public abstract class AbstractFileCheckpointCollection implements ICheckpointCol
      */
     @Override
     public void setTimeRange(TmfTimeRange timeRange) {
-        fTimeRange = timeRange;
+        fHeader.fTimeRange = timeRange;
     }
 
     /**
@@ -385,7 +368,7 @@ public abstract class AbstractFileCheckpointCollection implements ICheckpointCol
      */
     @Override
     public TmfTimeRange getTimeRange() {
-        return fTimeRange;
+        return fHeader.fTimeRange;
     }
 
     /**
@@ -452,7 +435,9 @@ public abstract class AbstractFileCheckpointCollection implements ICheckpointCol
      */
     public CheckpointCollectionFileHeader getHeader() {
         return fHeader;
-    }/**
+    }
+
+    /**
      * Dispose and delete the checkpoint collection
      */
     @Override
@@ -470,11 +455,18 @@ public abstract class AbstractFileCheckpointCollection implements ICheckpointCol
     public void dispose() {
         try {
             if (fRandomAccessFile != null) {
+                if (fHeader != null) {
+                    fHeader.serialize(fRandomAccessFile);
+                }
+
+                fRandomAccessFile.seek(0);
+                fRandomAccessFile.writeInt(getVersion());
+
                 fRandomAccessFile.close();
             }
             setCreatedFromScratch(true);
             fRandomAccessFile = null;
-            String headerTrace = fHeader == null ? "" : "nbEvents: " + fHeader.fNbEvents + " timerange:" + fTimeRange; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            String headerTrace = fHeader == null ? "" : "nbEvents: " + fHeader.fNbEvents + " timerange:" + fHeader.fTimeRange; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
             TmfCoreTracer.traceIndexer(this.getClass().getSimpleName() + " disposed. " + headerTrace); //$NON-NLS-1$
         } catch (IOException e) {
             Activator.logError(MessageFormat.format(Messages.IOErrorClosingIndex, fFile), e);
index 9623c65814a32e02a0c7a57ddf9540a0a18493af..682faca6e74391c432c01384ee4d29cc8a8f2998 100644 (file)
@@ -243,6 +243,8 @@ public class BTree extends AbstractFileCheckpointCollection {
                 }
             }
             node.setEntry(i, checkpoint);
+            CheckpointCollectionFileHeader header = getHeader();
+            ++header.fSize;
             return;
         }
     }
@@ -339,16 +341,6 @@ public class BTree extends AbstractFileCheckpointCollection {
         return;
     }
 
-    /**
-     * Set the index as complete. No more checkpoints will be inserted.
-     */
-    @Override
-    public void setIndexComplete() {
-        super.setIndexComplete();
-
-        fNodeCache.serialize();
-    }
-
     /**
      * Get the maximum number of entries in a node
      *
@@ -358,16 +350,6 @@ public class BTree extends AbstractFileCheckpointCollection {
         return fMaxNumEntries;
     }
 
-    /**
-     * Set the size of the BTree, expressed as a number of checkpoints
-     *
-     * @param size
-     *            the size of the BTree
-     */
-    public void setSize(int size) {
-        fBTreeHeader.fSize = size;
-    }
-
     /**
      * Get the maximum number of children in a node
      *
@@ -380,4 +362,13 @@ public class BTree extends AbstractFileCheckpointCollection {
     ByteBuffer getNodeByteBuffer() {
         return fNodeByteBuffer;
     }
+
+    @Override
+    public void dispose() {
+        if (fNodeCache != null) {
+            fNodeCache.serialize();
+        }
+
+        super.dispose();
+    }
 }
index 0cd450812dc3a3f430f120d1e8bc6e7541d966d2..d3abf5b58fd608ccaf70ea6c649a9e794bfa238a 100644 (file)
@@ -82,11 +82,6 @@ public interface ICheckpointCollection {
      */
     long getNbEvents();
 
-    /**
-     * Set the index as complete. No more checkpoints will be inserted.
-     */
-    void setIndexComplete();
-
     /**
      * Dispose the collection and delete persistent data (file)
      */
index a57523a436580b9c2432c761f2a6fd0da5ce0abb..6f03ed2c5e255566d19195f1e60262f45b18b787 100644 (file)
@@ -17,6 +17,7 @@ import java.util.Collections;
 import java.util.List;
 
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
+import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint;
 import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpointIndex;
@@ -29,6 +30,8 @@ import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint
 public class TmfMemoryIndex implements ITmfCheckpointIndex, ICheckpointCollection {
 
     private final List<ITmfCheckpoint> fCheckpoints;
+    private TmfTimeRange fTimeRange;
+    private long fNbEvents;
 
     /**
      * Creates an index for the given trace
@@ -37,6 +40,8 @@ public class TmfMemoryIndex implements ITmfCheckpointIndex, ICheckpointCollectio
      */
     public TmfMemoryIndex(ITmfTrace trace) {
         fCheckpoints = new ArrayList<>();
+        fTimeRange = new TmfTimeRange(TmfTimestamp.ZERO, TmfTimestamp.ZERO);
+        fNbEvents = 0;
     }
 
     @Override
@@ -76,24 +81,22 @@ public class TmfMemoryIndex implements ITmfCheckpointIndex, ICheckpointCollectio
 
     @Override
     public void setTimeRange(TmfTimeRange timeRange) {
+        fTimeRange = timeRange;
     }
 
     @Override
     public void setNbEvents(long nbEvents) {
+        fNbEvents = nbEvents;
     }
 
     @Override
     public TmfTimeRange getTimeRange() {
-        return null;
+        return fTimeRange;
     }
 
     @Override
     public long getNbEvents() {
-        return 0;
-    }
-
-    @Override
-    public void setIndexComplete() {
+        return fNbEvents;
     }
 
     @Override
index 6a14eb85c3bb464eb32f76a0d19583ee24022db3..1a299afb5de4a254701c800fad58928bd4744761 100644 (file)
@@ -81,7 +81,6 @@ public class TmfBTreeTraceIndex implements ITmfCheckpointIndex {
     public void insert(ITmfCheckpoint checkpoint) {
         fCheckpoints.insert(checkpoint);
         fCheckpointRanks.insert(checkpoint);
-        fCheckpoints.setSize(fCheckpoints.size() + 1);
     }
 
     @Override
@@ -128,11 +127,4 @@ public class TmfBTreeTraceIndex implements ITmfCheckpointIndex {
     public long getNbEvents() {
         return fCheckpoints.getNbEvents();
     }
-
-    @Override
-    public void setIndexComplete() {
-        fCheckpoints.setIndexComplete();
-        fCheckpointRanks.setIndexComplete();
-    }
-
 }
index 7013b37a834ae5014a9bedcc00801a63c44cce5f..5ea149ee9a9cd5a5ba510944ffa5b64bc9348a44 100644 (file)
@@ -102,10 +102,4 @@ public class TmfFlatArrayTraceIndex implements ITmfCheckpointIndex {
     public long getNbEvents() {
         return fCheckpoints.getNbEvents();
     }
-
-    @Override
-    public void setIndexComplete() {
-        fCheckpoints.setIndexComplete();
-    }
-
 }
index 492f8423eaf1e7e0998cce846cf9788508bc61f4..16acb38d9dfb406f7fbb8d9a1a6a3b0bd8e4deb7 100644 (file)
@@ -109,9 +109,4 @@ public interface ITmfCheckpointIndex {
      * @return the total number of events
      */
     long getNbEvents();
-
-    /**
-     * Set the index as complete. No more checkpoints will be inserted.
-     */
-    void setIndexComplete();
 }
index 1b0d9636c7f0a39d0b695dad65cec246aa2e79d7..7e7f603524aac330812db5790beb3373af9e1964 100644 (file)
@@ -28,9 +28,9 @@ import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest;
 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceUpdatedSignal;
 import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
+import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
-import org.eclipse.tracecompass.tmf.core.trace.ITmfTraceCompleteness;
 import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer;
 import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation;
 
@@ -78,6 +78,9 @@ public class TmfCheckpointIndexer implements ITmfTraceIndexer {
      */
     private ITmfEventRequest fIndexingRequest = null;
 
+    /** Whether or not the index was built once */
+    private boolean fBuiltOnce;
+
     // ------------------------------------------------------------------------
     // Construction
     // ------------------------------------------------------------------------
@@ -141,6 +144,9 @@ public class TmfCheckpointIndexer implements ITmfTraceIndexer {
     @Override
     public void buildIndex(final long offset, final TmfTimeRange range, final boolean waitForCompletion) {
 
+        long indexingOffset = offset;
+        TmfTimeRange indexingTimeRange = range;
+
         // Don't do anything if we are already indexing
         synchronized (fTraceIndex) {
             if (fIsIndexing) {
@@ -149,21 +155,17 @@ public class TmfCheckpointIndexer implements ITmfTraceIndexer {
             fIsIndexing = true;
         }
 
-        // No need to build the index, it has been restored
-        if (!fTraceIndex.isCreatedFromScratch()) {
+        // Restore previously built index values
+        if (!fTraceIndex.isCreatedFromScratch() && !fBuiltOnce && fTraceIndex.getNbEvents() > 0) {
+            indexingOffset = fTraceIndex.getNbEvents();
+            indexingTimeRange = new TmfTimeRange(fTraceIndex.getTimeRange().getStartTime(), TmfTimestamp.BIG_CRUNCH);
+            TmfCoreTracer.traceIndexer("restoring index. nbEvents: " + fTraceIndex.getNbEvents() + " time range: " + fTraceIndex.getTimeRange()); //$NON-NLS-1$ //$NON-NLS-2$
             // Set some trace attributes that depends on indexing
-            TmfCoreTracer.traceIndexer("Restoring index. nbEvents: " + fTraceIndex.getNbEvents() + " time range: " + fTraceIndex.getTimeRange()); //$NON-NLS-1$ //$NON-NLS-2$
-            TmfTraceUpdatedSignal signal = new TmfTraceUpdatedSignal(this, fTrace, new TmfTimeRange(fTraceIndex.getTimeRange().getStartTime(), fTraceIndex.getTimeRange().getEndTime()), fTraceIndex.getNbEvents());
-            if (waitForCompletion) {
-                fTrace.broadcast(signal);
-            } else {
-                fTrace.broadcastAsync(signal);
-            }
-            fIsIndexing = false;
-            return;
+            TmfTraceUpdatedSignal signal = new TmfTraceUpdatedSignal(this, fTrace, new TmfTimeRange(fTraceIndex.getTimeRange().getStartTime(), fTraceIndex.getTimeRange().getEndTime()), indexingOffset);
+            fTrace.broadcast(signal);
         }
 
-        TmfCoreTracer.traceIndexer("buildIndex. offset: " + offset + " time range: " + range); //$NON-NLS-1$ //$NON-NLS-2$
+        TmfCoreTracer.traceIndexer("buildIndex. offset: " + indexingOffset + " (requested " + offset + ")" + " time range: " + range); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
 
         // The monitoring job
         final Job job = new Job("Indexing " + fTrace.getName() + "...") { //$NON-NLS-1$ //$NON-NLS-2$
@@ -187,13 +189,14 @@ public class TmfCheckpointIndexer implements ITmfTraceIndexer {
                 return Status.OK_STATUS;
             }
         };
-        job.setSystem(!isCompleteTrace(fTrace));
+        job.setSystem(fBuiltOnce);
+        fBuiltOnce = true;
         job.schedule();
 
         // Build a background request for all the trace data. The index is
         // updated as we go by readNextEvent().
         fIndexingRequest = new TmfEventRequest(ITmfEvent.class,
-                range, offset, ITmfEventRequest.ALL_DATA,
+                indexingTimeRange, indexingOffset, ITmfEventRequest.ALL_DATA,
                 ITmfEventRequest.ExecutionType.BACKGROUND) {
             @Override
             public void handleData(final ITmfEvent event) {
@@ -206,20 +209,17 @@ public class TmfCheckpointIndexer implements ITmfTraceIndexer {
 
             @Override
             public void handleSuccess() {
-                fTraceIndex.setTimeRange(fTrace.getTimeRange());
-                fTraceIndex.setNbEvents(fTrace.getNbEvents());
-                if (isCompleteTrace(fTrace)) {
-                    fTraceIndex.setIndexComplete();
-                }
                 updateTraceStatus();
             }
 
             @Override
             public void handleCompleted() {
                 job.cancel();
+                fTraceIndex.setTimeRange(fTrace.getTimeRange());
+                fTraceIndex.setNbEvents(fTrace.getNbEvents());
                 super.handleCompleted();
                 fIsIndexing = false;
-                TmfCoreTracer.traceIndexer("Build index request done. nbEvents: " + fTraceIndex.getNbEvents() + " time range: " + fTraceIndex.getTimeRange()); //$NON-NLS-1$ //$NON-NLS-2$
+                TmfCoreTracer.traceIndexer("Build index request completed. nbEvents: " + fTraceIndex.getNbEvents() + " time range: " + fTraceIndex.getTimeRange()); //$NON-NLS-1$ //$NON-NLS-2$
             }
 
             private void updateTraceStatus() {
@@ -344,8 +344,4 @@ public class TmfCheckpointIndexer implements ITmfTraceIndexer {
     protected ITmfCheckpointIndex getTraceIndex() {
         return fTraceIndex;
     }
-
-    private static boolean isCompleteTrace(ITmfTrace trace) {
-        return !(trace instanceof ITmfTraceCompleteness) || ((ITmfTraceCompleteness)trace).isComplete();
-    }
 }
This page took 0.040563 seconds and 5 git commands to generate.