Commit | Line | Data |
---|---|---|
788ddcbc MK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2012 Ericsson | |
3 | * | |
4 | * All rights reserved. This program and the accompanying materials are made | |
5 | * 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: Matthew Khouzam - Initial API and implementation | |
10 | *******************************************************************************/ | |
11 | ||
12 | package org.eclipse.linuxtools.tmf.core.ctfadaptor; | |
13 | ||
14 | import java.util.ArrayList; | |
15 | import java.util.ListIterator; | |
16 | ||
17 | import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; | |
18 | import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation; | |
19 | ||
20 | /** | |
21 | * Lightweight Context for CtfTmf traces. Should only use 3 references, 1 ref to | |
22 | * a boxed Long, a long and an int. | |
23 | * | |
24 | * @author Matthew Khouzam | |
25 | * | |
26 | */ | |
27 | public class CtfTmfLightweightContext implements ITmfContext { | |
28 | ||
29 | // ------------------------------------------- | |
30 | // Constants | |
31 | // ------------------------------------------- | |
32 | private static final int MAX_COLLISIONS = 10; | |
33 | ||
34 | // ------------------------------------------- | |
35 | // Fields | |
36 | // ------------------------------------------- | |
37 | private CtfLocation curLocation; | |
38 | private long curRank; | |
39 | private int collisions; | |
40 | ||
41 | private CtfIterator fSeeker; | |
42 | final private ArrayList<CtfIterator> fIteratorPool; | |
43 | private ListIterator<CtfIterator> fCurrentIterator; | |
44 | ||
45 | // ------------------------------------------- | |
46 | // Constructor | |
47 | // ------------------------------------------- | |
48 | /** | |
49 | * | |
50 | * @param iters | |
51 | * the shared iterator pool. | |
52 | * @param pos | |
53 | * the iterator position. | |
54 | */ | |
55 | public CtfTmfLightweightContext(ArrayList<CtfIterator> iters, | |
56 | ListIterator<CtfIterator> pos) { | |
57 | fIteratorPool = iters; | |
58 | fCurrentIterator = pos; | |
59 | fSeeker = getIterator(); | |
60 | curLocation = new CtfLocation((Long)null); | |
61 | collisions = 0; | |
62 | } | |
63 | ||
64 | // ------------------------------------------- | |
65 | // TmfContext Overrides | |
66 | // ------------------------------------------- | |
67 | ||
68 | @Override | |
69 | public long getRank() { | |
70 | return curRank; | |
71 | } | |
72 | ||
73 | @Override | |
74 | public ITmfLocation<? extends Comparable<?>> getLocation() { | |
75 | return curLocation; | |
76 | } | |
77 | ||
78 | @Override | |
79 | public boolean hasValidRank() { | |
80 | return curRank != CtfLocation.INVALID_LOCATION; | |
81 | } | |
82 | ||
83 | @Override | |
84 | public void setLocation(ITmfLocation<? extends Comparable<?>> location) { | |
85 | curLocation = (CtfLocation) location; | |
86 | updateLocation(); | |
87 | } | |
88 | ||
89 | @Override | |
90 | public void setRank(long rank) { | |
91 | curRank = rank; | |
92 | ||
93 | } | |
94 | ||
95 | @Override | |
96 | public void increaseRank() { | |
97 | if (hasValidRank()) { | |
98 | curRank++; | |
99 | } | |
100 | } | |
101 | ||
102 | // ------------------------------------------- | |
103 | // CtfTmfTrace Helpers | |
104 | // ------------------------------------------- | |
105 | ||
106 | /** | |
107 | * Gets the current event. Wrapper to help CtfTmfTrace | |
108 | * @return The event or null | |
109 | */ | |
110 | public synchronized CtfTmfEvent getCurrentEvent() { | |
111 | updateLocation(); | |
112 | return fSeeker.getCurrentEvent(); | |
113 | } | |
114 | ||
115 | /** | |
116 | * Advances to a the next event. Wrapper to help CtfTmfTrace | |
117 | * @return success or not | |
118 | */ | |
119 | public synchronized boolean advance() { | |
120 | updateLocation(); | |
121 | boolean retVal = fSeeker.advance(); | |
122 | CtfTmfEvent currentEvent = fSeeker.getCurrentEvent(); | |
123 | if (currentEvent != null) { | |
124 | curLocation.setLocation(currentEvent.getTimestampValue()); | |
125 | } else { | |
126 | curLocation.setLocation(CtfLocation.INVALID_LOCATION); | |
127 | } | |
128 | ||
129 | return retVal; | |
130 | } | |
131 | ||
132 | @Override | |
133 | public void dispose() { | |
134 | // do nothing | |
135 | } | |
136 | ||
137 | /** | |
138 | * Seeks to a given timestamp. Wrapper to help CtfTmfTrace | |
139 | * @param timestamp desired timestamp | |
140 | * @return success or not | |
141 | */ | |
142 | public synchronized boolean seek(final long timestamp) { | |
143 | curLocation.setLocation(timestamp); | |
144 | collisions = 0; | |
145 | fSeeker = getIterator(); | |
146 | return updateLocation(); | |
147 | } | |
148 | ||
149 | /* | |
150 | * (non-Javadoc) | |
151 | * | |
152 | * @see java.lang.Object#clone() | |
153 | */ | |
154 | @Override | |
155 | public CtfTmfLightweightContext clone() { | |
156 | CtfTmfLightweightContext ret = new CtfTmfLightweightContext( | |
157 | fIteratorPool, fCurrentIterator); | |
158 | ret.curLocation = curLocation.clone(); | |
159 | ret.curRank = curRank; | |
160 | return ret; | |
161 | } | |
162 | ||
163 | // ------------------------------------------- | |
164 | // Private helpers | |
165 | // ------------------------------------------- | |
166 | /** | |
167 | * This updates the position of an iterator to the location(curLocation) | |
168 | * Since the iterators are in a pool to not exhaust the number of file | |
169 | * pointers some of them can be shared. This means there can be collisions | |
170 | * between contexts fighting over the same resource. A heuristic is applied | |
171 | * that if there are MAX_COLLISIONS collisions in a row, the iterator is | |
172 | * changed for the next one in the iterator pool. | |
173 | * | |
174 | * @return true if the location is correct. | |
175 | */ | |
176 | private synchronized boolean updateLocation() { | |
177 | if (!curLocation.getLocation().equals( | |
178 | (fSeeker.getLocation().getLocation()))) { | |
179 | collisions++; | |
180 | if (collisions > MAX_COLLISIONS) { | |
181 | fSeeker = getIterator(); | |
182 | collisions = 0; | |
183 | } | |
184 | fSeeker.setRank(curRank); | |
185 | return fSeeker.seek(curLocation.getLocation()); | |
186 | } | |
187 | collisions = 0; | |
188 | return true; | |
189 | } | |
190 | ||
191 | /** | |
192 | * gets the next iterator in a pool. | |
193 | * | |
194 | * @return | |
195 | */ | |
196 | private CtfIterator getIterator() { | |
197 | if (!fCurrentIterator.hasNext()) { | |
198 | fCurrentIterator = fIteratorPool.listIterator(0); | |
199 | } | |
200 | return fCurrentIterator.next(); | |
201 | } | |
202 | ||
203 | } |