lttng: fix NPE when segment selection is null
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.timing.core / src / org / eclipse / tracecompass / analysis / timing / core / segmentstore / AbstractSegmentStoreAnalysisModule.java
CommitLineData
152630e0
BH
1/*******************************************************************************
2 * Copyright (c) 2015 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
9package org.eclipse.tracecompass.analysis.timing.core.segmentstore;
10
11import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
12
13import java.io.IOException;
14import java.io.ObjectInputStream;
15import java.io.ObjectOutputStream;
16import java.nio.file.Files;
17import java.nio.file.Path;
18import java.nio.file.Paths;
18c18ee0 19import java.util.Collection;
152630e0
BH
20import java.util.HashSet;
21import java.util.Set;
22
23import org.eclipse.core.runtime.IProgressMonitor;
24import org.eclipse.jdt.annotation.Nullable;
25import org.eclipse.tracecompass.segmentstore.core.ISegment;
26import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
27import org.eclipse.tracecompass.segmentstore.core.treemap.TreeMapStore;
28import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule;
29import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
30import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
31import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest;
32import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest;
18c18ee0 33import org.eclipse.tracecompass.tmf.core.segment.ISegmentAspect;
152630e0
BH
34import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
35import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
36
18c18ee0
BH
37import com.google.common.collect.ImmutableList;
38
152630e0
BH
39/**
40 * Abstract analysis module to generate a segment store. It is a base class that
41 * can be used as a shortcut by analysis who just need to build a single segment
42 * store.
43 *
44 * @author Bernd Hufmann
45 * @since 2.0
46 *
47 */
48public abstract class AbstractSegmentStoreAnalysisModule extends TmfAbstractAnalysisModule {
49
50 private final Set<IAnalysisProgressListener> fListeners = new HashSet<>();
51
52 private @Nullable ISegmentStore<ISegment> fSegmentStore;
53
54 private @Nullable ITmfEventRequest fOngoingRequest = null;
55
56 /**
57 * Listener for the viewers
58 *
59 * @param listener
60 * listener for each type of viewer
61 */
62 public void addListener(IAnalysisProgressListener listener) {
63 fListeners.add(listener);
64 }
65
66 /**
67 * Returns all the listeners
68 * @return latency listners
69 */
70 public Iterable<IAnalysisProgressListener> getListeners() {
71 return fListeners;
72 }
73
18c18ee0
BH
74 /**
75 * Return the pre-defined set of segment aspects exposed by this analysis.
76 *
77 * It should not be null, but could be empty.
78 * @return The segment aspects for this analysis
79 */
80 public Iterable<ISegmentAspect> getSegmentAspects() {
81 Collection<ISegmentAspect> coll = ImmutableList.of();
82 return checkNotNull(coll);
83 }
84
152630e0
BH
85 /**
86 * Returns the file name for storing segment store
87 * @return segment store fine name
88 */
89 public abstract String getDataFileName();
90
91 /**
92 * Returns the analysis request for creating the segment store
93 * @param segmentStore
94 * a segment store to fill
95 * @return the segment store analysis request implementation
96 */
97 public abstract AbstractSegmentStoreAnalysisRequest createAnalysisRequest(ISegmentStore<ISegment> segmentStore);
98
99 /**
100 * Read an object from the ObjectInputStream.
101 *
102 * @param ois
103 * the ObjectInputStream to used
104 * @return the read object
105 * @throws ClassNotFoundException
106 * - Class of a serialized object cannot be found.
107 * @throws IOException
108 * - Any of the usual Input/Output related exceptions.
109 */
110 protected abstract Object[] readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException;
111
112 /**
113 * Returns the result in a from the analysis in a ISegmentStore
114 * @return Results from the analysis in a ISegmentStore
115 */
116 public @Nullable ISegmentStore<ISegment> getResults() {
117 return fSegmentStore;
118 }
119
120 @Override
121 protected void canceling() {
122 ITmfEventRequest req = fOngoingRequest;
123 if ((req != null) && (!req.isCompleted())) {
124 req.cancel();
125 }
126 }
127
73f1f3ea
BH
128 @Override
129 public void dispose() {
130 super.dispose();
131 ISegmentStore<ISegment> store = fSegmentStore;
132 if (store != null) {
133 store.dispose();
134 }
135 }
136
152630e0
BH
137 @Override
138 protected boolean executeAnalysis(IProgressMonitor monitor) throws TmfAnalysisException {
139 ITmfTrace trace = checkNotNull(getTrace());
140
141 /* See if the data file already exists on disk */
142 String dir = TmfTraceManager.getSupplementaryFileDir(trace);
143 final Path file = Paths.get(dir, getDataFileName());
144
145 if (Files.exists(file)) {
146 /* Attempt to read the existing file */
147 try (ObjectInputStream ois = new ObjectInputStream(Files.newInputStream(file))) {
148 Object[] segmentArray = readObject(ois);
149 final ISegmentStore<ISegment> store = new TreeMapStore<>();
150 for (Object element : segmentArray) {
151 if (element instanceof ISegment) {
152 ISegment segment = (ISegment) element;
153 store.add(segment);
154 }
155 }
156 fSegmentStore = store;
157 for (IAnalysisProgressListener listener : getListeners()) {
158 listener.onComplete(this, store);
159 }
160 return true;
161 } catch (IOException | ClassNotFoundException | ClassCastException e) {
162 /*
163 * We did not manage to read the file successfully, we will just
164 * fall-through to rebuild a new one.
165 */
166 try {
167 Files.delete(file);
168 } catch (IOException e1) {
169 }
170 }
171 }
172
173 ISegmentStore<ISegment> syscalls = new TreeMapStore<>();
174
175 /* Cancel an ongoing request */
176 ITmfEventRequest req = fOngoingRequest;
177 if ((req != null) && (!req.isCompleted())) {
178 req.cancel();
179 }
180
181 /* Create a new request */
182 req = createAnalysisRequest(syscalls);
183 fOngoingRequest = req;
184 trace.sendRequest(req);
185
186 try {
187 req.waitForCompletion();
188 } catch (InterruptedException e) {
189 }
190
191 /* Do not process the results if the request was cancelled */
192 if (req.isCancelled() || req.isFailed()) {
193 return false;
194 }
195
196 /* The request will fill 'syscalls' */
197 fSegmentStore = syscalls;
198
199 /* Serialize the collections to disk for future usage */
200 try (ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(file))) {
201 oos.writeObject(syscalls.toArray());
202 } catch (IOException e) {
203 /* Didn't work, oh well. We will just re-read the trace next time */
204 }
205
206 for (IAnalysisProgressListener listener : getListeners()) {
207 listener.onComplete(this, syscalls);
208 }
209
210 return true;
211 }
212
213 /**
214 * Abstract event request to fill a a segment store
215 */
216 public static abstract class AbstractSegmentStoreAnalysisRequest extends TmfEventRequest {
217
218 private final ISegmentStore<ISegment> fFullLatencyStore;
219
220 /**
221 * Constructor
222 *
223 * @param latencyStore
224 * a latency segment store to fill
225 */
226 public AbstractSegmentStoreAnalysisRequest(ISegmentStore<ISegment> latencyStore) {
227 super(ITmfEvent.class, 0, ITmfEventRequest.ALL_DATA, ExecutionType.BACKGROUND);
228 /*
229 * We do NOT make a copy here! We want to modify the list that was
230 * passed in parameter.
231 */
232 fFullLatencyStore = latencyStore;
233 }
234
235 /**
236 * Returns the segment store
237 * @return the segment store
238 */
239 public ISegmentStore<ISegment> getSegmentStore() {
240 return fFullLatencyStore;
241 }
242 }
243}
This page took 0.048326 seconds and 5 git commands to generate.