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