Coverage Report - org.apache.commons.performance.Statistics
 
Classes in this File Line Coverage Branch Coverage Complexity
Statistics
0%
0/111
0%
0/36
0
Statistics$StatisticsKey
0%
0/14
0%
0/8
0
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  * 
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  * 
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.commons.performance;
 18  
 
 19  
 import java.util.ArrayList;
 20  
 import java.util.HashMap;
 21  
 import java.util.Iterator;
 22  
 import java.util.List;
 23  
 import java.io.Serializable;
 24  
 import org.apache.commons.math.stat.descriptive.SummaryStatistics;
 25  
 
 26  
 /**
 27  
  * <p>Container for {@link SummaryStatistics} accumulated during 
 28  
  * {@link ClientThread} executions.</p>
 29  
  * 
 30  
  * <p>Maintains a HashMap of {@link SummaryStatistics} instances with a composite
 31  
  * key of the form (process,type).  "Process" typically identifies the client
 32  
  * thread and "type" identifies the metric - e.g., "latency", "numActive."</p>
 33  
  * 
 34  
  * <p>{@link ClientThread#run()} adds one <code>SummaryStatistics</code>
 35  
  * instance, with key = (current thread id,"latency").</p>
 36  
  *
 37  
  */
 38  0
 public class Statistics implements Serializable {
 39  0
     private HashMap<StatisticsKey,SummaryStatistics> data = 
 40  
         new HashMap <StatisticsKey,SummaryStatistics>();
 41  
     
 42  
     /**
 43  
      * Adds the results of the given SummaryStatistics instance under
 44  
      * the key <process,type>
 45  
      * 
 46  
      * @param stats the SummaryStatistics whose results we are adding
 47  
      * @param process name of the associated process
 48  
      * @param type description of the associated metric
 49  
      */
 50  
     public synchronized void addStatistics(SummaryStatistics stats,
 51  
             String process, String type) {
 52  0
         StatisticsKey key = new StatisticsKey(process, type);
 53  0
         data.put(key, stats);
 54  0
     }
 55  
     
 56  
     /**
 57  
      * Retrieves the SummaryStatistics corresponding to the given
 58  
      * process and type, if this exists; null otherwise.
 59  
      * 
 60  
      * @param process name of the associated process
 61  
      * @param type description of the associated metric
 62  
      * @return SummaryStatistics for the given <process,type>; null if there is
 63  
      * no such element in the container
 64  
      */
 65  
     public synchronized SummaryStatistics getStatistics(String process,
 66  
             String type) {
 67  0
         StatisticsKey key = new StatisticsKey(process, type);
 68  0
         return data.get(key);
 69  
     }
 70  
     
 71  
     /**
 72  
      * Returns the full list of SummaryStatistics corresponding to
 73  
      * the given <code>type</code> - i.e, the list of statistics of the 
 74  
      * given type across processes.  For example, 
 75  
      * <code>getStatisticsByType("latency")</code> will return a list of latency
 76  
      * summaries, one for each process, assuming "latency" is the name of 
 77  
      * an accumulated metric.
 78  
      * 
 79  
      * @param type the type value to get statistics for
 80  
      * @return the List of SummaryStatistics stored under the given type
 81  
      */
 82  
     public synchronized List<SummaryStatistics> getStatisticsByType(String type) {
 83  0
         ArrayList<SummaryStatistics> result = new ArrayList<SummaryStatistics>();
 84  0
         Iterator<StatisticsKey> it = data.keySet().iterator();
 85  0
         while (it.hasNext()) {
 86  0
             StatisticsKey key = it.next();
 87  0
             if (key.type.equals(type)) {
 88  0
                 result.add(data.get(key));
 89  
             }
 90  0
         }
 91  0
         return result;
 92  
     }
 93  
     
 94  
     /**
 95  
      * Returns the full list of SummaryStatistics corresponding to
 96  
      * the given <code>process</code> - i.e, the list of statistics of
 97  
      * of different types maintained for the given process. 
 98  
      * 
 99  
      * @param process the process to get statistics for
 100  
      * @return the List of SummaryStatistics for the given process
 101  
      */
 102  
     public synchronized List<SummaryStatistics> getStatisticsByProcess(
 103  
             String process) {
 104  0
         ArrayList<SummaryStatistics> result = new ArrayList<SummaryStatistics>();
 105  0
         Iterator<StatisticsKey> it = data.keySet().iterator();
 106  0
         while (it.hasNext()) {
 107  0
             StatisticsKey key = it.next();
 108  0
             if (key.process.equals(process)) {
 109  0
                 result.add(data.get(key));
 110  
             }
 111  0
         }
 112  0
         return result;
 113  
     }
 114  
     
 115  
     /**
 116  
      * <p>Returns a SummaryStatistics instance describing the mean of the given
 117  
      * metric across processes - i.e., the "mean of the means", the 
 118  
      * "min of the means" etc. More precisely, the returned SummaryStatistics
 119  
      * describes the distribution of the individual process means for the given
 120  
      * metric.</p>
 121  
      * 
 122  
      * <p>The same results could be obtained by iterating over the result of 
 123  
      * {{@link #getStatisticsByType(String)} for the given <code>type</code>,
 124  
      * extracting the mean and adding its value to a SummaryStatistics
 125  
      * instance.</p>
 126  
      * 
 127  
      * @param type the metric to get summary mean statistics for
 128  
      * @return a SummaryStatistics instance describing the process means for
 129  
      * the given metric
 130  
      */
 131  
     public synchronized SummaryStatistics getMeanSummary(String type) {
 132  0
         SummaryStatistics result = new SummaryStatistics();
 133  0
         Iterator<StatisticsKey> it = data.keySet().iterator();
 134  0
         while (it.hasNext()) {
 135  0
             StatisticsKey key = it.next();
 136  0
             if (key.type.equals(type)) {
 137  0
                 result.addValue(data.get(key).getMean());
 138  
             }
 139  0
         }
 140  0
         return result;
 141  
     }
 142  
     
 143  
     /**
 144  
      * Returns SummaryStatistics for the standard deviation of the given metric
 145  
      * across processes.
 146  
      * 
 147  
      * @param type the metric to get summary standard deviation statistics for
 148  
      * @return a SummaryStatistics instance describing the process standard
 149  
      * deviations for the given metric
 150  
      * @see #getMeanSummary(String)
 151  
      */
 152  
     public synchronized SummaryStatistics getStdSummary(String type) {
 153  0
         SummaryStatistics result = new SummaryStatistics();
 154  0
         Iterator<StatisticsKey> it = data.keySet().iterator();
 155  0
         while (it.hasNext()) {
 156  0
             StatisticsKey key = it.next();
 157  0
             if (key.type.equals(type)) {
 158  0
                 result.addValue(data.get(key).getStandardDeviation());
 159  
             }
 160  0
         }
 161  0
         return result;
 162  
     }
 163  
     
 164  
     /**
 165  
      * Returns SummaryStatistics for the minimum of the given metric across
 166  
      * processes.
 167  
      * 
 168  
      * @param type the metric to get summary minimum statistics for
 169  
      * @return a SummaryStatistics instance describing the process minima
 170  
      * for the given metric
 171  
      * @see #getMeanSummary(String)
 172  
      */
 173  
     public synchronized SummaryStatistics getMinSummary(String type) {
 174  0
         SummaryStatistics result = new SummaryStatistics();
 175  0
         Iterator<StatisticsKey> it = data.keySet().iterator();
 176  0
         while (it.hasNext()) {
 177  0
             StatisticsKey key = it.next();
 178  0
             if (key.type.equals(type)) {
 179  0
                 result.addValue(data.get(key).getMin());
 180  
             }
 181  0
         }
 182  0
         return result;
 183  
     }
 184  
     
 185  
     /**
 186  
      * Returns SummaryStatistics for the maximum of the given metric across
 187  
      * processes.
 188  
      * 
 189  
      * @param type the metric to get summary maximum statistics for
 190  
      * @return a SummaryStatistics describing the process maxima
 191  
      * for the given metric
 192  
      * @see #getMeanSummary(String)
 193  
      */
 194  
     public synchronized SummaryStatistics getMaxSummary(String type) {
 195  0
         SummaryStatistics result = new SummaryStatistics();
 196  0
         Iterator<StatisticsKey> it = data.keySet().iterator();
 197  0
         while (it.hasNext()) {
 198  0
             StatisticsKey key = it.next();
 199  0
             if (key.type.equals(type)) {
 200  0
                 result.addValue(data.get(key).getMax());
 201  
             }
 202  0
         }
 203  0
         return result;
 204  
     }
 205  
     
 206  
     /**
 207  
      * Returns the List of processes corresponding to statistics.
 208  
      * 
 209  
      * @return List of processes represented in the container
 210  
      */
 211  
     public synchronized List<String> getProcesses() {
 212  0
         ArrayList<String> result = new ArrayList<String>();
 213  0
         Iterator<StatisticsKey> it = data.keySet().iterator();
 214  0
         while (it.hasNext()) {
 215  0
             String currProcess = it.next().process;
 216  0
             if (!result.contains(currProcess)) {
 217  0
                 result.add(currProcess);
 218  
             }
 219  0
         }
 220  0
         return result;
 221  
     }
 222  
     
 223  
     /**
 224  
      * Returns the List of types corresponding to statistics.
 225  
      * 
 226  
      * @return List of types represented in the container
 227  
      */
 228  
     public synchronized List<String> getTypes() {
 229  0
         ArrayList<String> result = new ArrayList<String>();
 230  0
         Iterator<StatisticsKey> it = data.keySet().iterator();
 231  0
         while (it.hasNext()) {
 232  0
             String currType = it.next().type;
 233  0
             if (!result.contains(currType)) {
 234  0
                 result.add(currType);
 235  
             }
 236  0
         }
 237  0
         return result;
 238  
     }
 239  
     
 240  
     /**
 241  
      * Computes and formats display of summary statistics by type, across
 242  
      * processes. 
 243  
      * 
 244  
      * @return String representing summaries for each metric 
 245  
      */
 246  
     public synchronized String displayOverallSummary() {
 247  0
         Iterator<String> metricsIterator = getTypes().iterator();
 248  0
         StringBuffer buffer = new StringBuffer();
 249  0
         while (metricsIterator.hasNext()) {
 250  0
             String metric = metricsIterator.next();
 251  0
             buffer.append("Overall statistics for the mean ");
 252  0
             buffer.append(metric.toUpperCase());
 253  0
             buffer.append("\n");
 254  0
             buffer.append(getMeanSummary(metric).toString());
 255  0
             buffer.append("********************************************\n");
 256  0
             buffer.append("Overall statistics for the standard deviation ");
 257  0
             buffer.append(metric.toUpperCase());
 258  0
             buffer.append("\n");
 259  0
             buffer.append(getStdSummary(metric).toString());
 260  0
             buffer.append("********************************************\n");
 261  0
             buffer.append("Overall statistics for the min ");
 262  0
             buffer.append(metric.toUpperCase());
 263  0
             buffer.append("\n");
 264  0
             buffer.append(getMinSummary(metric).toString());
 265  0
             buffer.append("********************************************\n");
 266  0
             buffer.append("Overall statistics for the max ");
 267  0
             buffer.append(metric.toUpperCase());
 268  0
             buffer.append("\n");
 269  0
             buffer.append(getMaxSummary(metric).toString());
 270  0
             buffer.append("********************************************\n");
 271  0
         } 
 272  0
         return buffer.toString();
 273  
     }
 274  
     
 275  
     /**
 276  
      * Displays statistics for the given process
 277  
      * 
 278  
      * @param process the process to retrieve metrics for
 279  
      * @return String representing all currently defined statistics for the
 280  
      * given process
 281  
      */
 282  
     public synchronized String displayProcessStatistics(String process) {
 283  0
         Iterator<String> metricsIterator = getTypes().iterator();
 284  0
         StringBuffer buffer = new StringBuffer();
 285  0
         while (metricsIterator.hasNext()) {
 286  0
             String metric = metricsIterator.next();
 287  0
             buffer.append("*********************************************\n");
 288  0
             buffer.append(metric.toUpperCase());
 289  0
             buffer.append(" for ");
 290  0
             buffer.append(process);
 291  0
             buffer.append(" ");
 292  0
             buffer.append(getStatistics(process, metric).toString());
 293  0
             buffer.append("\n********************************************\n");
 294  0
         }
 295  0
         return buffer.toString();
 296  
     }
 297  
     
 298  
     
 299  
     /**
 300  
      * Composite key (<process,type>).
 301  
      */
 302  0
     private static class StatisticsKey implements Serializable {
 303  0
         public StatisticsKey(String process, String type) {
 304  0
             this.process = process;
 305  0
             this.type = type;
 306  0
         }
 307  0
         private String process = null;
 308  0
         private String type = null;
 309  
         public boolean equals(Object obj) {
 310  0
             if (!(obj instanceof StatisticsKey) || obj == null) {
 311  0
                 return false;
 312  
             } else {
 313  0
                 StatisticsKey other = (StatisticsKey) obj;
 314  0
                 return (other.process.equals(this.process)) &&
 315  
                     (other.type.equals(this.type));  
 316  
             }
 317  
         }
 318  
         public int hashCode() {
 319  0
             return 7 + 11 * process.hashCode() + 17 * type.hashCode();
 320  
         } 
 321  
         public String getType() {
 322  0
             return type;
 323  
         }
 324  
         public String getProcess() {
 325  0
             return process;
 326  
         }
 327  
     }
 328  
 
 329  
 }