View Javadoc

1   /**
2    * Copyright (c) 2012, University of Konstanz, Distributed Systems Group
3    * All rights reserved.
4    * 
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions are met:
7    * * Redistributions of source code must retain the above copyright
8    * notice, this list of conditions and the following disclaimer.
9    * * Redistributions in binary form must reproduce the above copyright
10   * notice, this list of conditions and the following disclaimer in the
11   * documentation and/or other materials provided with the distribution.
12   * * Neither the name of the University of Konstanz nor the
13   * names of its contributors may be used to endorse or promote products
14   * derived from this software without specific prior written permission.
15   * 
16   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19   * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20   * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26   */
27  package org.perfidix.result;
28  
29  import java.util.Collection;
30  import java.util.Hashtable;
31  import java.util.LinkedList;
32  import java.util.Map;
33  import java.util.Set;
34  
35  import org.apache.commons.collections.primitives.adapters.CollectionDoubleCollection;
36  import org.apache.commons.math.stat.descriptive.AbstractUnivariateStatistic;
37  import org.apache.commons.math.stat.descriptive.moment.Mean;
38  import org.apache.commons.math.stat.descriptive.moment.StandardDeviation;
39  import org.apache.commons.math.stat.descriptive.rank.Max;
40  import org.apache.commons.math.stat.descriptive.rank.Min;
41  import org.apache.commons.math.stat.descriptive.rank.Percentile;
42  import org.apache.commons.math.stat.descriptive.summary.Sum;
43  import org.apache.commons.math.stat.descriptive.summary.SumOfSquares;
44  import org.perfidix.meter.AbstractMeter;
45  
46  /**
47   * Results which are generated through the benchmark are stored in the inherted
48   * implementation of this class. The storage is done corresponding to the
49   * mapping of meters.
50   * 
51   * @author Sebastian Graf, University of Konstanz
52   * @author Alexander Onea, neue Couch
53   */
54  public abstract class AbstractResult {
55  
56      /** Related element of this container. Can be a method or a class. */
57      private transient final Object relatedElement;
58  
59      /**
60       * Results mapped to the meters.
61       */
62      private transient final Map<AbstractMeter, Collection<Double>> meterResults;
63  
64      /**
65       * Constructor with a given name.
66       * 
67       * @param paramElement
68       *            element to this result.
69       */
70      protected AbstractResult(final Object paramElement) {
71          this.relatedElement = paramElement;
72          this.meterResults = new Hashtable<AbstractMeter, Collection<Double>>();
73  
74      }
75  
76      /**
77       * Returns the name of the related element where these results belong to.
78       * 
79       * @return the name as a String.
80       */
81      public abstract String getElementName();
82  
83      /**
84       * an array of all data items in the structure.
85       * 
86       * @param meter
87       *            for the results wanted
88       * @return the result set.
89       */
90      public final Collection<Double> getResultSet(final AbstractMeter meter) {
91          checkIfMeterExists(meter);
92          return this.meterResults.get(meter);
93      }
94  
95      /**
96       * Getting all meters registered in this result.
97       * 
98       * @return a set of all meters.
99       */
100     public final Set<AbstractMeter> getRegisteredMeters() {
101         return this.meterResults.keySet();
102     }
103 
104     /**
105      * Returns the arithmetic mean of the result set. avg() is an alias for this
106      * method.
107      * 
108      * @param meter
109      *            the meter of the mean
110      * @return the mean value.
111      */
112     public final double mean(final AbstractMeter meter) {
113         checkIfMeterExists(meter);
114         final AbstractUnivariateStatistic mean = new Mean();
115         final CollectionDoubleCollection doubleColl =
116             new CollectionDoubleCollection(this.meterResults.get(meter));
117         return mean.evaluate(doubleColl.toArray(), 0, doubleColl.toArray().length);
118     }
119 
120     /**
121      * Computes the square sum of the elements.
122      * 
123      * @param meter
124      *            the meter of the mean
125      * @return the square sum.
126      */
127     public final double squareSum(final AbstractMeter meter) {
128         checkIfMeterExists(meter);
129         final AbstractUnivariateStatistic sqrSum = new SumOfSquares();
130         final CollectionDoubleCollection doubleColl =
131             new CollectionDoubleCollection(this.meterResults.get(meter));
132         return sqrSum.evaluate(doubleColl.toArray(), 0, doubleColl.toArray().length);
133     }
134 
135     /**
136      * Computes the standard deviation.
137      * 
138      * @param meter
139      *            the meter of the mean
140      * @return the standard deviation
141      */
142     public final double getStandardDeviation(final AbstractMeter meter) {
143         checkIfMeterExists(meter);
144         final AbstractUnivariateStatistic stdDev = new StandardDeviation();
145         final CollectionDoubleCollection doubleColl =
146             new CollectionDoubleCollection(this.meterResults.get(meter));
147         return stdDev.evaluate(doubleColl.toArray(), 0, doubleColl.toArray().length);
148     }
149 
150     /**
151      * Computes the sum over all data items.
152      * 
153      * @param meter
154      *            the meter of the mean
155      * @return the sum of all runs.
156      */
157     public final double sum(final AbstractMeter meter) {
158         checkIfMeterExists(meter);
159         final AbstractUnivariateStatistic sum = new Sum();
160         final CollectionDoubleCollection doubleColl =
161             new CollectionDoubleCollection(this.meterResults.get(meter));
162         return sum.evaluate(doubleColl.toArray(), 0, doubleColl.toArray().length);
163     }
164 
165     /**
166      * Computes the minimum.
167      * 
168      * @param meter
169      *            the meter of the mean
170      * @return the minimum result value.
171      */
172     public final double min(final AbstractMeter meter) {
173         checkIfMeterExists(meter);
174         final AbstractUnivariateStatistic min = new Min();
175         final CollectionDoubleCollection doubleColl =
176             new CollectionDoubleCollection(this.meterResults.get(meter));
177         return min.evaluate(doubleColl.toArray(), 0, doubleColl.toArray().length);
178     }
179 
180     /**
181      * Computes the confidence 05 interval-factor. This value has to be combined
182      * with the mean to get the confidence-interval.
183      * 
184      * @param meter
185      *            the meter for the 05-confidence interval factor
186      * @return the 99% confidence
187      */
188     public final double getConf05(final AbstractMeter meter) {
189         checkIfMeterExists(meter);
190         final AbstractUnivariateStatistic conf05 = new Percentile(5.0);
191         final CollectionDoubleCollection doubleColl =
192             new CollectionDoubleCollection(this.meterResults.get(meter));
193         return conf05.evaluate(doubleColl.toArray(), 0, doubleColl.toArray().length);
194 
195     }
196 
197     /**
198      * Computes the confidence 95 interval-factor. This value has to be combined
199      * with the mean to get the confidence-interval.
200      * 
201      * @param meter
202      *            the meter for the 95-confidence interval factor
203      * @return the 95% confidence
204      */
205     public final double getConf95(final AbstractMeter meter) {
206         checkIfMeterExists(meter);
207         final AbstractUnivariateStatistic conf95 = new Percentile(95.0);
208         final CollectionDoubleCollection doubleColl =
209             new CollectionDoubleCollection(this.meterResults.get(meter));
210         return conf95.evaluate(doubleColl.toArray(), 0, doubleColl.toArray().length);
211     }
212 
213     /**
214      * Computes the maximum.
215      * 
216      * @param meter
217      *            the meter of the mean
218      * @return the maximum result value.
219      */
220     public final double max(final AbstractMeter meter) {
221         checkIfMeterExists(meter);
222         final AbstractUnivariateStatistic max = new Max();
223         final CollectionDoubleCollection doubleColl =
224             new CollectionDoubleCollection(this.meterResults.get(meter));
225         return max.evaluate(doubleColl.toArray(), 0, doubleColl.toArray().length);
226     }
227 
228     /**
229      * Returning the number of results for one specific meter.
230      * 
231      * @param meter
232      *            to get the number of results
233      * @return the number of results of one meter
234      */
235     public final int getNumberOfResult(final AbstractMeter meter) {
236         checkIfMeterExists(meter);
237         return meterResults.get(meter).size();
238     }
239 
240     /**
241      * Getter for the related element where this container corresponds to.
242      * 
243      * @return the relatedElement
244      */
245     public final Object getRelatedElement() {
246         return relatedElement;
247     }
248 
249     /**
250      * Adding a data to a meter.
251      * 
252      * @param meter
253      *            the related meter
254      * @param data
255      *            the data to be added
256      */
257     protected final void addData(final AbstractMeter meter, final double data) {
258         checkIfMeterExists(meter);
259         meterResults.get(meter).add(data);
260     }
261 
262     /**
263      * Checking method if meter is registered, otherwise inserting a suitable
264      * data structure.
265      * 
266      * @param meter
267      *            to be checked
268      */
269     private void checkIfMeterExists(final AbstractMeter meter) {
270         if (!meterResults.containsKey(meter)) {
271             meterResults.put(meter, new LinkedList<Double>());
272         }
273     }
274 
275     /**
276      * {@inheritDoc}
277      */
278     @Override
279     public String toString() {
280         final StringBuilder builder = new StringBuilder();
281         builder.append(getElementName()).append("\nmeters: ").append(getRegisteredMeters()).append(
282             "\nresults: ").append(meterResults);
283         return builder.toString();
284     }
285 
286 }