~ubuntu-branches/ubuntu/trusty/eclipse-linuxtools/trusty

« back to all changes in this revision

Viewing changes to lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/timechart/TimeChartAnalysisEntry.java

  • Committer: Package Import Robot
  • Author(s): Jakub Adam
  • Date: 2012-06-29 12:07:30 UTC
  • Revision ID: package-import@ubuntu.com-20120629120730-bfri1xys1i71dpn6
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*******************************************************************************
 
2
 * Copyright (c) 2010 Ericsson
 
3
 *
 
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
 
8
 *
 
9
 * Contributors:
 
10
 *   Patrick Tasse - Initial API and implementation
 
11
 *******************************************************************************/
 
12
 
 
13
package org.eclipse.linuxtools.tmf.ui.views.timechart;
 
14
 
 
15
import java.util.Iterator;
 
16
import java.util.NoSuchElementException;
 
17
import java.util.Vector;
 
18
 
 
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;
 
22
 
 
23
/**
 
24
 * An entry (row) in the time chart analysis view
 
25
 *
 
26
 * @version 1.0
 
27
 * @author Patrick Tasse
 
28
 */
 
29
public class TimeChartAnalysisEntry implements ITimeGraphEntry {
 
30
 
 
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
 
38
 
 
39
    TimeChartAnalysisEntry(ITmfTrace<?> trace, int modelSize) {
 
40
        fTrace = trace;
 
41
        fTraceEvents = new Vector<TimeChartEvent>(modelSize);
 
42
    }
 
43
 
 
44
    @Override
 
45
    public ITimeGraphEntry[] getChildren() {
 
46
        return null;
 
47
    }
 
48
 
 
49
    @Override
 
50
    public ITimeGraphEntry getParent() {
 
51
        return null;
 
52
    }
 
53
 
 
54
    @Override
 
55
    public boolean hasChildren() {
 
56
        return false;
 
57
    }
 
58
 
 
59
    @Override
 
60
    public String getName() {
 
61
        return fTrace.getName();
 
62
    }
 
63
 
 
64
    @Override
 
65
    public long getStartTime() {
 
66
        return fStartTime;
 
67
    }
 
68
 
 
69
    @Override
 
70
    public long getEndTime() {
 
71
        return fStopTime;
 
72
    }
 
73
 
 
74
    @Override
 
75
    public boolean hasTimeEvents() {
 
76
        return true;
 
77
    }
 
78
 
 
79
    @Override
 
80
    public Iterator<ITimeEvent> getTimeEventsIterator() {
 
81
        return new EntryIterator(0, Long.MAX_VALUE, 0);
 
82
    }
 
83
 
 
84
    @Override
 
85
    public Iterator<ITimeEvent> getTimeEventsIterator(long startTime, long stopTime, long maxDuration) {
 
86
        return new EntryIterator(startTime, stopTime, maxDuration);
 
87
    }
 
88
 
 
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;
 
96
 
 
97
        public EntryIterator(long startTime, long stopTime, long maxDuration) {
 
98
            fIteratorStartTime = startTime;
 
99
            fIteratorStopTime = stopTime;
 
100
            fIteratorMaxDuration = maxDuration;
 
101
        }
 
102
 
 
103
        @Override
 
104
        public boolean hasNext() {
 
105
            synchronized (fTraceEvents) {
 
106
                if (next != null) {
 
107
                    return true;
 
108
                }
 
109
                if (nestedIterator != null) {
 
110
                    if (nestedIterator.hasNext()) {
 
111
                        return true;
 
112
                    } else {
 
113
                        nestedIterator = null;
 
114
                    }
 
115
                }
 
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();
 
124
                                next = event;
 
125
                                return true;
 
126
                            } else {
 
127
                                nestedIterator = event.getItemizedEntry().getTimeEventsIterator(fIteratorStartTime, fIteratorStopTime, fIteratorMaxDuration);
 
128
                                return nestedIterator.hasNext();
 
129
                            }
 
130
                        }
 
131
                    }
 
132
                }
 
133
                return false;
 
134
            }
 
135
        }
 
136
 
 
137
        @Override
 
