1 /*******************************************************************************
2 * Copyright (c) 2010, 2014 Ericsson
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
10 * Patrick Tasse - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.tmf
.ui
.views
.timechart
;
15 import java
.util
.Iterator
;
16 import java
.util
.List
;
17 import java
.util
.NoSuchElementException
;
18 import java
.util
.Vector
;
20 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
21 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ITimeEvent
;
22 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ITimeGraphEntry
;
25 * An entry (row) in the time chart analysis view
28 * @author Patrick Tasse
30 public class TimeChartAnalysisEntry
implements ITimeGraphEntry
{
32 private final ITmfTrace fTrace
;
33 private final Vector
<TimeChartEvent
> fTraceEvents
;
34 private int fPower
= 0; // 2^fPower nanoseconds per vector position
35 private long fReferenceTime
= -1; // time corresponding to beginning of index 0
36 private long fStartTime
= -1; // time of first event
37 private long fStopTime
= -1; // time of last event
38 private long fLastRank
= -1; // rank of last processed trace event
40 TimeChartAnalysisEntry(ITmfTrace trace
, int modelSize
) {
42 fTraceEvents
= new Vector
<>(modelSize
);
46 public List
<ITimeGraphEntry
> getChildren() {
51 public ITimeGraphEntry
getParent() {
56 public boolean hasChildren() {
61 public String
getName() {
62 return fTrace
.getName();
66 public long getStartTime() {
71 public long getEndTime() {
76 public boolean hasTimeEvents() {
81 public Iterator
<ITimeEvent
> getTimeEventsIterator() {
82 return new EntryIterator(0, Long
.MAX_VALUE
, 0);
86 public Iterator
<ITimeEvent
> getTimeEventsIterator(long startTime
, long stopTime
, long maxDuration
) {
87 return new EntryIterator(startTime
, stopTime
, maxDuration
);
90 private class EntryIterator
implements Iterator
<ITimeEvent
> {
91 private final long fIteratorStartTime
;
92 private final long fIteratorStopTime
;
93 private final long fIteratorMaxDuration
;
94 private long lastTime
= -1;
95 private TimeChartEvent next
= null;
96 private Iterator
<ITimeEvent
> nestedIterator
= null;
98 public EntryIterator(long startTime
, long stopTime
, long maxDuration
) {
99 fIteratorStartTime
= startTime
;
100 fIteratorStopTime
= stopTime
;
101 fIteratorMaxDuration
= maxDuration
;
105 public boolean hasNext() {
106 synchronized (fTraceEvents
) {
110 if (nestedIterator
!= null) {
111 if (nestedIterator
.hasNext()) {
114 nestedIterator
= null;
116 long time
= (lastTime
== -1) ? fStartTime
: lastTime
;
117 int index
= (fReferenceTime
== -1) ?
0 : (int) ((time
- fReferenceTime
) >> fPower
);
118 while (index
< fTraceEvents
.size()) {
119 TimeChartEvent event
= fTraceEvents
.get(index
++);
120 if (event
!= null && (lastTime
== -1 || event
.getTime() > time
)) {
121 if (event
.getTime() + event
.getDuration() >= fIteratorStartTime
&& event
.getTime() <= fIteratorStopTime
) {
122 if (event
.getItemizedEntry() == null || event
.getDuration() <= fIteratorMaxDuration
) {
123 lastTime
= event
.getTime() + event
.getDuration();
127 nestedIterator
= event
.getItemizedEntry().getTimeEventsIterator(fIteratorStartTime
, fIteratorStopTime
, fIteratorMaxDuration
);
128 return nestedIterator
.hasNext();
137 public TimeChartEvent
next() {
138 synchronized (fTraceEvents
) {
139 if (nestedIterator
!= null) {
140 TimeChartEvent event
= (TimeChartEvent
) nestedIterator
.next();
141 lastTime
= event
.getTime() + event
.getDuration();
145 TimeChartEvent event
= next
;
149 throw new NoSuchElementException();
154 public void remove() {
155 throw new UnsupportedOperationException();
161 * Add a time event to the time chart entry
166 public void addTraceEvent(ITimeEvent timeEvent
) {
167 long time
= timeEvent
.getTime();
168 synchronized (fTraceEvents
) {
169 long index
= (fReferenceTime
== -1) ?
0 : (time
- fReferenceTime
) >> fPower
;
171 if (fTraceEvents
.capacity() - fTraceEvents
.size() < -index
) {
172 int powershift
= (-index
+ fTraceEvents
.size() <= 2 * fTraceEvents
.capacity()) ?
1 :
173 (int) Math
.ceil(Math
.log((double) (-index
+ fTraceEvents
.size()) / fTraceEvents
.capacity()) / Math
.log(2));
175 index
= (int) ((time
- fReferenceTime
) >> fPower
);
179 fTraceEvents
.set(0, (TimeChartEvent
) timeEvent
);
180 } else if (index
< fTraceEvents
.capacity()) {
181 if (index
>= fTraceEvents
.size()) {
182 fTraceEvents
.setSize((int) index
+ 1);
185 int powershift
= (index
< 2 * fTraceEvents
.capacity()) ?
1 :
186 (int) Math
.ceil(Math
.log((double) (index
+ 1) / fTraceEvents
.capacity()) / Math
.log(2));
188 index
= (int) ((time
- fReferenceTime
) >> fPower
);
189 fTraceEvents
.setSize((int) index
+ 1);
191 TimeChartEvent event
= fTraceEvents
.get((int) index
);
193 fTraceEvents
.set((int) index
, (TimeChartEvent
) timeEvent
);
195 if (event
.getItemizedEntry() == null) {
196 event
.merge((TimeChartEvent
) timeEvent
);
198 event
.mergeDecorations((TimeChartEvent
) timeEvent
);
199 event
.getItemizedEntry().addTraceEvent(timeEvent
);
202 if (fReferenceTime
== -1 || time
< fReferenceTime
) {
203 fReferenceTime
= (time
>> fPower
) << fPower
;
205 if (fStartTime
== -1 || time
< fStartTime
) {
208 if (fStopTime
== -1 || time
> fStopTime
) {
214 private void merge(int powershift
) {
215 fPower
+= powershift
;
216 fReferenceTime
= (fReferenceTime
>> fPower
) << fPower
;
218 for (int i
= 0; i
< fTraceEvents
.size(); i
++) {
219 TimeChartEvent event
= fTraceEvents
.get(i
);
221 index
= (int) ((event
.getTime() - fReferenceTime
) >> fPower
);
222 TimeChartEvent mergedEvent
= fTraceEvents
.get(index
);
223 if (mergedEvent
== null) {
224 fTraceEvents
.set(index
, event
);
226 mergedEvent
.merge(event
);
229 fTraceEvents
.set(i
, null);
233 fTraceEvents
.setSize(index
+ 1);
236 private void shift(int indexshift
) {
237 int oldSize
= fTraceEvents
.size();
238 fTraceEvents
.setSize(oldSize
+ indexshift
);
239 for (int i
= oldSize
- 1; i
>= 0; i
--) {
240 fTraceEvents
.set(i
+ indexshift
, fTraceEvents
.get(i
));
242 for (int i
= 0; i
< indexshift
; i
++) {
243 fTraceEvents
.set(i
, null);
248 * Retrieve the trace associated with this entry
250 * @return The trace object
252 public ITmfTrace
getTrace() {
257 * Set the last rank of the entry
262 public void setLastRank(long rank
) {
267 * Retrieve the last rank of the entry
269 * @return The last rank
271 public long getLastRank() {