diff -r 5b9d4d8641ce -r ae255c9aa552 sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/GenericSampledTrace.java --- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/GenericSampledTrace.java Wed Jun 23 14:49:59 2010 +0300 +++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi/src/com/nokia/carbide/cpp/internal/pi/model/GenericSampledTrace.java Wed Jun 23 15:05:09 2010 +0300 @@ -17,21 +17,35 @@ package com.nokia.carbide.cpp.internal.pi.model; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.Enumeration; +import java.util.List; import java.util.Vector; public abstract class GenericSampledTrace extends GenericTrace { private static final long serialVersionUID = 5248402326692863890L; + + /** highest sync time within samples */ private long lastSampleTime; + /** the samples */ public Vector samples; + /** + * Constructor + */ public GenericSampledTrace() { this.samples = new Vector(); } + /** + * Adds the given sample to the samples collection + * @param sample the sample to add + */ public void addSample(GenericSample sample) { this.samples.add(sample); @@ -59,16 +73,31 @@ return lastSampleTime; } + /** + * returns all samples as an enumeration + * @return + */ public Enumeration getSamples() { return samples.elements(); } + /** + * Gets the nth element of the collection of samples + * @param number the index to look for + * @return the found sample (or ArrayIndexOutOfBoundsException) + */ public GenericSample getSample(int number) { return (GenericSample)this.samples.elementAt(number); } + /** + * Returns samples inside the given time period (including the boundaries). + * @param start the start time at which to include samples + * @param end the end time at which to include samples + * @return samples included in the time period + */ public Vector getSamplesInsideTimePeriod(long start, long end) { Enumeration sEnum = samples.elements(); @@ -88,128 +117,55 @@ return okSamples; } - - public GenericSample[] getSamplesForTime(long time) - { - // start the search from the middle of the sample set - long location = this.samples.size() / 2; - - // next, add or remove 1/4 of the length of the sample set - int div = 4; - - // boolean value indicating that the search proceeds now one step at a time - boolean saturated = false; + + /** + * Returns all samples with the given sync time + * @param time the time to look for + * @return array of samples for given sync time + */ + public GenericSample[] getSamplesForTime(long time) { + List resList = new ArrayList(); - // search algorithm, proceed until a value is found or - // reached the boundaries of the search area - - // note that the sample numbers MUST increase with growing - // indices within the samples vector in order for this - // algorithm to work! - while (true) - { - // take the sample from the location - GenericSample s = (GenericSample)samples.elementAt((int)location); - - // if the searched value is larger than the value at the proposed location - // increment the proposed location with the length of the data set divided - // by the divisor - if (s.sampleSynchTime < time) - { - if (!saturated) - { - int change = this.samples.size() / div; - if (change >= 1) - { - location += change; - div *= 2; - } - else - { - saturated = true; - } - } - else - { - // already saturated, go one step at a time - location++; - } + //find the sample just before the search result + GenericSample sample = new MockGenericSample(); + sample.sampleSynchTime = time-1; + int pos = Collections.binarySearch(samples, sample, new Comparator(){ + public int compare(GenericSample s1, GenericSample s2) { + return (int)(s1.sampleSynchTime - s2.sampleSynchTime); } - // similarly, decrement the proposed location - // if the value is smaller than the searched value - else if (s.sampleSynchTime > time) - { - if (!saturated) - { - int change = this.samples.size() / div; - if (change >= 1) - { - location -= change; - div *= 2; - } - else - { - saturated = true; - } - } - else - { - // already saturated, go one step at a time - location--; + }); + + //go to the first match + pos = pos < 0 ? (-(pos)-1) : pos+1; + + if (pos < samples.size()){ + //collect matches + for (int i = pos; i < samples.size(); i++) { + GenericSample found = samples.elementAt(i); + if (found.sampleSynchTime > time){ + break; + } else if (found.sampleSynchTime == time){ + resList.add(found); } } - else if (s.sampleSynchTime == time) - { - return this.getSamplesWithSameTimeFrom(location); - } - - // reached the end of the sample set without a match - if (location < 0 || location >= this.samples.size()) - return null; - } - - } - - private GenericSample[] getSamplesWithSameTimeFrom(long location) - { - long sameTime = ((GenericSample)samples.elementAt((int)location)).sampleSynchTime; - int lowBound = (int)location; - int highBound = (int)location; - - if (lowBound-1 >=0) - { - // go backwards as long as there are samples with the same samplenumber - while ( ((GenericSample)samples.elementAt(lowBound - 1)).sampleSynchTime == sameTime - && (lowBound - 1) >= 0) - { - lowBound--; - } } - if (highBound + 1 < this.samples.size()) - { - // go backwards as long as there are samples with the same samplenumber - while ( ((GenericSample)samples.elementAt(highBound + 1)).sampleSynchTime == sameTime - && (highBound + 1) < this.samples.size()) - { - highBound++; - } - } - - GenericSample[] sa = new GenericSample[highBound - lowBound + 1]; - for (int i = 0; i < sa.length; i++) - { - sa[i] = (GenericSample)samples.elementAt(lowBound + i); - } - - return sa; - } + return resList.toArray(new GenericSample[resList.size()]); + } + /** + * Returns the overall number of samples + * @return + */ public int getSampleAmount() { return this.samples.size(); } + /** + * Returns the sync time of the first sample, or 0. + * @return + */ public int getFirstSampleNumber() { if (this.samples.size() > 0) @@ -228,6 +184,9 @@ return (int)getLastSampleTime(); } + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ public String toString() { Enumeration sEnum = this.getSamples(); @@ -259,4 +218,10 @@ String total = new String(bytes); return total; } + + // this class is only needed for binary search + @SuppressWarnings("serial") + class MockGenericSample extends GenericSample { + } + }