Commit | Line | Data |
---|---|---|
8c8bf09f | 1 | /******************************************************************************* |
165c977c | 2 | * Copyright (c) 2009 Ericsson |
8c8bf09f ASL |
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 | * Francois Chouinard - Initial API and implementation | |
11 | *******************************************************************************/ | |
12 | ||
13 | package org.eclipse.linuxtools.tmf.trace; | |
14 | ||
8c8bf09f ASL |
15 | import java.util.Vector; |
16 | ||
8c8bf09f ASL |
17 | import org.eclipse.linuxtools.tmf.event.TmfEvent; |
18 | import org.eclipse.linuxtools.tmf.event.TmfTimeRange; | |
19 | import org.eclipse.linuxtools.tmf.event.TmfTimestamp; | |
165c977c FC |
20 | import org.eclipse.linuxtools.tmf.request.ITmfRequestHandler; |
21 | import org.eclipse.linuxtools.tmf.request.TmfDataRequest; | |
82b08e62 | 22 | import org.eclipse.linuxtools.tmf.signal.TmfSignalHandler; |
50adc88e | 23 | import org.eclipse.linuxtools.tmf.signal.TmfSignalManager; |
165c977c | 24 | import org.eclipse.linuxtools.tmf.stream.ITmfEventStream; |
82b08e62 | 25 | import org.eclipse.linuxtools.tmf.stream.TmfStreamUpdatedSignal; |
165c977c | 26 | import org.eclipse.linuxtools.tmf.stream.ITmfEventStream.StreamContext; |
8c8bf09f ASL |
27 | |
28 | /** | |
0ab46cd3 | 29 | * <b><u>TmfTrace</u></b> |
8c8bf09f | 30 | * <p> |
0ab46cd3 | 31 | * TmfTrace represents a time-ordered set of events tied to a single event |
165c977c FC |
32 | * stream. It keeps track of the global information about the event log: |
33 | * <ul> | |
34 | * <li> the epoch, a reference timestamp for the whole log (t0) | |
35 | * <li> the span of the log i.e. the timestamps range | |
36 | * <li> the total number of events | |
37 | * </ul> | |
38 | * As an ITmfRequestHandler, it provides an implementation of process() | |
39 | * which handles event requests. | |
8c8bf09f | 40 | * <p> |
165c977c FC |
41 | * TODO: Handle concurrent and possibly overlapping requests in a way that |
42 | * optimizes the stream access and event parsing. | |
8c8bf09f | 43 | */ |
165c977c | 44 | public class TmfTrace implements ITmfRequestHandler<TmfEvent> { |
8c8bf09f | 45 | |
165c977c | 46 | // ======================================================================== |
8c8bf09f | 47 | // Attributes |
165c977c | 48 | // ======================================================================== |
8c8bf09f | 49 | |
165c977c FC |
50 | private final String fId; |
51 | private final ITmfEventStream fStream; | |
52 | private final TmfTimestamp fEpoch; | |
53 | ||
165c977c | 54 | // ======================================================================== |
50adc88e | 55 | // Constructors |
165c977c | 56 | // ======================================================================== |
8c8bf09f | 57 | |
165c977c FC |
58 | public TmfTrace(String id, ITmfEventStream stream) { |
59 | this(id, stream, TmfTimestamp.BigBang); | |
8c8bf09f ASL |
60 | } |
61 | ||
165c977c FC |
62 | public TmfTrace(String id, ITmfEventStream stream, TmfTimestamp epoch) { |
63 | assert stream != null; | |
64 | fId = id; | |
65 | fStream = stream; | |
66 | fEpoch = epoch; | |
50adc88e | 67 | TmfSignalManager.addListener(this); |
8c8bf09f ASL |
68 | } |
69 | ||
165c977c | 70 | public void dispose() { |
50adc88e | 71 | TmfSignalManager.removeListener(this); |
8c8bf09f ASL |
72 | } |
73 | ||
165c977c | 74 | // ======================================================================== |
8c8bf09f | 75 | // Accessors |
165c977c | 76 | // ======================================================================== |
8c8bf09f | 77 | |
165c977c FC |
78 | public String getId() { |
79 | return fId; | |
8c8bf09f ASL |
80 | } |
81 | ||
165c977c FC |
82 | public ITmfEventStream getStream() { |
83 | return fStream; | |
8c8bf09f ASL |
84 | } |
85 | ||
165c977c FC |
86 | public TmfTimestamp getEpoch() { |
87 | return fEpoch; | |
8c8bf09f ASL |
88 | } |
89 | ||
8c8bf09f | 90 | public TmfTimeRange getTimeRange() { |
165c977c | 91 | return fStream.getTimeRange(); |
8c8bf09f ASL |
92 | } |
93 | ||
165c977c FC |
94 | public int getNbEvents() { |
95 | return fStream.getNbEvents(); | |
8c8bf09f ASL |
96 | } |
97 | ||
82b08e62 FC |
98 | public int getIndex(TmfTimestamp ts) { |
99 | return fStream.getIndex(ts); | |
100 | } | |
101 | ||
165c977c | 102 | // ======================================================================== |
8c8bf09f | 103 | // Operators |
165c977c | 104 | // ======================================================================== |
8c8bf09f | 105 | |
165c977c FC |
106 | /* (non-Javadoc) |
107 | * @see org.eclipse.linuxtools.tmf.eventlog.ITmfRequestHandler#processRequest(org.eclipse.linuxtools.tmf.eventlog.TmfDataRequest, boolean) | |
108 | */ | |
109 | public void processRequest(TmfDataRequest<TmfEvent> request, boolean waitForCompletion) { | |
110 | if (request.getRange() != null) { | |
111 | serviceEventRequestByTimestamp(request); | |
112 | } else { | |
113 | serviceEventRequestByIndex(request); | |
114 | } | |
115 | if (waitForCompletion) { | |
116 | request.waitForCompletion(); | |
117 | } | |
8c8bf09f ASL |
118 | } |
119 | ||
82b08e62 FC |
120 | // ======================================================================== |
121 | // Signal handlers | |
122 | // ======================================================================== | |
123 | ||
124 | @TmfSignalHandler | |
125 | public void streamUpdated(TmfStreamUpdatedSignal signal) { | |
126 | TmfSignalManager.dispatchSignal(new TmfTraceUpdatedSignal(this, this)); | |
127 | } | |
8c8bf09f | 128 | |
165c977c FC |
129 | // ======================================================================== |
130 | // Helper functions | |
131 | // ======================================================================== | |
8c8bf09f | 132 | |
165c977c FC |
133 | /* (non-Javadoc) |
134 | * | |
135 | * @param request | |
136 | */ | |
137 | private void serviceEventRequestByTimestamp(final TmfDataRequest<TmfEvent> request) { | |
138 | Thread thread = new Thread() { | |
139 | @Override | |
82b08e62 | 140 | public void run() { |
165c977c FC |
141 | TmfTimestamp startTime = request.getRange().getStartTime(); |
142 | TmfTimestamp endTime = request.getRange().getEndTime(); | |
143 | int blockSize = request.getBlockize(); | |
144 | ||
145 | int nbRequestedEvents = request.getNbRequestedItems(); | |
146 | if (nbRequestedEvents == -1) { | |
147 | nbRequestedEvents = Integer.MAX_VALUE; | |
148 | } | |
149 | ||
150 | Vector<TmfEvent> events = new Vector<TmfEvent>(); | |
151 | int nbEvents = 0; | |
152 | ||
153 | StreamContext context = new StreamContext(null); | |
154 | TmfEvent event = fStream.getEvent(context, startTime); | |
155 | ||
156 | while (!request.isCancelled() && nbEvents < nbRequestedEvents && event != null && | |
157 | event.getTimestamp().compareTo(endTime, false) <= 0 ) | |
158 | { | |
159 | events.add(event); | |
160 | if (++nbEvents % blockSize == 0) { | |
161 | TmfEvent[] result = new TmfEvent[events.size()]; | |
162 | events.toArray(result); | |
163 | request.setData(result); | |
0ab46cd3 | 164 | request.handleData(); |
165c977c FC |
165 | events.removeAllElements(); |
166 | } | |
167 | // To avoid an unnecessary read passed the last event requested | |
168 | if (nbEvents < nbRequestedEvents) | |
169 | event = fStream.getNextEvent(context); | |
170 | } | |
171 | TmfEvent[] result = new TmfEvent[events.size()]; | |
172 | events.toArray(result); | |
173 | request.setData(result); | |
174 | ||
0ab46cd3 | 175 | request.handleData(); |
165c977c FC |
176 | request.done(); |
177 | } | |
178 | }; | |
179 | thread.start(); | |
8c8bf09f ASL |
180 | } |
181 | ||
182 | /* (non-Javadoc) | |
165c977c FC |
183 | * |
184 | * @param request | |
8c8bf09f | 185 | */ |
165c977c FC |
186 | private void serviceEventRequestByIndex(final TmfDataRequest<TmfEvent> request) { |
187 | Thread thread = new Thread() { | |
188 | @Override | |
82b08e62 | 189 | public void run() { |
165c977c FC |
190 | int blockSize = request.getBlockize(); |
191 | ||
192 | int nbRequestedEvents = request.getNbRequestedItems(); | |
193 | if (nbRequestedEvents == -1) { | |
194 | nbRequestedEvents = Integer.MAX_VALUE; | |
195 | } | |
196 | ||
197 | Vector<TmfEvent> events = new Vector<TmfEvent>(); | |
198 | int nbEvents = 0; | |
199 | ||
200 | StreamContext context = new StreamContext(null); | |
201 | TmfEvent event = fStream.getEvent(context, request.getIndex()); | |
202 | ||
203 | while (!request.isCancelled() && nbEvents < nbRequestedEvents && event != null) | |
204 | { | |
205 | events.add(event); | |
206 | if (++nbEvents % blockSize == 0) { | |
207 | TmfEvent[] result = new TmfEvent[events.size()]; | |
208 | events.toArray(result); | |
209 | request.setData(result); | |
0ab46cd3 | 210 | request.handleData(); |
165c977c FC |
211 | events.removeAllElements(); |
212 | } | |
213 | // To avoid an unnecessary read passed the last event requested | |
214 | if (nbEvents < nbRequestedEvents) | |
215 | event = fStream.getNextEvent(context); | |
216 | } | |
217 | TmfEvent[] result = new TmfEvent[events.size()]; | |
218 | events.toArray(result); | |
219 | ||
220 | request.setData(result); | |
0ab46cd3 | 221 | request.handleData(); |
165c977c | 222 | request.done(); |
8c8bf09f | 223 | } |
165c977c FC |
224 | }; |
225 | thread.start(); | |
8c8bf09f ASL |
226 | } |
227 | ||
8c8bf09f | 228 | } |