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
;
23 public class TimeChartAnalysisEntry
implements ITimeGraphEntry
{
25 private ITmfTrace
<?
> fTrace
;
26 private Vector
<TimeChartEvent
> fTraceEvents
;
27 private int fPower
= 0; // 2^fPower nanoseconds per vector position
28 private long fReferenceTime
= -1; // time corresponding to beginning of index 0
29 private long fStartTime
= -1; // time of first event
30 private long fStopTime
= -1; // time of last event
31 private long fLastRank
= -1; // rank of last processed trace event
33 TimeChartAnalysisEntry(ITmfTrace
<?
> trace
, int modelSize
) {
35 fTraceEvents
= new Vector
<TimeChartEvent
>(modelSize
);
39 public ITimeGraphEntry
[] getChildren() {
44 public ITimeGraphEntry
getParent() {
49 public boolean hasChildren() {
54 public String
getName() {
55 return fTrace
.getName();
59 public long getStartTime() {
64 public long getEndTime() {
69 public Iterator
<ITimeEvent
> getTimeEventsIterator() {
70 return new EntryIterator(0, Long
.MAX_VALUE
, 0);
74 public Iterator
<ITimeEvent
> getTimeEventsIterator(long startTime
, long stopTime
, long maxDuration
) {
75 return new EntryIterator(startTime
, stopTime
, maxDuration
);
78 private class EntryIterator
implements Iterator
<ITimeEvent
> {
79 private final long fIteratorStartTime
;
80 private final long fIteratorStopTime
;
81 private final long fIteratorMaxDuration
;
82 private long lastTime
= -1;
83 private TimeChartEvent next
= null;
84 private Iterator
<ITimeEvent
> nestedIterator
= null;
86 public EntryIterator(long startTime
, long stopTime
, long maxDuration
) {
87 fIteratorStartTime
= startTime
;
88 fIteratorStopTime
= stopTime
;
89 fIteratorMaxDuration
= maxDuration
;
93 public boolean hasNext() {
94 synchronized (fTraceEvents
) {
95 if (next
!= null) return true;
96 if (nestedIterator
!= null) {
97 if (nestedIterator
.hasNext()) {
100 nestedIterator
= null;
103 long time
= (lastTime
== -1) ? fStartTime
: lastTime
;
104 int index
= (fReferenceTime
== -1) ?
0 : (int) ((time
- fReferenceTime
) >> fPower
);
105 while (index
< fTraceEvents
.size()) {
106 TimeChartEvent event
= fTraceEvents
.get(index
++);
107 if (event
!= null && (lastTime
== -1 || event
.getTime() > time
)) {
108 if (event
.getTime() + event
.getDuration() >= fIteratorStartTime
&& event
.getTime() <= fIteratorStopTime
) {
109 if (event
.getItemizedEntry() == null || event
.getDuration() <= fIteratorMaxDuration
) {
110 lastTime
= event
.getTime() + event
.getDuration();
114 nestedIterator
= event
.getItemizedEntry().getTimeEventsIterator(fIteratorStartTime
, fIteratorStopTime
, fIteratorMaxDuration
);
115 return nestedIterator
.hasNext();
125 public TimeChartEvent
next() {
126 synchronized (fTraceEvents
) {
127 if (nestedIterator
!= null) {
128 TimeChartEvent event
= (TimeChartEvent
) nestedIterator
.next();
129 lastTime
= event
.getTime() + event
.getDuration();
133 TimeChartEvent event
= next
;
137 throw new NoSuchElementException();
142 public void remove() {
143 throw new UnsupportedOperationException();
148 public void addTraceEvent(ITimeEvent timeEvent
) {
149 long time
= timeEvent
.getTime();
150 synchronized (fTraceEvents
) {
151 long index
= (fReferenceTime
== -1) ?
0 : (time
- fReferenceTime
) >> fPower
;
153 if (fTraceEvents
.capacity() - fTraceEvents
.size() < -index
) {
154 int powershift
= (-index
+ fTraceEvents
.size() <= 2 * fTraceEvents
.capacity()) ?
1 :
155 (int) Math
.ceil(Math
.log((double) (-index
+ fTraceEvents
.size()) / fTraceEvents
.capacity()) / Math
.log(2));
157 index
= (int) ((time
- fReferenceTime
) >> fPower
);
161 fTraceEvents
.set(0, (TimeChartEvent
) timeEvent
);
162 } else if (index
< fTraceEvents
.capacity()) {
163 if (index
>= fTraceEvents
.size()) {
164 fTraceEvents
.setSize((int) index
+ 1);
167 int powershift
= (index
< 2 * fTraceEvents
.capacity()) ?
1 :
168 (int) Math
.ceil(Math
.log((double) (index
+ 1) / fTraceEvents
.capacity()) / Math
.log(2));
170 index
= (int) ((time
- fReferenceTime
) >> fPower
);
171 fTraceEvents
.setSize((int) index
+ 1);
173 TimeChartEvent event
= (TimeChartEvent
) fTraceEvents
.get((int) index
);
175 fTraceEvents
.set((int) index
, (TimeChartEvent
) timeEvent
);
177 if (event
.getItemizedEntry() == null) {
178 event
.merge((TimeChartEvent
) timeEvent
);
180 event
.mergeDecorations((TimeChartEvent
) timeEvent
);
181 event
.getItemizedEntry().addTraceEvent(timeEvent
);
184 if (fReferenceTime
== -1 || time
< fReferenceTime
) {
185 fReferenceTime
= (time
>> fPower
) << fPower
;
187 if (fStartTime
== -1 || time
< fStartTime
) {
190 if (fStopTime
== -1 || time
> fStopTime
) {
196 private void merge(int powershift
) {
197 fPower
+= powershift
;
198 fReferenceTime
= (fReferenceTime
>> fPower
) << fPower
;
200 for (int i
= 0; i
< fTraceEvents
.size(); i
++) {
201 TimeChartEvent event
= fTraceEvents
.get(i
);
203 index
= (int) ((event
.getTime() - fReferenceTime
) >> fPower
);
204 TimeChartEvent mergedEvent
= (TimeChartEvent
) fTraceEvents
.get(index
);
205 if (mergedEvent
== null) {
206 fTraceEvents
.set(index
, event
);
208 mergedEvent
.merge(event
);
211 fTraceEvents
.set(i
, null);
215 fTraceEvents
.setSize(index
+ 1);
218 private void shift(int indexshift
) {
219 int oldSize
= fTraceEvents
.size();
220 fTraceEvents
.setSize(oldSize
+ indexshift
);
221 for (int i
= oldSize
- 1; i
>= 0; i
--) {
222 fTraceEvents
.set(i
+ indexshift
, fTraceEvents
.get(i
));
224 for (int i
= 0; i
< indexshift
; i
++) {
225 fTraceEvents
.set(i
, null);
229 public ITmfTrace
<?
> getTrace() {
233 public void setLastRank(long rank
) {
237 public long getLastRank() {