138
        public TimeChartEvent next() {
 
139
            synchronized (fTraceEvents) {
 
140
                if (nestedIterator != null) {
 
141
                    TimeChartEvent event = (TimeChartEvent) nestedIterator.next();
 
142
                    lastTime = event.getTime() + event.getDuration();
 
143
                    return event;
 
144
                }
 
145
                if (hasNext()) {
 
146
                    TimeChartEvent event = next;
 
147
                    next = null;
 
148
                    return event;
 
149
                }
 
150
                throw new NoSuchElementException();
 
151
            }
 
152
        }
 
153
 
 
154
        @Override
 
155
        public void remove() {
 
156
            throw new UnsupportedOperationException();
 
157
        }
 
158
 
 
159
    }
 
160
 
 
161
    public void addTraceEvent(ITimeEvent timeEvent) {
 
162
        long time = timeEvent.getTime();
 
163
        synchronized (fTraceEvents) {
 
164
            long index = (fReferenceTime == -1) ? 0 : (time - fReferenceTime) >> fPower;
 
165
            if (index < 0) {
 
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));
 
169
                    merge(powershift);
 
170
                    index = (int) ((time - fReferenceTime) >> fPower);
 
171
                }
 
172
                shift((int) -index);
 
173
                index = 0;
 
174
                fTraceEvents.set(0, (TimeChartEvent) timeEvent);
 
175
            } else if (index < fTraceEvents.capacity()) {
 
176
                if (index >= fTraceEvents.size()) {
 
177
                    fTraceEvents.setSize((int) index + 1);
 
178
                }
 
179
            } else {
 
180
                int powershift = (index < 2 * fTraceEvents.capacity()) ? 1 :
 
181
                    (int) Math.ceil(Math.log((double) (index + 1) / fTraceEvents.capacity()) / Math.log(2));
 
182
                merge(powershift);
 
183
                index = (int) ((time - fReferenceTime) >> fPower);
 
184
                fTraceEvents.setSize((int) index + 1);
 
185
            }
 
186
            TimeChartEvent event = (TimeChartEvent) fTraceEvents.get((int) index);
 
187
            if (event == null) {
 
188
                fTraceEvents.set((int) index, (TimeChartEvent) timeEvent);
 
189
            } else {
 
190
                if (event.getItemizedEntry() == null) {
 
191
                    event.merge((TimeChartEvent) timeEvent);
 
192
                } else {
 
193
                        event.mergeDecorations((TimeChartEvent) timeEvent);
 
194
                    event.getItemizedEntry().addTraceEvent(timeEvent);
 
195
                }
 
196
            }
 
197
            if (fReferenceTime == -1 || time < fReferenceTime) {
 
198
                fReferenceTime = (time >> fPower) << fPower;
 
199
            }
 
200
            if (fStartTime == -1 || time < fStartTime) {
 
201
                fStartTime = time;
 
202
            }
 
203
            if (fStopTime == -1 || time > fStopTime) {
 
204
                fStopTime = time;
 
205
            }
 
206
        }
 
207
    }
 
208
 
 
209
    private void merge(int powershift) {
 
210
        fPower += powershift;
 
211
        fReferenceTime = (fReferenceTime >> fPower) << fPower;
 
212
        int index = 0;
 
213
        for (int i = 0; i < fTraceEvents.size(); i++) {
 
214
            TimeChartEvent event = fTraceEvents.get(i);
 
215
            if (event != null) {
 
216
                index = (int) ((event.getTime() - fReferenceTime) >> fPower);
 
217
                TimeChartEvent mergedEvent = (TimeChartEvent) fTraceEvents.get(index);
 
218
                if (mergedEvent == null) {
 
219
                    fTraceEvents.set(index, event);
 
220
                } else {
 
221
                    mergedEvent.merge(event);
 
222
                }
 
223
                if (i != index) {
 
224
                    fTraceEvents.set(i, null);
 
225
                }
 
226
            }
 
227
        }
 
228
        fTraceEvents.setSize(index + 1);
 
229
    }
 
230
 
 
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));
 
236
        }
 
237
        for (int i = 0; i < indexshift; i++) {
 
238
            fTraceEvents.set(i, null);
 
239
        }
 
240
    }
 
241
 
 
242
    public ITmfTrace<?> getTrace() {
 
243
        return fTrace;
 
244
    }
 
245
 
 
246
    public void setLastRank(long rank) {
 
247
        fLastRank = rank;
 
248
    }
 
249
 
 
250
    public long getLastRank() {
 
251
        return fLastRank;
 
252
    }
 
253
}