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 | ||
165c977c FC |
15 | import java.util.HashSet; |
16 | import java.util.Set; | |
8c8bf09f ASL |
17 | import java.util.Vector; |
18 | ||
8c8bf09f ASL |
19 | import org.eclipse.linuxtools.tmf.event.TmfEvent; |
20 | import org.eclipse.linuxtools.tmf.event.TmfTimeRange; | |
21 | import org.eclipse.linuxtools.tmf.event.TmfTimestamp; | |
165c977c FC |
22 | import org.eclipse.linuxtools.tmf.request.ITmfRequestHandler; |
23 | import org.eclipse.linuxtools.tmf.request.TmfDataRequest; | |
24 | import org.eclipse.linuxtools.tmf.stream.ITmfEventStream; | |
25 | import org.eclipse.linuxtools.tmf.stream.TmfStreamUpdateEvent; | |
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 | ||
54 | // The listeners | |
55 | private Set<ITmfTraceEventListener> fListeners = new HashSet<ITmfTraceEventListener>(); | |
8c8bf09f | 56 | |
165c977c FC |
57 | // ======================================================================== |
58 | // Constructors/Destructors | |
59 | // ======================================================================== | |
8c8bf09f | 60 | |
165c977c FC |
61 | public TmfTrace(String id, ITmfEventStream stream) { |
62 | this(id, stream, TmfTimestamp.BigBang); | |
8c8bf09f ASL |
63 | } |
64 | ||
165c977c FC |
65 | public TmfTrace(String id, ITmfEventStream stream, TmfTimestamp epoch) { |
66 | assert stream != null; | |
67 | fId = id; | |
68 | fStream = stream; | |
69 | fEpoch = epoch; | |
70 | fStream.addListener(this); | |
8c8bf09f ASL |
71 | } |
72 | ||
165c977c FC |
73 | public void dispose() { |
74 | fStream.removeListener(this); | |
8c8bf09f ASL |
75 | } |
76 | ||
165c977c | 77 | // ======================================================================== |
8c8bf09f | 78 | // Accessors |
165c977c | 79 | // ======================================================================== |
8c8bf09f | 80 | |
165c977c FC |
81 | public String getId() { |
82 | return fId; | |
8c8bf09f ASL |
83 | } |
84 | ||
165c977c FC |
85 | public ITmfEventStream getStream() { |
86 | return fStream; | |
8c8bf09f ASL |
87 | } |
88 | ||
165c977c FC |
89 | public TmfTimestamp getEpoch() { |
90 | return fEpoch; | |
8c8bf09f ASL |
91 | } |
92 | ||
8c8bf09f | 93 | public TmfTimeRange getTimeRange() { |
165c977c | 94 | return fStream.getTimeRange(); |
8c8bf09f ASL |
95 | } |
96 | ||
165c977c FC |
97 | public int getNbEvents() { |
98 | return fStream.getNbEvents(); | |
8c8bf09f ASL |
99 | } |
100 | ||
165c977c | 101 | // ======================================================================== |
8c8bf09f | 102 | // Operators |
165c977c | 103 | // ======================================================================== |
8c8bf09f | 104 | |
165c977c FC |
105 | /* (non-Javadoc) |
106 | * @see org.eclipse.linuxtools.tmf.eventlog.ITmfRequestHandler#processRequest(org.eclipse.linuxtools.tmf.eventlog.TmfDataRequest, boolean) | |
107 | */ | |
108 | public void processRequest(TmfDataRequest<TmfEvent> request, boolean waitForCompletion) { | |
109 | if (request.getRange() != null) { | |
110 | serviceEventRequestByTimestamp(request); | |
111 | } else { | |
112 | serviceEventRequestByIndex(request); | |
113 | } | |
114 | if (waitForCompletion) { | |
115 | request.waitForCompletion(); | |
116 | } | |
8c8bf09f ASL |
117 | } |
118 | ||
165c977c FC |
119 | public void addListener(ITmfTraceEventListener listener) { |
120 | fListeners.add(listener); | |
8c8bf09f ASL |
121 | } |
122 | ||
165c977c FC |
123 | public void removeListener(ITmfTraceEventListener listener) { |
124 | fListeners.remove(listener); | |
8c8bf09f ASL |
125 | } |
126 | ||
165c977c FC |
127 | public void handleEvent(TmfStreamUpdateEvent event) { |
128 | for (ITmfTraceEventListener listener : fListeners) { | |
129 | listener.handleEvent(new TmfTraceUpdateEvent(this)); | |
8c8bf09f | 130 | } |
165c977c | 131 | } |
8c8bf09f | 132 | |
165c977c FC |
133 | // ======================================================================== |
134 | // Helper functions | |
135 | // ======================================================================== | |
8c8bf09f | 136 | |
165c977c FC |
137 | /* (non-Javadoc) |
138 | * | |
139 | * @param request | |
140 | */ | |
141 | private void serviceEventRequestByTimestamp(final TmfDataRequest<TmfEvent> request) { | |
142 | Thread thread = new Thread() { | |
143 | @Override | |
144 | public void run() { | |
145 | TmfTimestamp startTime = request.getRange().getStartTime(); | |
146 | TmfTimestamp endTime = request.getRange().getEndTime(); | |
147 | int blockSize = request.getBlockize(); | |
148 | ||
149 | int nbRequestedEvents = request.getNbRequestedItems(); | |
150 | if (nbRequestedEvents == -1) { | |
151 | nbRequestedEvents = Integer.MAX_VALUE; | |
152 | } | |
153 | ||
154 | Vector<TmfEvent> events = new Vector<TmfEvent>(); | |
155 | int nbEvents = 0; | |
156 | ||
157 | StreamContext context = new StreamContext(null); | |
158 | TmfEvent event = fStream.getEvent(context, startTime); | |
159 | ||
160 | while (!request.isCancelled() && nbEvents < nbRequestedEvents && event != null && | |
161 | event.getTimestamp().compareTo(endTime, false) <= 0 ) | |
162 | { | |
163 | events.add(event); | |
164 | if (++nbEvents % blockSize == 0) { | |
165 | TmfEvent[] result = new TmfEvent[events.size()]; | |
166 | events.toArray(result); | |
167 | request.setData(result); | |
0ab46cd3 | 168 | request.handleData(); |
165c977c FC |
169 | events.removeAllElements(); |
170 | } | |
171 | // To avoid an unnecessary read passed the last event requested | |
172 | if (nbEvents < nbRequestedEvents) | |
173 | event = fStream.getNextEvent(context); | |
174 | } | |
175 | TmfEvent[] result = new TmfEvent[events.size()]; | |
176 | events.toArray(result); | |
177 | request.setData(result); | |
178 | ||
0ab46cd3 | 179 | request.handleData(); |
165c977c FC |
180 | request.done(); |
181 | } | |
182 | }; | |
183 | thread.start(); | |
8c8bf09f ASL |
184 | } |
185 | ||
186 | /* (non-Javadoc) | |
165c977c FC |
187 | * |
188 | * @param request | |
8c8bf09f | 189 | */ |
165c977c FC |
190 | private void serviceEventRequestByIndex(final TmfDataRequest<TmfEvent> request) { |
191 | Thread thread = new Thread() { | |
192 | @Override | |
193 | public void run() { | |
194 | int blockSize = request.getBlockize(); | |
195 | ||
196 | int nbRequestedEvents = request.getNbRequestedItems(); | |
197 | if (nbRequestedEvents == -1) { | |
198 | nbRequestedEvents = Integer.MAX_VALUE; | |
199 | } | |
200 | ||
201 | Vector<TmfEvent> events = new Vector<TmfEvent>(); | |
202 | int nbEvents = 0; | |
203 | ||
204 | StreamContext context = new StreamContext(null); | |
205 | TmfEvent event = fStream.getEvent(context, request.getIndex()); | |
206 | ||
207 | while (!request.isCancelled() && nbEvents < nbRequestedEvents && event != null) | |
208 | { | |
209 | events.add(event); | |
210 | if (++nbEvents % blockSize == 0) { | |
211 | TmfEvent[] result = new TmfEvent[events.size()]; | |
212 | events.toArray(result); | |
213 | request.setData(result); | |
0ab46cd3 | 214 | request.handleData(); |
165c977c FC |
215 | events.removeAllElements(); |
216 | } | |
217 | // To avoid an unnecessary read passed the last event requested | |
218 | if (nbEvents < nbRequestedEvents) | |
219 | event = fStream.getNextEvent(context); | |
220 | } | |
221 | TmfEvent[] result = new TmfEvent[events.size()]; | |
222 | events.toArray(result); | |
223 | ||
224 | request.setData(result); | |
0ab46cd3 | 225 | request.handleData(); |
165c977c | 226 | request.done(); |
8c8bf09f | 227 | } |
165c977c FC |
228 | }; |
229 | thread.start(); | |
8c8bf09f ASL |
230 | } |
231 | ||
8c8bf09f | 232 | } |