1 /*******************************************************************************
2 * Copyright (c) 2013 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Marc-Andre Laperle - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.internal
.tmf
.core
.trace
.indexer
;
16 import java
.io
.IOException
;
17 import java
.nio
.ByteBuffer
;
18 import java
.text
.MessageFormat
;
20 import org
.eclipse
.linuxtools
.internal
.tmf
.core
.Activator
;
21 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.ITmfTimestamp
;
22 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.TmfTimestamp
;
23 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.indexer
.ITmfPersistentlyIndexable
;
24 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.indexer
.checkpoint
.ITmfCheckpoint
;
25 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.indexer
.checkpoint
.TmfCheckpoint
;
26 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.location
.ITmfLocation
;
29 * An array of checkpoints stored on disk. It is very efficient for searching
30 * checkpoints by rank (O(1))
32 * @author Marc-Andre Laperle
34 public class FlatArray
extends AbstractFileCheckpointCollection
{
36 * Typical FlatArray file name
38 public static final String INDEX_FILE_NAME
= "checkpoint_flatarray.idx"; //$NON-NLS-1$
41 private int fCheckpointSize
= 0;
42 private ByteBuffer fByteBuffer
;
45 * Constructs a FlatArray for a given trace from scratch or from an existing
46 * file. When the FlatArray is created from scratch, it is populated by
47 * subsequent calls to {@link #insert}.
50 * the file to use as the persistent storage
54 public FlatArray(File file
, ITmfPersistentlyIndexable trace
) {
57 fCheckpointSize
= getTrace().getCheckpointSize();
58 fByteBuffer
= ByteBuffer
.allocate(fCheckpointSize
);
63 * Insert a checkpoint into the file-backed array
66 * the checkpoint to insert
69 public void insert(ITmfCheckpoint checkpoint
) {
71 CheckpointCollectionFileHeader header
= getHeader();
73 getRandomAccessFile().seek(getRandomAccessFile().length());
75 checkpoint
.serialize(fByteBuffer
);
76 getRandomAccessFile().write(fByteBuffer
.array());
77 } catch (IOException e
) {
78 Activator
.logError(MessageFormat
.format(Messages
.FlatArray_IOErrorWriting
, getFile()), e
);
83 * Get a checkpoint from a rank
87 * @return the checkpoint that has been found or null if not found
89 public ITmfCheckpoint
get(long rank
) {
90 ITmfCheckpoint checkpoint
= null;
92 long pos
= getHeader().getSize() + fCheckpointSize
* rank
;
93 getRandomAccessFile().seek(pos
);
95 getRandomAccessFile().read(fByteBuffer
.array());
96 ITmfLocation location
= getTrace().restoreLocation(fByteBuffer
);
97 ITmfTimestamp timeStamp
= new TmfTimestamp(fByteBuffer
);
98 checkpoint
= new TmfCheckpoint(timeStamp
, location
, fByteBuffer
);
99 } catch (IOException e
) {
100 Activator
.logError(MessageFormat
.format(Messages
.FlatArray_IOErrorReading
, getFile()), e
);
106 * Search for a checkpoint and return the rank.
109 * the checkpoint to search
110 * @return the checkpoint rank of the searched checkpoint, if it is
111 * contained in the index; otherwise, (-(insertion point) - 1).
114 public long binarySearch(ITmfCheckpoint checkpoint
) {
115 if (getHeader().fSize
== 1) {
120 long upper
= getHeader().fSize
- 1;
121 long lastMiddle
= -1;
123 while (lower
<= upper
&& lastMiddle
!= middle
) {
125 middle
= (lower
+ upper
) / 2;
126 ITmfCheckpoint found
= get(middle
);
128 int compare
= checkpoint
.compareTo(found
);
139 long insertionPoint
= lower
;
140 return -(insertionPoint
) - 1;