Commit | Line | Data |
---|---|---|
152630e0 | 1 | /******************************************************************************* |
65a4afc0 | 2 | * Copyright (c) 2015, 2016 Ericsson |
152630e0 BH |
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; | |
76be6c00 | 19 | import java.util.ArrayList; |
0f769d2b | 20 | import java.util.Collections; |
76be6c00 | 21 | import java.util.List; |
152630e0 BH |
22 | |
23 | import org.eclipse.core.runtime.IProgressMonitor; | |
76be6c00 | 24 | import org.eclipse.core.runtime.ListenerList; |
152630e0 BH |
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; | |
152630e0 | 30 | import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; |
18c18ee0 | 31 | import org.eclipse.tracecompass.tmf.core.segment.ISegmentAspect; |
152630e0 BH |
32 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; |
33 | import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; | |
34 | ||
35 | /** | |
36 | * Abstract analysis module to generate a segment store. It is a base class that | |
37 | * can be used as a shortcut by analysis who just need to build a single segment | |
38 | * store. | |
39 | * | |
40 | * @author Bernd Hufmann | |
41 | * @since 2.0 | |
42 | * | |
43 | */ | |
0f769d2b | 44 | public abstract class AbstractSegmentStoreAnalysisModule extends TmfAbstractAnalysisModule implements ISegmentStoreProvider { |
152630e0 | 45 | |
76be6c00 | 46 | private final ListenerList fListeners = new ListenerList(ListenerList.IDENTITY); |
152630e0 BH |
47 | |
48 | private @Nullable ISegmentStore<ISegment> fSegmentStore; | |
49 | ||
0f769d2b | 50 | @Override |
152630e0 BH |
51 | public void addListener(IAnalysisProgressListener listener) { |
52 | fListeners.add(listener); | |
53 | } | |
54 | ||
0f769d2b | 55 | @Override |
76be6c00 BH |
56 | public void removeListener(IAnalysisProgressListener listener) { |
57 | fListeners.remove(listener); | |
58 | } | |
59 | ||
152630e0 BH |
60 | /** |
61 | * Returns all the listeners | |
07b705e8 | 62 | * |
76be6c00 | 63 | * @return latency listeners |
152630e0 | 64 | */ |
cabc09fe | 65 | protected Iterable<IAnalysisProgressListener> getListeners() { |
76be6c00 BH |
66 | List<IAnalysisProgressListener> listeners = new ArrayList<>(); |
67 | for (Object listener : fListeners.getListeners()) { | |
aa353506 AM |
68 | if (listener != null) { |
69 | listeners.add((IAnalysisProgressListener) listener); | |
70 | } | |
76be6c00 BH |
71 | } |
72 | return listeners; | |
152630e0 BH |
73 | } |
74 | ||
0f769d2b | 75 | @Override |
18c18ee0 | 76 | public Iterable<ISegmentAspect> getSegmentAspects() { |
0f769d2b | 77 | return Collections.emptyList(); |
18c18ee0 BH |
78 | } |
79 | ||
152630e0 BH |
80 | /** |
81 | * Returns the file name for storing segment store | |
07b705e8 MK |
82 | * |
83 | * @return segment store fine name, or null if you don't want a file | |
152630e0 | 84 | */ |
07b705e8 MK |
85 | protected @Nullable String getDataFileName() { |
86 | return null; | |
87 | } | |
152630e0 | 88 | |
152630e0 BH |
89 | /** |
90 | * Read an object from the ObjectInputStream. | |
91 | * | |
92 | * @param ois | |
93 | * the ObjectInputStream to used | |
94 | * @return the read object | |
95 | * @throws ClassNotFoundException | |
96 | * - Class of a serialized object cannot be found. | |
97 | * @throws IOException | |
98 | * - Any of the usual Input/Output related exceptions. | |
99 | */ | |
100 | protected abstract Object[] readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException; | |
101 | ||
65a4afc0 JCK |
102 | /** |
103 | * Fills the segment store. This is the main method that children classes | |
104 | * need to implement to build the segment store. For example, if the | |
105 | * segments are found by parsing the events of a trace, the event request | |
106 | * would be done in this method. | |
107 | * | |
108 | * @param segmentStore | |
109 | * The segment store to fill | |
110 | * @param monitor | |
111 | * Progress monitor | |
112 | * @return Whether the segments was resolved successfully or not | |
113 | * @throws TmfAnalysisException | |
114 | * Method may throw an analysis exception | |
115 | */ | |
116 | protected abstract boolean buildAnalysisSegments(ISegmentStore<ISegment> segmentStore, IProgressMonitor monitor) throws TmfAnalysisException; | |
117 | ||
0f769d2b | 118 | @Override |
73c74de7 | 119 | public @Nullable ISegmentStore<ISegment> getSegmentStore() { |
152630e0 BH |
120 | return fSegmentStore; |
121 | } | |
122 | ||
73f1f3ea BH |
123 | @Override |
124 | public void dispose() { | |
125 | super.dispose(); | |
126 | ISegmentStore<ISegment> store = fSegmentStore; | |
127 | if (store != null) { | |
128 | store.dispose(); | |
129 | } | |
130 | } | |
131 | ||
152630e0 BH |
132 | @Override |
133 | protected boolean executeAnalysis(IProgressMonitor monitor) throws TmfAnalysisException { | |
134 | ITmfTrace trace = checkNotNull(getTrace()); | |
135 | ||
07b705e8 MK |
136 | final @Nullable String dataFileName = getDataFileName(); |
137 | if (dataFileName != null) { | |
138 | /* See if the data file already exists on disk */ | |
139 | String dir = TmfTraceManager.getSupplementaryFileDir(trace); | |
140 | final Path file = Paths.get(dir, dataFileName); | |
141 | ||
142 | if (Files.exists(file)) { | |
143 | /* Attempt to read the existing file */ | |
144 | try (ObjectInputStream ois = new ObjectInputStream(Files.newInputStream(file))) { | |
145 | Object[] segmentArray = readObject(ois); | |
146 | final ISegmentStore<ISegment> store = new TreeMapStore<>(); | |
147 | for (Object element : segmentArray) { | |
148 | if (element instanceof ISegment) { | |
149 | ISegment segment = (ISegment) element; | |
150 | store.add(segment); | |
151 | } | |
152 | } | |
153 | fSegmentStore = store; | |
154 | for (IAnalysisProgressListener listener : getListeners()) { | |
155 | listener.onComplete(this, store); | |
156 | } | |
157 | return true; | |
158 | } catch (IOException | ClassNotFoundException | ClassCastException e) { | |
159 | /* | |
160 | * We did not manage to read the file successfully, we will | |
161 | * just fall-through to rebuild a new one. | |
162 | */ | |
163 | try { | |
164 | Files.delete(file); | |
165 | } catch (IOException e1) { | |
152630e0 | 166 | } |
152630e0 BH |
167 | } |
168 | } | |
169 | } | |
152630e0 | 170 | |
65a4afc0 JCK |
171 | ISegmentStore<ISegment> segmentStore = new TreeMapStore<>(); |
172 | boolean completed = buildAnalysisSegments(segmentStore, monitor); | |
173 | if (!completed) { | |
152630e0 BH |
174 | return false; |
175 | } | |
07b705e8 MK |
176 | fSegmentStore = segmentStore; |
177 | ||
178 | if (dataFileName != null) { | |
179 | String dir = TmfTraceManager.getSupplementaryFileDir(trace); | |
180 | final Path file = Paths.get(dir, dataFileName); | |
152630e0 | 181 | |
07b705e8 MK |
182 | /* Serialize the collections to disk for future usage */ |
183 | try (ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(file))) { | |
184 | oos.writeObject(segmentStore.toArray()); | |
185 | } catch (IOException e) { | |
186 | /* | |
187 | * Didn't work, oh well. We will just re-read the trace next | |
188 | * time | |
189 | */ | |
190 | } | |
152630e0 BH |
191 | } |
192 | ||
193 | for (IAnalysisProgressListener listener : getListeners()) { | |
07b705e8 | 194 | listener.onComplete(this, segmentStore); |
152630e0 BH |
195 | } |
196 | ||
197 | return true; | |
198 | } | |
152630e0 | 199 | } |