tmf: Bug 495219: Fix NPE in checkpoint indexer seeking on disposed trace
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / internal / tmf / core / trace / indexer / FlatArray.java
CommitLineData
032ecd45 1/*******************************************************************************
7b3400bd 2 * Copyright (c) 2013, 2016 Ericsson
032ecd45
MAL
3 *
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
8 *
9 * Contributors:
10 * Marc-Andre Laperle - Initial API and implementation
11 *******************************************************************************/
12
2bdf0193 13package org.eclipse.tracecompass.internal.tmf.core.trace.indexer;
032ecd45
MAL
14
15import java.io.File;
16import java.io.IOException;
17import java.nio.ByteBuffer;
18import java.text.MessageFormat;
19
2bdf0193
AM
20import org.eclipse.tracecompass.internal.tmf.core.Activator;
21import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
22import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
23import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfPersistentlyIndexable;
24import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint;
25import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpoint;
26import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation;
032ecd45
MAL
27
28/**
29 * An array of checkpoints stored on disk. It is very efficient for searching
30 * checkpoints by rank (O(1))
31 *
32 * @author Marc-Andre Laperle
33 */
34public class FlatArray extends AbstractFileCheckpointCollection {
35 /**
36 * Typical FlatArray file name
37 */
38 public static final String INDEX_FILE_NAME = "checkpoint_flatarray.idx"; //$NON-NLS-1$
39
40 // Cached values
41 private int fCheckpointSize = 0;
42 private ByteBuffer fByteBuffer;
43
44 /**
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}.
48 *
49 * @param file
50 * the file to use as the persistent storage
51 * @param trace
52 * the trace
53 */
54 public FlatArray(File file, ITmfPersistentlyIndexable trace) {
55 super(file, trace);
56
57 fCheckpointSize = getTrace().getCheckpointSize();
58 fByteBuffer = ByteBuffer.allocate(fCheckpointSize);
59 fByteBuffer.clear();
60 }
61
62 /**
63 * Insert a checkpoint into the file-backed array
64 *
65 * @param checkpoint
66 * the checkpoint to insert
67 */
68 @Override
69 public void insert(ITmfCheckpoint checkpoint) {
70 try {
71 CheckpointCollectionFileHeader header = getHeader();
72 ++header.fSize;
73 getRandomAccessFile().seek(getRandomAccessFile().length());
74 fByteBuffer.clear();
75 checkpoint.serialize(fByteBuffer);
76 getRandomAccessFile().write(fByteBuffer.array());
77 } catch (IOException e) {
78 Activator.logError(MessageFormat.format(Messages.FlatArray_IOErrorWriting, getFile()), e);
79 }
80 }
81
82 /**
83 * Get a checkpoint from a rank
84 *
85 * @param rank
86 * the rank to search
87 * @return the checkpoint that has been found or null if not found
88 */
89 public ITmfCheckpoint get(long rank) {
90 ITmfCheckpoint checkpoint = null;
91 try {
92 long pos = getHeader().getSize() + fCheckpointSize * rank;
7b3400bd
PT
93 if (getRandomAccessFile() == null) {
94 return null;
95 }
032ecd45
MAL
96 getRandomAccessFile().seek(pos);
97 fByteBuffer.clear();
98 getRandomAccessFile().read(fByteBuffer.array());
99 ITmfLocation location = getTrace().restoreLocation(fByteBuffer);
b2c971ec 100 ITmfTimestamp timeStamp = TmfTimestamp.create(fByteBuffer);
032ecd45
MAL
101 checkpoint = new TmfCheckpoint(timeStamp, location, fByteBuffer);
102 } catch (IOException e) {
103 Activator.logError(MessageFormat.format(Messages.FlatArray_IOErrorReading, getFile()), e);
104 }
105 return checkpoint;
106 }
107
108 /**
109 * Search for a checkpoint and return the rank.
110 *
111 * @param checkpoint
112 * the checkpoint to search
113 * @return the checkpoint rank of the searched checkpoint, if it is
114 * contained in the index; otherwise, (-(insertion point) - 1).
115 */
116 @Override
117 public long binarySearch(ITmfCheckpoint checkpoint) {
118 if (getHeader().fSize == 1) {
119 return 0;
120 }
121
122 long lower = 0;
123 long upper = getHeader().fSize - 1;
124 long lastMiddle = -1;
125 long middle = 0;
126 while (lower <= upper && lastMiddle != middle) {
127 lastMiddle = middle;
128 middle = (lower + upper) / 2;
129 ITmfCheckpoint found = get(middle);
130 incCacheMisses();
131 int compare = checkpoint.compareTo(found);
132 if (compare == 0) {
133 return middle;
134 }
135
136 if (compare < 0) {
137 upper = middle;
138 } else {
139 lower = middle + 1;
140 }
141 }
3a324705 142 return -(lower) - 1;
032ecd45
MAL
143 }
144}
This page took 0.083515 seconds and 5 git commands to generate.