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;
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();
138
public TimeChartEvent next() {
139
synchronized (fTraceEvents) {
140
if (nestedIterator != null) {
141
TimeChartEvent event = (TimeChartEvent) nestedIterator.next();
142
lastTime = event.getTime() + event.getDuration();
146
TimeChartEvent event = next;
150
throw new NoSuchElementException();
155
public void remove() {
156
throw new UnsupportedOperationException();
161
public void addTraceEvent(ITimeEvent timeEvent) {
162
long time = timeEvent.getTime();
163
synchronized (fTraceEvents) {
164
long index = (fReferenceTime == -1) ? 0 : (time - fReferenceTime) >> fPower;
166
if (fTraceEvents.capacity() - fTraceEvents.size() < -index) {
167
int powershift = (-index + fTraceEvents.size() <= 2 * fTraceEvents.capacity()) ? 1 :
168
(int) Math.ceil(Math.log((double) (-index + fTraceEvents.size()) / fTraceEvents.capacity()) / Math.log(2));
170
index = (int) ((time - fReferenceTime) >> fPower);
174
fTraceEvents.set(0, (TimeChartEvent) timeEvent);
175
} else if (index < fTraceEvents.capacity()) {
176
if (index >= fTraceEvents.size()) {
177
fTraceEvents.setSize((int) index + 1);
180
int powershift = (index < 2 * fTraceEvents.capacity()) ? 1 :
181
(int) Math.ceil(Math.log((double) (index + 1) / fTraceEvents.capacity()) / Math.log(2));
183
index = (int) ((time - fReferenceTime) >> fPower);
184
fTraceEvents.setSize((int) index + 1);
186
TimeChartEvent event = (TimeChartEvent) fTraceEvents.get((int) index);
188
fTraceEvents.set((int) index, (TimeChartEvent) timeEvent);
190
if (event.getItemizedEntry() == null) {
191
event.merge((TimeChartEvent) timeEvent);
193
event.mergeDecorations((TimeChartEvent) timeEvent);
194
event.getItemizedEntry().addTraceEvent(timeEvent);
197
if (fReferenceTime == -1 || time < fReferenceTime) {
198
fReferenceTime = (time >> fPower) << fPower;
200
if (fStartTime == -1 || time < fStartTime) {
203
if (fStopTime == -1 || time > fStopTime) {
209
private void merge(int powershift) {
210
fPower += powershift;
211
fReferenceTime = (fReferenceTime >> fPower) << fPower;
213
for (int i = 0; i < fTraceEvents.size(); i++) {
214
TimeChartEvent event = fTraceEvents.get(i);
216
index = (int) ((event.getTime() - fReferenceTime) >> fPower);
217
TimeChartEvent mergedEvent = (TimeChartEvent) fTraceEvents.get(index);
218
if (mergedEvent == null) {
219
fTraceEvents.set(index, event);
221
mergedEvent.merge(event);
224
fTraceEvents.set(i, null);
228
fTraceEvents.setSize(index + 1);
231
private void shift(int indexshift) {
232
int oldSize = fTraceEvents.size();
233
fTraceEvents.setSize(oldSize + indexshift);
234
for (int i = oldSize - 1; i >= 0; i--) {
235
fTraceEvents.set(i + indexshift, fTraceEvents.get(i));
237
for (int i = 0; i < indexshift; i++) {
238
fTraceEvents.set(i, null);
242
public ITmfTrace<?> getTrace() {
246
public void setLastRank(long rank) {
250
public long getLastRank() {