1 /*******************************************************************************
2 * Copyright (c) 2010 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
.NoSuchElementException
;
17 import java
.util
.Vector
;
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
;
24 * An entry (row) in the time chart analysis view
27 * @author Patrick Tasse
29 public class TimeChartAnalysisEntry
implements ITimeGraphEntry
{
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
39 TimeChartAnalysisEntry(ITmfTrace trace
, int modelSize
) {
41 fTraceEvents
= new Vector
<TimeChartEvent
>(modelSize
);
45 public ITimeGraphEntry
[] getChildren() {
50 public ITimeGraphEntry
getParent() {
55 public boolean hasChildren() {
60 public String
getName() {
61 return fTrace
.getName();
65 public long getStartTime() {
70 public long getEndTime() {
75 public boolean hasTimeEvents() {
80 public Iterator
<ITimeEvent
> getTimeEventsIterator() {
81 return new EntryIterator(0, Long
.MAX_VALUE
, 0);
85 public Iterator
<ITimeEvent
> getTimeEventsIterator(long startTime
, long stopTime
, long maxDuration
) {
86 return new EntryIterator(startTime
, stopTime
, maxDuration
);
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;
97 public EntryIterator(long startTime
, long stopTime
, long maxDuration
) {
98 fIteratorStartTime
= startTime
;
99 fIteratorStopTime
= stopTime
;
100 fIteratorMaxDuration
= maxDuration
;
104 public boolean hasNext() {
105 synchronized (fTraceEvents
) {
109 if (nestedIterator
!= null) {
110 if (nestedIterator
.hasNext()) {
113 nestedIterator
= null;
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();
126 nestedIterator
= event
.getItemizedEntry().getTimeEventsIterator(fIteratorStartTime
, fIteratorStopTime
, fIteratorMaxDuration
);
127 return nestedIterator
.hasNext();
136 public TimeChartEvent
next() {
137 synchronized (fTraceEvents
) {
138 if (nestedIterator
!= null) {
139 TimeChartEvent event
= (TimeChartEvent
) nestedIterator
.next();
140 lastTime
= event
.getTime() + event
.getDuration();
144 TimeChartEvent event
= next
;
148 throw new NoSuchElementException();
153 public void remove() {
154 throw new UnsupportedOperationException();
160 * Add a time event to the time chart entry
165 public void addTraceEvent(ITimeEvent timeEvent
) {
166 long time
= timeEvent
.getTime();
167 synchronized (fTraceEvents
) {
168 long index
= (fReferenceTime
== -1) ?
0 : (time
- fReferenceTime
) >> fPower
;
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));
174 index
= (int) ((time
- fReferenceTime
) >> fPower
);
178 fTraceEvents
.set(0, (TimeChartEvent
) timeEvent
);
179 } else if (index
< fTraceEvents
.capacity()) {
180 if (index
>= fTraceEvents
.size()) {
181 fTraceEvents
.setSize((int) index
+ 1);
184 int powershift
= (index
< 2 * fTraceEvents
.capacity()) ?
1 :
185 (int) Math
.ceil(Math
.log((double) (index
+ 1) / fTraceEvents
.capacity()) / Math
.log(2));
187 index
= (int) ((time
- fReferenceTime
) >> fPower
);
188 fTraceEvents
.setSize((int) index
+ 1);
190 TimeChartEvent event
= fTraceEvents
.get((int) index
);
192 fTraceEvents
.set((int) index
, (TimeChartEvent
) timeEvent
);
194 if (event
.getItemizedEntry() == null) {
195 event
.merge((TimeChartEvent
) timeEvent
);
197 event
.mergeDecorations((TimeChartEvent
) timeEvent
);
198 event
.getItemizedEntry().addTraceEvent(timeEvent
);
201 if (fReferenceTime
== -1 || time
< fReferenceTime
) {
202 fReferenceTime
= (time
>> fPower
) << fPower
;
204 if (fStartTime
== -1 || time
< fStartTime
) {
207 if (fStopTime
== -1 || time
> fStopTime
) {
213 private void merge(int powershift
) {
214 fPower
+= powershift
;
215 fReferenceTime
= (fReferenceTime
>> fPower
) << fPower
;
217 for (int i
= 0; i
< fTraceEvents
.size(); i
++) {
218 TimeChartEvent event
= fTraceEvents
.get(i
);
220 index
= (int) ((event
.getTime() - fReferenceTime
) >> fPower
);
221 TimeChartEvent mergedEvent
= fTraceEvents
.get(index
);
222 if (mergedEvent
== null) {
223 fTraceEvents
.set(index
, event
);
225 mergedEvent
.merge(event
);
228 fTraceEvents
.set(i
, null);
232 fTraceEvents
.setSize(index
+ 1);
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
));
241 for (int i
= 0; i
< indexshift
; i
++) {
242 fTraceEvents
.set(i
, null);
247 * Retrieve the trace associated with this entry
249 * @return The trace object
251 public ITmfTrace
getTrace() {
256 * Set the last rank of the entry
261 public void setLastRank(long rank
) {
266 * Retrieve the last rank of the entry
268 * @return The last rank
270 public long getLastRank() {