15 * |
15 * |
16 */ |
16 */ |
17 |
17 |
18 package com.nokia.carbide.cpp.internal.pi.model; |
18 package com.nokia.carbide.cpp.internal.pi.model; |
19 |
19 |
|
20 import java.util.ArrayList; |
|
21 import java.util.Collections; |
|
22 import java.util.Comparator; |
20 import java.util.Enumeration; |
23 import java.util.Enumeration; |
|
24 import java.util.List; |
21 import java.util.Vector; |
25 import java.util.Vector; |
22 |
26 |
23 public abstract class GenericSampledTrace extends GenericTrace |
27 public abstract class GenericSampledTrace extends GenericTrace |
24 { |
28 { |
25 private static final long serialVersionUID = 5248402326692863890L; |
29 private static final long serialVersionUID = 5248402326692863890L; |
|
30 |
|
31 /** highest sync time within samples */ |
26 private long lastSampleTime; |
32 private long lastSampleTime; |
27 |
33 |
|
34 /** the samples */ |
28 public Vector<GenericSample> samples; |
35 public Vector<GenericSample> samples; |
29 |
36 |
|
37 /** |
|
38 * Constructor |
|
39 */ |
30 public GenericSampledTrace() |
40 public GenericSampledTrace() |
31 { |
41 { |
32 this.samples = new Vector<GenericSample>(); |
42 this.samples = new Vector<GenericSample>(); |
33 } |
43 } |
34 |
44 |
|
45 /** |
|
46 * Adds the given sample to the samples collection |
|
47 * @param sample the sample to add |
|
48 */ |
35 public void addSample(GenericSample sample) |
49 public void addSample(GenericSample sample) |
36 { |
50 { |
37 this.samples.add(sample); |
51 this.samples.add(sample); |
38 if (sample.sampleSynchTime > lastSampleTime){ |
52 if (sample.sampleSynchTime > lastSampleTime){ |
39 lastSampleTime = sample.sampleSynchTime; |
53 lastSampleTime = sample.sampleSynchTime; |
57 } |
71 } |
58 } |
72 } |
59 return lastSampleTime; |
73 return lastSampleTime; |
60 } |
74 } |
61 |
75 |
|
76 /** |
|
77 * returns all samples as an enumeration |
|
78 * @return |
|
79 */ |
62 public Enumeration<GenericSample> getSamples() |
80 public Enumeration<GenericSample> getSamples() |
63 { |
81 { |
64 return samples.elements(); |
82 return samples.elements(); |
65 } |
83 } |
66 |
84 |
|
85 /** |
|
86 * Gets the nth element of the collection of samples |
|
87 * @param number the index to look for |
|
88 * @return the found sample (or ArrayIndexOutOfBoundsException) |
|
89 */ |
67 public GenericSample getSample(int number) |
90 public GenericSample getSample(int number) |
68 { |
91 { |
69 return (GenericSample)this.samples.elementAt(number); |
92 return (GenericSample)this.samples.elementAt(number); |
70 } |
93 } |
71 |
94 |
|
95 /** |
|
96 * Returns samples inside the given time period (including the boundaries). |
|
97 * @param start the start time at which to include samples |
|
98 * @param end the end time at which to include samples |
|
99 * @return samples included in the time period |
|
100 */ |
72 public Vector<GenericSample> getSamplesInsideTimePeriod(long start, long end) |
101 public Vector<GenericSample> getSamplesInsideTimePeriod(long start, long end) |
73 { |
102 { |
74 Enumeration<GenericSample> sEnum = samples.elements(); |
103 Enumeration<GenericSample> sEnum = samples.elements(); |
75 Vector<GenericSample> okSamples = new Vector<GenericSample>(); |
104 Vector<GenericSample> okSamples = new Vector<GenericSample>(); |
76 |
105 |
86 } |
115 } |
87 } |
116 } |
88 |
117 |
89 return okSamples; |
118 return okSamples; |
90 } |
119 } |
91 |
120 |
92 public GenericSample[] getSamplesForTime(long time) |
121 /** |
93 { |
122 * Returns all samples with the given sync time |
94 // start the search from the middle of the sample set |
123 * @param time the time to look for |
95 long location = this.samples.size() / 2; |
124 * @return array of samples for given sync time |
96 |
125 */ |
97 // next, add or remove 1/4 of the length of the sample set |
126 public GenericSample[] getSamplesForTime(long time) { |
98 int div = 4; |
127 List<GenericSample> resList = new ArrayList<GenericSample>(); |
99 |
128 |
100 // boolean value indicating that the search proceeds now one step at a time |
129 //find the sample just before the search result |
101 boolean saturated = false; |
130 GenericSample sample = new MockGenericSample(); |
102 |
131 sample.sampleSynchTime = time-1; |
103 // search algorithm, proceed until a value is found or |
132 int pos = Collections.binarySearch(samples, sample, new Comparator<GenericSample>(){ |
104 // reached the boundaries of the search area |
133 public int compare(GenericSample s1, GenericSample s2) { |
105 |
134 return (int)(s1.sampleSynchTime - s2.sampleSynchTime); |
106 // note that the sample numbers MUST increase with growing |
135 } |
107 // indices within the samples vector in order for this |
136 }); |
108 // algorithm to work! |
137 |
109 while (true) |
138 //go to the first match |
110 { |
139 pos = pos < 0 ? (-(pos)-1) : pos+1; |
111 // take the sample from the location |
140 |
112 GenericSample s = (GenericSample)samples.elementAt((int)location); |
141 if (pos < samples.size()){ |
113 |
142 //collect matches |
114 // if the searched value is larger than the value at the proposed location |
143 for (int i = pos; i < samples.size(); i++) { |
115 // increment the proposed location with the length of the data set divided |
144 GenericSample found = samples.elementAt(i); |
116 // by the divisor |
145 if (found.sampleSynchTime > time){ |
117 if (s.sampleSynchTime < time) |
146 break; |
118 { |
147 } else if (found.sampleSynchTime == time){ |
119 if (!saturated) |
148 resList.add(found); |
120 { |
|
121 int change = this.samples.size() / div; |
|
122 if (change >= 1) |
|
123 { |
|
124 location += change; |
|
125 div *= 2; |
|
126 } |
|
127 else |
|
128 { |
|
129 saturated = true; |
|
130 } |
|
131 } |
149 } |
132 else |
150 } |
133 { |
|
134 // already saturated, go one step at a time |
|
135 location++; |
|
136 } |
|
137 } |
|
138 // similarly, decrement the proposed location |
|
139 // if the value is smaller than the searched value |
|
140 else if (s.sampleSynchTime > time) |
|
141 { |
|
142 if (!saturated) |
|
143 { |
|
144 int change = this.samples.size() / div; |
|
145 if (change >= 1) |
|
146 { |
|
147 location -= change; |
|
148 div *= 2; |
|
149 } |
|
150 else |
|
151 { |
|
152 saturated = true; |
|
153 } |
|
154 } |
|
155 else |
|
156 { |
|
157 // already saturated, go one step at a time |
|
158 location--; |
|
159 } |
|
160 } |
|
161 else if (s.sampleSynchTime == time) |
|
162 { |
|
163 return this.getSamplesWithSameTimeFrom(location); |
|
164 } |
|
165 |
|
166 // reached the end of the sample set without a match |
|
167 if (location < 0 || location >= this.samples.size()) |
|
168 return null; |
|
169 } |
151 } |
170 |
152 |
171 } |
153 return resList.toArray(new GenericSample[resList.size()]); |
172 |
154 } |
173 private GenericSample[] getSamplesWithSameTimeFrom(long location) |
155 |
174 { |
156 /** |
175 long sameTime = ((GenericSample)samples.elementAt((int)location)).sampleSynchTime; |
157 * Returns the overall number of samples |
176 int lowBound = (int)location; |
158 * @return |
177 int highBound = (int)location; |
159 */ |
178 |
|
179 if (lowBound-1 >=0) |
|
180 { |
|
181 // go backwards as long as there are samples with the same samplenumber |
|
182 while ( ((GenericSample)samples.elementAt(lowBound - 1)).sampleSynchTime == sameTime |
|
183 && (lowBound - 1) >= 0) |
|
184 { |
|
185 lowBound--; |
|
186 } |
|
187 } |
|
188 |
|
189 if (highBound + 1 < this.samples.size()) |
|
190 { |
|
191 // go backwards as long as there are samples with the same samplenumber |
|
192 while ( ((GenericSample)samples.elementAt(highBound + 1)).sampleSynchTime == sameTime |
|
193 && (highBound + 1) < this.samples.size()) |
|
194 { |
|
195 highBound++; |
|
196 } |
|
197 } |
|
198 |
|
199 GenericSample[] sa = new GenericSample[highBound - lowBound + 1]; |
|
200 for (int i = 0; i < sa.length; i++) |
|
201 { |
|
202 sa[i] = (GenericSample)samples.elementAt(lowBound + i); |
|
203 } |
|
204 |
|
205 return sa; |
|
206 } |
|
207 |
|
208 public int getSampleAmount() |
160 public int getSampleAmount() |
209 { |
161 { |
210 return this.samples.size(); |
162 return this.samples.size(); |
211 } |
163 } |
212 |
164 |
|
165 /** |
|
166 * Returns the sync time of the first sample, or 0. |
|
167 * @return |
|
168 */ |
213 public int getFirstSampleNumber() |
169 public int getFirstSampleNumber() |
214 { |
170 { |
215 if (this.samples.size() > 0) |
171 if (this.samples.size() > 0) |
216 return (int)this.getSample(0).sampleSynchTime; |
172 return (int)this.getSample(0).sampleSynchTime; |
217 else |
173 else |