Merge branch 'master' into lttng-kepler
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / views / timechart / TimeChartAnalysisEntry.java
1 /*******************************************************************************
2 * Copyright (c) 2010 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 * Contributors:
10 * Patrick Tasse - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.linuxtools.tmf.ui.views.timechart;
14
15 import java.util.Iterator;
16 import java.util.NoSuchElementException;
17 import java.util.Vector;
18
19 import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
20 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent;
21 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
22
23 /**
24 * An entry (row) in the time chart analysis view
25 *
26 * @version 1.0
27 * @author Patrick Tasse
28 */
29 public class TimeChartAnalysisEntry implements ITimeGraphEntry {
30
31 private final ITmfTrace fTrace;
32 private final Vector<TimeChartEvent> fTraceEvents;
33 private int fPower = 0; // 2^fPower nanoseconds per vector position
34 private long fReferenceTime = -1; // time corresponding to beginning of index 0
35 private long fStartTime = -1; // time of first event
36 private long fStopTime = -1; // time of last event
37 private long fLastRank = -1; // rank of last processed trace event
38
39 TimeChartAnalysisEntry(ITmfTrace trace, int modelSize) {
40 fTrace = trace;
41 fTraceEvents = new Vector<TimeChartEvent>(modelSize);
42 }
43
44 @Override
45 public ITimeGraphEntry[] getChildren() {
46 return null;
47 }
48
49 @Override
50 public ITimeGraphEntry getParent() {
51 return null;
52 }
53
54 @Override
55 public boolean hasChildren() {
56 return false;
57 }
58
59 @Override
60 public String getName() {
61 return fTrace.getName();
62 }
63
64 @Override
65 public long getStartTime() {
66 return fStartTime;
67 }
68
69 @Override
70 public long getEndTime() {
71 return fStopTime;
72 }
73
74 @Override
75 public boolean hasTimeEvents() {
76 return true;
77 }
78
79 @Override
80 public Iterator<ITimeEvent> getTimeEventsIterator() {
81 return new EntryIterator(0, Long.MAX_VALUE, 0);
82 }
83
84 @Override
85 public Iterator<ITimeEvent> getTimeEventsIterator(long startTime, long stopTime, long maxDuration) {
86 return new EntryIterator(startTime, stopTime, maxDuration);
87 }
88
89 private class EntryIterator implements Iterator<ITimeEvent> {
90 private final long fIteratorStartTime;
91 private final long fIteratorStopTime;
92 private final long fIteratorMaxDuration;
93 private long lastTime = -1;
94 private TimeChartEvent next = null;
95 private Iterator<ITimeEvent> nestedIterator = null;
96
97 public EntryIterator(long startTime, long stopTime, long maxDuration) {
98 fIteratorStartTime = startTime;
99 fIteratorStopTime = stopTime;
100 fIteratorMaxDuration = maxDuration;
101 }
102
103 @Override
104 public boolean hasNext() {
105 synchronized (fTraceEvents) {
106 if (next != null) {
107 return true;
108 }
109 if (nestedIterator != null) {
110 if (nestedIterator.hasNext()) {
111 return true;
112 }
113 nestedIterator = null;
114 }
115 long time = (lastTime == -1) ? fStartTime : lastTime;
116 int index = (fReferenceTime == -1) ? 0 : (int) ((time - fReferenceTime) >> fPower);
117 while (index < fTraceEvents.size()) {
118 TimeChartEvent event = fTraceEvents.get(index++);
119 if (event != null && (lastTime == -1 || event.getTime() > time)) {
120 if (event.getTime() + event.getDuration() >= fIteratorStartTime && event.getTime() <= fIteratorStopTime) {
121 if (event.getItemizedEntry() == null || event.getDuration() <= fIteratorMaxDuration) {
122 lastTime = event.getTime() + event.getDuration();
123 next = event;
124 return true;
125 }
126 nestedIterator = event.getItemizedEntry().getTimeEventsIterator(fIteratorStartTime, fIteratorStopTime, fIteratorMaxDuration);
127 return nestedIterator.hasNext();
128 }
129 }
130 }
131 return false;
132 }
133 }
134
135 @Override
136 public TimeChartEvent next() {
137 synchronized (fTraceEvents) {
138 if (nestedIterator != null) {
139 TimeChartEvent event = (TimeChartEvent) nestedIterator.next();
140 lastTime = event.getTime() + event.getDuration();
141 return event;
142 }
143 if (hasNext()) {
144 TimeChartEvent event = next;
145 next = null;
146 return event;
147 }
148 throw new NoSuchElementException();
149 }
150 }
151
152 @Override
153 public void remove() {
154 throw new UnsupportedOperationException();
155 }
156
157 }
158
159 /**
160 * Add a time event to the time chart entry
161 *
162 * @param timeEvent
163 * The event to add
164 */
165 public void addTraceEvent(ITimeEvent timeEvent) {
166 long time = timeEvent.getTime();
167 synchronized (fTraceEvents) {
168 long index = (fReferenceTime == -1) ? 0 : (time - fReferenceTime) >> fPower;
169 if (index < 0) {
170 if (fTraceEvents.capacity() - fTraceEvents.size() < -index) {
171 int powershift = (-index + fTraceEvents.size() <= 2 * fTraceEvents.capacity()) ? 1 :
172 (int) Math.ceil(Math.log((double) (-index + fTraceEvents.size()) / fTraceEvents.capacity()) / Math.log(2));
173 merge(powershift);
174 index = (int) ((time - fReferenceTime) >> fPower);
175 }
176 shift((int) -index);
177 index = 0;
178 fTraceEvents.set(0, (TimeChartEvent) timeEvent);
179 } else if (index < fTraceEvents.capacity()) {
180 if (index >= fTraceEvents.size()) {
181 fTraceEvents.setSize((int) index + 1);
182 }
183 } else {
184 int powershift = (index < 2 * fTraceEvents.capacity()) ? 1 :
185 (int) Math.ceil(Math.log((double) (index + 1) / fTraceEvents.capacity()) / Math.log(2));
186 merge(powershift);
187 index = (int) ((time - fReferenceTime) >> fPower);
188 fTraceEvents.setSize((int) index + 1);
189 }
190 TimeChartEvent event = fTraceEvents.get((int) index);
191 if (event == null) {
192 fTraceEvents.set((int) index, (TimeChartEvent) timeEvent);
193 } else {
194 if (event.getItemizedEntry() == null) {
195 event.merge((TimeChartEvent) timeEvent);
196 } else {
197 event.mergeDecorations((TimeChartEvent) timeEvent);
198 event.getItemizedEntry().addTraceEvent(timeEvent);
199 }
200 }
201 if (fReferenceTime == -1 || time < fReferenceTime) {
202 fReferenceTime = (time >> fPower) << fPower;
203 }
204 if (fStartTime == -1 || time < fStartTime) {
205 fStartTime = time;
206 }
207 if (fStopTime == -1 || time > fStopTime) {
208 fStopTime = time;
209 }
210 }
211 }
212
213 private void merge(int powershift) {
214 fPower += powershift;
215 fReferenceTime = (fReferenceTime >> fPower) << fPower;
216 int index = 0;
217 for (int i = 0; i < fTraceEvents.size(); i++) {
218 TimeChartEvent event = fTraceEvents.get(i);
219 if (event != null) {
220 index = (int) ((event.getTime() - fReferenceTime) >> fPower);
221 TimeChartEvent mergedEvent = fTraceEvents.get(index);
222 if (mergedEvent == null) {
223 fTraceEvents.set(index, event);
224 } else {
225 mergedEvent.merge(event);
226 }
227 if (i != index) {
228 fTraceEvents.set(i, null);
229 }
230 }
231 }
232 fTraceEvents.setSize(index + 1);
233 }
234
235 private void shift(int indexshift) {
236 int oldSize = fTraceEvents.size();
237 fTraceEvents.setSize(oldSize + indexshift);
238 for (int i = oldSize - 1; i >= 0; i--) {
239 fTraceEvents.set(i + indexshift, fTraceEvents.get(i));
240 }
241 for (int i = 0; i < indexshift; i++) {
242 fTraceEvents.set(i, null);
243 }
244 }
245
246 /**
247 * Retrieve the trace associated with this entry
248 *
249 * @return The trace object
250 */
251 public ITmfTrace getTrace() {
252 return fTrace;
253 }
254
255 /**
256 * Set the last rank of the entry
257 *
258 * @param rank
259 * The rank to set
260 */
261 public void setLastRank(long rank) {
262 fLastRank = rank;
263 }
264
265 /**
266 * Retrieve the last rank of the entry
267 *
268 * @return The last rank
269 */
270 public long getLastRank() {
271 return fLastRank;
272 }
273 }
This page took 0.03751 seconds and 5 git commands to generate.