Bug 378401: Implementation of time graph widget.
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / views / timechart / TimeChartAnalysisEntry.java
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 public class TimeChartAnalysisEntry implements ITimeGraphEntry {
24
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
32
33 TimeChartAnalysisEntry(ITmfTrace<?> trace, int modelSize) {
34 fTrace = trace;
35 fTraceEvents = new Vector<TimeChartEvent>(modelSize);
36 }
37
38 @Override
39 public ITimeGraphEntry[] getChildren() {
40 return null;
41 }
42
43 @Override
44 public ITimeGraphEntry getParent() {
45 return null;
46 }
47
48 @Override
49 public boolean hasChildren() {
50 return false;
51 }
52
53 @Override
54 public String getName() {
55 return fTrace.getName();
56 }
57
58 @Override
59 public long getStartTime() {
60 return fStartTime;
61 }
62
63 @Override
64 public long getEndTime() {
65 return fStopTime;
66 }
67
68 @Override
69 public Iterator<ITimeEvent> getTimeEventsIterator() {
70 return new EntryIterator(0, Long.MAX_VALUE, 0);
71 }
72
73 @Override
74 public Iterator<ITimeEvent> getTimeEventsIterator(long startTime, long stopTime, long maxDuration) {
75 return new EntryIterator(startTime, stopTime, maxDuration);
76 }
77
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;
85
86 public EntryIterator(long startTime, long stopTime, long maxDuration) {
87 fIteratorStartTime = startTime;
88 fIteratorStopTime = stopTime;
89 fIteratorMaxDuration = maxDuration;
90 }
91
92 @Override
93 public boolean hasNext() {
94 synchronized (fTraceEvents) {
95 if (next != null) return true;
96 if (nestedIterator != null) {
97 if (nestedIterator.hasNext()) {
98 return true;
99 } else {
100 nestedIterator = null;
101 }
102 }
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();
111 next = event;
112 return true;
113 } else {
114 nestedIterator = event.getItemizedEntry().getTimeEventsIterator(fIteratorStartTime, fIteratorStopTime, fIteratorMaxDuration);
115 return nestedIterator.hasNext();
116 }
117 }
118 }
119 }
120 return false;
121 }
122 }
123
124 @Override
125 public TimeChartEvent next() {
126 synchronized (fTraceEvents) {
127 if (nestedIterator != null) {
128 TimeChartEvent event = (TimeChartEvent) nestedIterator.next();
129 lastTime = event.getTime() + event.getDuration();
130 return event;
131 }
132 if (hasNext()) {
133 TimeChartEvent event = next;
134 next = null;
135 return event;
136 }
137 throw new NoSuchElementException();
138 }
139 }
140
141 @Override
142 public void remove() {
143 throw new UnsupportedOperationException();
144 }
145
146 }
147
148 public void addTraceEvent(ITimeEvent timeEvent) {
149 long time = timeEvent.getTime();
150 synchronized (fTraceEvents) {
151 long index = (fReferenceTime == -1) ? 0 : (time - fReferenceTime) >> fPower;
152 if (index < 0) {
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));
156 merge(powershift);
157 index = (int) ((time - fReferenceTime) >> fPower);
158 }
159 shift((int) -index);
160 index = 0;
161 fTraceEvents.set(0, (TimeChartEvent) timeEvent);
162 } else if (index < fTraceEvents.capacity()) {
163 if (index >= fTraceEvents.size()) {
164 fTraceEvents.setSize((int) index + 1);
165 }
166 } else {
167 int powershift = (index < 2 * fTraceEvents.capacity()) ? 1 :
168 (int) Math.ceil(Math.log((double) (index + 1) / fTraceEvents.capacity()) / Math.log(2));
169 merge(powershift);
170 index = (int) ((time - fReferenceTime) >> fPower);
171 fTraceEvents.setSize((int) index + 1);
172 }
173 TimeChartEvent event = (TimeChartEvent) fTraceEvents.get((int) index);
174 if (event == null) {
175 fTraceEvents.set((int) index, (TimeChartEvent) timeEvent);
176 } else {
177 if (event.getItemizedEntry() == null) {
178 event.merge((TimeChartEvent) timeEvent);
179 } else {
180 event.mergeDecorations((TimeChartEvent) timeEvent);
181 event.getItemizedEntry().addTraceEvent(timeEvent);
182 }
183 }
184 if (fReferenceTime == -1 || time < fReferenceTime) {
185 fReferenceTime = (time >> fPower) << fPower;
186 }
187 if (fStartTime == -1 || time < fStartTime) {
188 fStartTime = time;
189 }
190 if (fStopTime == -1 || time > fStopTime) {
191 fStopTime = time;
192 }
193 }
194 }
195
196 private void merge(int powershift) {
197 fPower += powershift;
198 fReferenceTime = (fReferenceTime >> fPower) << fPower;
199 int index = 0;
200 for (int i = 0; i < fTraceEvents.size(); i++) {
201 TimeChartEvent event = fTraceEvents.get(i);
202 if (event != null) {
203 index = (int) ((event.getTime() - fReferenceTime) >> fPower);
204 TimeChartEvent mergedEvent = (TimeChartEvent) fTraceEvents.get(index);
205 if (mergedEvent == null) {
206 fTraceEvents.set(index, event);
207 } else {
208 mergedEvent.merge(event);
209 }
210 if (i != index) {
211 fTraceEvents.set(i, null);
212 }
213 }
214 }
215 fTraceEvents.setSize(index + 1);
216 }
217
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));
223 }
224 for (int i = 0; i < indexshift; i++) {
225 fTraceEvents.set(i, null);
226 }
227 }
228
229 public ITmfTrace<?> getTrace() {
230 return fTrace;
231 }
232
233 public void setLastRank(long rank) {
234 fLastRank = rank;
235 }
236
237 public long getLastRank() {
238 return fLastRank;
239 }
240 }
This page took 0.044244 seconds and 6 git commands to generate.