1 /*******************************************************************************
2 * Copyright (c) 2010, 2012 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
.linuxtools
.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
.linuxtools
.tmf
.core
.trace
.ITmfTrace
;
21 import org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.timegraph
.model
.ITimeEvent
;
22 import org
.eclipse
.linuxtools
.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
<TimeChartEvent
>(modelSize
);
49 public List
<ITimeGraphEntry
> getChildren() {
54 public ITimeGraphEntry
getParent() {
59 public boolean hasChildren() {
64 public String
getName() {
65 return fTrace
.getName();
69 public long getStartTime() {
74 public long getEndTime() {
79 public boolean hasTimeEvents() {
84 public Iterator
<ITimeEvent
> getTimeEventsIterator() {
85 return new EntryIterator(0, Long
.MAX_VALUE
, 0);
89 public Iterator
<ITimeEvent
> getTimeEventsIterator(long startTime
, long stopTime
, long maxDuration
) {
90 return new EntryIterator(startTime
, stopTime
, maxDuration
);
93 private class EntryIterator
implements Iterator
<ITimeEvent
> {
94 private final long fIteratorStartTime
;
95 private final long fIteratorStopTime
;
96 private final long fIteratorMaxDuration
;
97 private long lastTime
= -1;
98 private TimeChartEvent next
= null;
99 private Iterator
<ITimeEvent
> nestedIterator
= null;
101 public EntryIterator(long startTime
, long stopTime
, long maxDuration
) {
102 fIteratorStartTime
= startTime
;
103 fIteratorStopTime
= stopTime
;
104 fIteratorMaxDuration
= maxDuration
;
108 public boolean hasNext() {
109 synchronized (fTraceEvents
) {
113 if (nestedIterator
!= null) {
114 if (nestedIterator
.hasNext()) {
117 nestedIterator
= null;
119 long time
= (lastTime
== -1) ? fStartTime
: lastTime
;
120 int index
= (fReferenceTime
== -1) ?
0 : (int) ((time
- fReferenceTime
) >> fPower
);
121 while (index
< fTraceEvents
.size()) {
122 TimeChartEvent event
= fTraceEvents
.get(index
++);
123 if (event
!= null && (lastTime
== -1 || event
.getTime() > time
)) {
124 if (event
.getTime() + event
.getDuration() >= fIteratorStartTime
&& event
.getTime() <= fIteratorStopTime
) {
125 if (event
.getItemizedEntry() == null || event
.getDuration() <= fIteratorMaxDuration
) {
126 lastTime
= event
.getTime() + event
.getDuration();
130 nestedIterator
= event
.getItemizedEntry().getTimeEventsIterator(fIteratorStartTime
, fIteratorStopTime
, fIteratorMaxDuration
);
131 return nestedIterator
.hasNext();
140 public TimeChartEvent
next() {
141 synchronized (fTraceEvents
) {
142 if (nestedIterator
!= null) {
143 TimeChartEvent event
= (TimeChartEvent
) nestedIterator
.next();
144 lastTime
= event
.getTime() + event
.getDuration();
148 TimeChartEvent event
= next
;
152 throw new NoSuchElementException();
157 public void remove() {
158 throw new UnsupportedOperationException();
164 * Add a time event to the time chart entry
169 public void addTraceEvent(ITimeEvent timeEvent
) {
170 long time
= timeEvent
.getTime();
171 synchronized (fTraceEvents
) {
172 long index
= (fReferenceTime
== -1) ?
0 : (time
- fReferenceTime
) >> fPower
;
174 if (fTraceEvents
.capacity() - fTraceEvents
.size() < -index
) {
175 int powershift
= (-index
+ fTraceEvents
.size() <= 2 * fTraceEvents
.capacity()) ?
1 :
176 (int) Math
.ceil(Math
.log((double) (-index
+ fTraceEvents
.size()) / fTraceEvents
.capacity()) / Math
.log(2));
178 index
= (int) ((time
- fReferenceTime
) >> fPower
);
182 fTraceEvents
.set(0, (TimeChartEvent
) timeEvent
);
183 } else if (index
< fTraceEvents
.capacity()) {
184 if (index
>= fTraceEvents
.size()) {
185 fTraceEvents
.setSize((int) index
+ 1);
188 int powershift
= (index
< 2 * fTraceEvents
.capacity()) ?
1 :
189 (int) Math
.ceil(Math
.log((double) (index
+ 1) / fTraceEvents
.capacity()) / Math
.log(2));
191 index
= (int) ((time
- fReferenceTime
) >> fPower
);
192 fTraceEvents
.setSize((int) index
+ 1);
194 TimeChartEvent event
= fTraceEvents
.get((int) index
);
196 fTraceEvents
.set((int) index
, (TimeChartEvent
) timeEvent
);
198 if (event
.getItemizedEntry() == null) {
199 event
.merge((TimeChartEvent
) timeEvent
);
201 event
.mergeDecorations((TimeChartEvent
) timeEvent
);
202 event
.getItemizedEntry().addTraceEvent(timeEvent
);
205 if (fReferenceTime
== -1 || time
< fReferenceTime
) {
206 fReferenceTime
= (time
>> fPower
) << fPower
;
208 if (fStartTime
== -1 || time
< fStartTime
) {
211 if (fStopTime
== -1 || time
> fStopTime
) {
217 private void merge(int powershift
) {
218 fPower
+= powershift
;
219 fReferenceTime
= (fReferenceTime
>> fPower
) << fPower
;
221 for (int i
= 0; i
< fTraceEvents
.size(); i
++) {
222 TimeChartEvent event
= fTraceEvents
.get(i
);
224 index
= (int) ((event
.getTime() - fReferenceTime
) >> fPower
);
225 TimeChartEvent mergedEvent
= fTraceEvents
.get(index
);
226 if (mergedEvent
== null) {
227 fTraceEvents
.set(index
, event
);
229 mergedEvent
.merge(event
);
232 fTraceEvents
.set(i
, null);
236 fTraceEvents
.setSize(index
+ 1);
239 private void shift(int indexshift
) {
240 int oldSize
= fTraceEvents
.size();
241 fTraceEvents
.setSize(oldSize
+ indexshift
);
242 for (int i
= oldSize
- 1; i
>= 0; i
--) {
243 fTraceEvents
.set(i
+ indexshift
, fTraceEvents
.get(i
));
245 for (int i
= 0; i
< indexshift
; i
++) {
246 fTraceEvents
.set(i
, null);
251 * Retrieve the trace associated with this entry
253 * @return The trace object
255 public ITmfTrace
getTrace() {
260 * Set the last rank of the entry
265 public void setLastRank(long rank
) {
270 * Retrieve the last rank of the entry
272 * @return The last rank
274 public long getLastRank() {