segment store: introduce a Segment Store Factory and centralize segment stores
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.analysis.xml.core / src / org / eclipse / tracecompass / internal / tmf / analysis / xml / core / pattern / stateprovider / XmlPatternSegmentStoreModule.java
1 /*******************************************************************************
2 * Copyright (c) 2016 Ericsson
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 package org.eclipse.tracecompass.internal.tmf.analysis.xml.core.pattern.stateprovider;
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.util.concurrent.CountDownLatch;
16
17 import org.eclipse.core.runtime.IProgressMonitor;
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.eclipse.tracecompass.analysis.timing.core.segmentstore.AbstractSegmentStoreAnalysisModule;
21 import org.eclipse.tracecompass.analysis.timing.core.segmentstore.IAnalysisProgressListener;
22 import org.eclipse.tracecompass.segmentstore.core.ISegment;
23 import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
24 import org.eclipse.tracecompass.segmentstore.core.SegmentStoreFactory;
25 import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
26 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
27
28 /**
29 * Segment store module for pattern analysis defined in XML. This module will
30 * receive all the segments provided by an external source and will build a
31 * segment store
32 *
33 * @author Jean-Christian Kouame
34 */
35 public class XmlPatternSegmentStoreModule extends AbstractSegmentStoreAnalysisModule implements ISegmentListener {
36
37 /**
38 * Fake segment indicated that the last segment have been received
39 */
40 public static final @NonNull EndSegment END_SEGMENT = new EndSegment();
41 private final ISegmentStore<@NonNull ISegment> fSegments = SegmentStoreFactory.createSegmentStore();
42 private final CountDownLatch fFinished = new CountDownLatch(1);
43 private final @NonNull XmlPatternAnalysis fParent;
44 private boolean fSegmentStoreCompleted;
45
46 /**
47 * Constructor
48 *
49 * @param parent
50 * The parent analysis
51 */
52 public XmlPatternSegmentStoreModule(@NonNull XmlPatternAnalysis parent) {
53 super();
54 fParent = parent;
55 }
56
57 @Override
58 protected Object @NonNull [] readObject(@NonNull ObjectInputStream ois) throws ClassNotFoundException, IOException {
59 return checkNotNull((Object[]) ois.readObject());
60 }
61
62 @Override
63 protected boolean buildAnalysisSegments(@NonNull ISegmentStore<@NonNull ISegment> segments, @NonNull IProgressMonitor monitor) throws TmfAnalysisException {
64 final @Nullable ITmfTrace trace = getTrace();
65 if (trace == null) {
66 /* This analysis was cancelled in the meantime */
67 segmentStoreReady(false);
68 segments.close(true);
69 return false;
70 }
71 if (waitForSegmentStoreCompletion()) {
72 segments.addAll(getSegments());
73 segments.close(false);
74 return true;
75 }
76 segments.close(true);
77 return false;
78 }
79
80 @Override
81 protected void canceling() {
82 super.cancel();
83 segmentStoreReady(false);
84 }
85
86 @Override
87 protected @Nullable String getDataFileName() {
88 return getId() + XmlPatternAnalysis.SEGMENT_STORE_EXTENSION;
89 }
90
91 /**
92 * Broadcast the segment store to its listeners. Since this analysis is not
93 * directly register to the trace, the parent analysis is used as the source.
94 *
95 * @param store
96 * The store to broadcast
97 */
98 @Override
99 protected void sendUpdate(final ISegmentStore<@NonNull ISegment> store) {
100 for (IAnalysisProgressListener listener : getListeners()) {
101 listener.onComplete(fParent, store);
102 }
103 }
104
105 @Override
106 public void onNewSegment(@NonNull ISegment segment) {
107 // We can accept segments until the first END_SEGMENT arrives. Nothing
108 // should be accept after it. This prevents to receive new segments if
109 // the analysis that generates the segments is rescheduled
110 if (!fSegmentStoreCompleted) {
111 if (segment == END_SEGMENT) {
112 segmentStoreReady(true);
113 return;
114 }
115 getSegments().add(segment);
116 }
117 }
118
119 /**
120 * Get the internal segment store of this module
121 *
122 * @return The segment store
123 */
124 private synchronized ISegmentStore<@NonNull ISegment> getSegments() {
125 return fSegments;
126 }
127
128 /**
129 * Wait until internal segment store of the module is fully filled. If all
130 * the segments have been received, the completion succeeded, otherwise it
131 * is not.
132 *
133 * @return True if the completion succeeded, false otherwise
134 */
135 public boolean waitForSegmentStoreCompletion() {
136 try {
137 fFinished.await();
138 } catch (InterruptedException e) {
139 return false;
140 }
141 return fSegmentStoreCompleted;
142 }
143
144 /**
145 * Make the module available and set whether the segment store completion
146 * succeeded or not. If not, no segment store is available and
147 * {@link #waitForSegmentStoreCompletion()} should return false.
148 *
149 * @param success
150 * True if the segment store completion succeeded, false
151 * otherwise
152 */
153 private void segmentStoreReady(boolean succeeded) {
154 fSegmentStoreCompleted = succeeded;
155 fFinished.countDown();
156 }
157
158 /**
159 * Fake segment indicating the build is over, and the segment store is fully
160 * filled
161 */
162 public static class EndSegment implements ISegment {
163 /**
164 * The serial version UID
165 */
166 private static final long serialVersionUID = 7834984029618274707L;
167
168 @Override
169 public long getStart() {
170 return Long.MIN_VALUE;
171 }
172
173 @Override
174 public long getEnd() {
175 return Long.MIN_VALUE;
176 }
177 }
178 }
This page took 0.044866 seconds and 5 git commands to generate.