Coverage report

  %line %branch
net.sf.infrared.base.model.AggregateExecutionTime
72% 
92% 

 1  
 /* 
 2  
  * Copyright 2005 Tavant Technologies and Contributors
 3  
  * 
 4  
  * Licensed under the Apache License, Version 2.0 (the "License")
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  * 
 16  
  *
 17  
  * 
 18  
  * Original Author:  binil.thoms (Tavant Technologies)
 19  
  * Contributor(s):   prashant.nair, subin.p
 20  
  *
 21  
  */
 22  
 package net.sf.infrared.base.model;
 23  
 
 24  
 import java.io.Serializable;
 25  
 
 26  
 import net.sf.infrared.base.util.LoggingFactory;
 27  
 
 28  
 import org.apache.log4j.Logger;
 29  
 
 30  
 /**
 31  
  * Captures the aggregated timing information for a set of executions.
 32  
  * 
 33  
  * <p>
 34  
  * Each AggregateExecutionTime is created with an ExecutionContext - the
 35  
  * aggregated timing information represented will be of executions of that
 36  
  * context type. The ExecutionContext answers the question "what was executed?",
 37  
  * whereas this class answers the question "what is the timing information for
 38  
  * those executions?".
 39  
  * 
 40  
  * <p>
 41  
  * AggregateExecutionTime starts out empty when created; it gets more data as
 42  
  * other AggregateExecutionTimes and ExecutionTimers (representing one execution
 43  
  * of the context) gets merged onto it.
 44  
  * 
 45  
  * @author binil.thomas
 46  
  * @author prashant.nair
 47  
  */
 48  3
 public class AggregateExecutionTime implements Cloneable, Serializable {
 49  6
     private static final Logger log = LoggingFactory.getLogger(AggregateExecutionTime.class);
 50  
 
 51  
     private ExecutionContext ctx;
 52  
 
 53  62
     private int count = 0;
 54  
 
 55  62
     private long totalInclusiveTime = 0;
 56  
 
 57  62
     private long maxInclusiveTime = Long.MIN_VALUE;
 58  
 
 59  62
     private long minInclusiveTime = Long.MAX_VALUE;
 60  
 
 61  62
     private long totalExclusiveTime = 0;
 62  
 
 63  62
     private long maxExclusiveTime = Long.MIN_VALUE;
 64  
 
 65  62
     private long minExclusiveTime = Long.MAX_VALUE;
 66  
 
 67  62
     private long timeOfFirstExecution = Long.MAX_VALUE;
 68  
 
 69  62
     private long timeOfLastExecution = -1;
 70  
 
 71  62
     private long inclusiveFirstExecutionTime = -1;
 72  
 
 73  62
     private long inclusiveLastExecutionTime = -1;
 74  
 
 75  62
     private long exclusiveFirstExecutionTime = -1;
 76  
 
 77  62
     private long exclusiveLastExecutionTime = -1;
 78  
     
 79  
     private String layerName;
 80  
 
 81  
     /**
 82  
      * Creates a new AggregateExecutionTime object which can track timing
 83  
      * information of multiple executions of the given ExecutionContext
 84  
      */
 85  62
     public AggregateExecutionTime(ExecutionContext ctx) {
 86  62
         assert (ctx != null): "Cannot create AggregateExecutionTime with null ExecutionContext";
 87  62
         this.ctx = ctx;
 88  62
     }
 89  
 
 90  
     /**
 91  
      * Merges another AggregateExecutionTime onto this one.
 92  
      * 
 93  
      * <p>
 94  
      * The argument AggregateExecutionTime is left unchanged after this
 95  
      * operation. The target AggregateExecutionTime, after the merge operation,
 96  
      * will also represent the aggregated timing information of those of the
 97  
      * argument. For instance, the execution count will be the sum of the
 98  
      * original execution count and the execution count of the argument.
 99  
      * 
 100  
      * <p>
 101  
      * Only AggregateExecutionTimes representing the same ExecutionContext can
 102  
      * be merged - 'same' here means that the two ExecutionContext objects must
 103  
      * be equal as defined by their equals(Object) method. 
 104  
      */
 105  
     public void merge(AggregateExecutionTime aet) {
 106  
         assert (getContext().equals(aet.getContext())) : 
 107  
             "Illegal attempt to merge two AggregateExecutionTimes representing different" +
 108  21
             " contexts[ " + getContext() + ", " + aet.getContext() + " ]"; 
 109  
             // will this string concatenation happen always or only when asserts are enabled?
 110  
         
 111  21
         synchronized (this) {
 112  21
             mergeExecutionCount(aet);
 113  21
             mergeInclusiveTime(aet);
 114  21
             mergeExclusiveTime(aet);
 115  21
             mergeFirstExecution(aet);
 116  21
             mergeLastExecution(aet);
 117  21
             if (getLayerName() == null) {
 118  21
                 this.layerName = aet.getLayerName();
 119  
             }
 120  
             assert (getLayerName().equals(aet.getLayerName())) :
 121  
                 "Illegal attempt to merge two AggregateExecutionTimes executed under two" +
 122  21
                 " layers[ " + getLayerName() + ", " + aet.getLayerName() + " ]";
 123  21
         }
 124  
 
 125  21
         if (log.isDebugEnabled()) {
 126  0
             log.debug(this + " - Merged " + aet);
 127  
         }
 128  21
     }
 129  
 
 130  
     /**
 131  
      * Adds the time of an execution to this one. The execution that is to be
 132  
      * merged is represented by an ExecutionTimer argument.
 133  
      * 
 134  
      * <p>
 135  
      * The argument ExecutionTimer is left unchanged after this operation. The
 136  
      * target AggregateExecutionTime, after the merge operation, will also
 137  
      * represent the timing information from the argument ExecutionTimer. For
 138  
      * instance, the exeucion count will be incremented by one.
 139  
      * 
 140  
      * <p>
 141  
      * Only ExecutionTimers representing the same ExecutionContext can be merged -
 142  
      * 'same' here means that the two ExecutionContext objects must be euqal as
 143  
      * defined by their equals(Object) method. 
 144  
      */
 145  
     public void merge(ExecutionTimer et) {
 146  
         assert (this.ctx.equals(et.getContext())) : 
 147  
             "Illegal attempt to merge an ExecutionTime representing a different" +
 148  58
             " context[ " + et.getContext() + " ] than this one[ " + this.ctx + " ]"; 
 149  
         
 150  58
         long inc = et.getInclusiveTime();
 151  58
         long exc = et.getExclusiveTime();
 152  
 
 153  58
         synchronized (this) {
 154  58
             mergeExecutionCount(1);
 155  58
             mergeInclusiveTime(inc, inc, inc);
 156  58
             mergeExclusiveTime(exc, exc, exc);
 157  58
             mergeFirstExecution(et.getStartTime(), inc, exc);
 158  58
             mergeLastExecution(et.getStartTime(), inc, exc);
 159  58
             if (getLayerName() == null) {
 160  58
                 setLayerName( et.getLayerName() );
 161  
             }
 162  
             assert (getLayerName().equals(et.getLayerName())) :
 163  
                 "Illegal attempt to merge two AggregateExecutionTimes executed under two" +
 164  58
                 " layers[ " + getLayerName() + ", " + et.getLayerName() + " ]";
 165  
             
 166  58
         }
 167  
 
 168  58
         if (log.isDebugEnabled()) {
 169  0
             log.debug(this + " - Merged " + et);
 170  
         }
 171  58
     }
 172  
 
 173  
     public Object clone() {
 174  
         try {
 175  1
             return super.clone();
 176  0
         } catch (CloneNotSupportedException e) {
 177  0
             log.error("CloneNotSupportedException should never be thrown here", e);
 178  0
             return null;
 179  
         }
 180  
     }
 181  
 
 182  
     public String toString() {
 183  4
         return "AggregateExecutionTime for " + ctx + "[ total inclusive time = "
 184  
                 + totalInclusiveTime + ", " + "total exclusive time = "
 185  
                 + totalExclusiveTime + ", " + "execution count = " + count
 186  
                 + " ]";
 187  
     }
 188  
 
 189  
     /**
 190  
      * Gets the ExecutionContext associated with this AggregateExecutionTime.
 191  
      * 
 192  
      * <p>
 193  
      * The timing information contained in this AggregateExecutionTime pertains
 194  
      * to multiple executions of whatever is represented by the returned
 195  
      * ExecutionContext.
 196  
      */
 197  
     public ExecutionContext getContext() {
 198  74
         return ctx;
 199  
     }
 200  
 
 201  
     /**
 202  
      * Gets the total number of times the ExecutionContext was executed.
 203  
      * 
 204  
      * <p>
 205  
      * Returns 0 if this AggregateExecutionTime does not contain any timing
 206  
      * information yet.
 207  
      */
 208  
     public int getExecutionCount() {
 209  42
         return count;
 210  
     }
 211  
 
 212  
     /**
 213  
      * Gets the system time the first (least recent) time the ExecutionContext
 214  
      * was executed.
 215  
      * 
 216  
      * <p>
 217  
      * Returns -1 if this AggregateExecutionTime does not contain any timing
 218  
      * information yet.
 219  
      */
 220  
     public long getTimeOfFirstExecution() {
 221  4
         return timeOfFirstExecution;
 222  
     }
 223  
 
 224  
     /**
 225  
      * Gets the inclusive time of the first (least recent) execution of the
 226  
      * ExecutionContext.
 227  
      * 
 228  
      * <p>
 229  
      * Returns -1 if this AggregateExecutionTime does not contain any timing
 230  
      * information yet.
 231  
      */
 232  
     public long getInclusiveFirstExecutionTime() {
 233  0
         return inclusiveFirstExecutionTime;
 234  
     }
 235  
 
 236  
     /**
 237  
      * Gets the exclusive time of the first (least recent) execution of the
 238  
      * ExecutionContext.
 239  
      * 
 240  
      * <p>
 241  
      * Returns -1 if this AggregateExecutionTime does not contain any timing
 242  
      * information yet.
 243  
      */
 244  
     public long getExclusiveFirstExecutionTime() {
 245  0
         return exclusiveFirstExecutionTime;
 246  
     }
 247  
 
 248  
     /**
 249  
      * Gets the system time the last (most recent) time the ExecutionContext was
 250  
      * executed.
 251  
      * 
 252  
      * <p>
 253  
      * Returns -1 if this AggregateExecutionTime does not contain any timing
 254  
      * information yet.
 255  
      */
 256  
     public long getTimeOfLastExecution() {
 257  27
         return timeOfLastExecution;
 258  
     }
 259  
 
 260  
     /**
 261  
      * Gets the inclusive time of the last (most recent) execution of the
 262  
      * ExecutionContext.
 263  
      * 
 264  
      * <p>
 265  
      * Returns -1 if this AggregateExecutionTime does not contain any timing
 266  
      * information yet.
 267  
      */
 268  
     public long getInclusiveLastExecutionTime() {
 269  21
         return inclusiveLastExecutionTime;
 270  
     }
 271  
 
 272  
     /**
 273  
      * Gets the exclusive time of the last (most recent) execution of the
 274  
      * ExecutionContext.
 275  
      * 
 276  
      * <p>
 277  
      * Returns -1 if this AggregateExecutionTime does not contain any timing
 278  
      * information yet.
 279  
      */
 280  
     public long getExclusiveLastExecutionTime() {
 281  21
         return exclusiveLastExecutionTime;
 282  
     }
 283  
 
 284  
     /**
 285  
      * Gets the total inclusive time of all executions of the ExecutionContext.
 286  
      * 
 287  
      * <p>
 288  
      * Returns 0 if this AggregateExecutionTime does not contain any timing
 289  
      * information yet.
 290  
      */
 291  
     public long getTotalInclusiveTime() {
 292  26
         return totalInclusiveTime;
 293  
     }
 294  
 
 295  
     /**
 296  
      * Gets the total exclusive time of all executions of the ExecutionContext.
 297  
      * 
 298  
      * <p>
 299  
      * Returns 0 if this AggregateExecutionTime does not contain any timing
 300  
      * information yet.
 301  
      */
 302  
     public long getTotalExclusiveTime() {
 303  21
         return totalExclusiveTime;
 304  
     }
 305  
 
 306  
     /**
 307  
      * Gets the maximum inclusive time taken of all executions of the
 308  
      * ExecutionContext.
 309  
      * 
 310  
      * <p>
 311  
      * Returns Long.MIN_VALUE if this AggregateExecutionTime does not contain
 312  
      * any timing information yet.
 313  
      */
 314  
     public long getMaxInclusiveTime() {
 315  27
         return maxInclusiveTime;
 316  
     }
 317  
 
 318  
     /**
 319  
      * Gets the minimum inclusive time taken of all executions of the
 320  
      * ExecutionContext.
 321  
      * 
 322  
      * <p>
 323  
      * Returns Long.MAX_VALUE if this AggregateExecutionTime does not contain
 324  
      * any timing information yet.
 325  
      */
 326  
     public long getMinInclusiveTime() {
 327  27
         return minInclusiveTime;
 328  
     }
 329  
 
 330  
     /**
 331  
      * Gets the maximum exclusive time taken of all executions of the
 332  
      * ExecutionContext.
 333  
      * 
 334  
      * <p>
 335  
      * Returns Long.MIN_VALUE if this AggregateExecutionTime does not contain
 336  
      * any timing information yet.
 337  
      */
 338  
     public long getMaxExclusiveTime() {
 339  21
         return maxExclusiveTime;
 340  
     }
 341  
 
 342  
     /**
 343  
      * Gets the minimum exclusive time taken of all executions of the
 344  
      * ExecutionContext.
 345  
      * 
 346  
      * <p>
 347  
      * Returns Long.MAX_VALUE if this AggregateExecutionTime does not contain
 348  
      * any timing information yet.
 349  
      */
 350  
     public long getMinExclusiveTime() {
 351  21
         return minExclusiveTime;
 352  
     }
 353  
     
 354  
     /**
 355  
      * Gets the average inclusive time of each execution of the ExecutionContext.
 356  
      * 
 357  
      * <p>
 358  
      * Returns 0 if this AggregateExecutionTime does not contain any 
 359  
      * timing information yet.
 360  
      */
 361  
     public double getAverageInclusiveTime() {
 362  0
         if (getExecutionCount() == 0) {
 363  0
             return 0;
 364  
         }
 365  0
         return ((double) getTotalInclusiveTime()) / getExecutionCount();
 366  
     }
 367  
 
 368  
     /**
 369  
      * Gets the average exclusive time of each execution of the ExecutionContext.
 370  
      * 
 371  
      * <p>
 372  
      * Returns 0 if this AggregateExecutionTime does not contain any 
 373  
      * timing information yet.
 374  
      */
 375  
     public double getAverageExclusiveTime() {
 376  0
         if (getExecutionCount() == 0) {
 377  0
             return 0;
 378  
         }
 379  0
         return ((double) getTotalExclusiveTime()) / getExecutionCount();
 380  
     }
 381  
 
 382  
     /**
 383  
      * Gets the adjusted average inclusive time of each execution of the ExecutionContext.
 384  
      * Adjusted average inclusive time means the average inclusive time calculated after 
 385  
      * excluding the first execution.
 386  
      *
 387  
      * <p>
 388  
      * Returns 0 if this AggregateExecutionTime does not contain any 
 389  
      * timing information yet. Returns the same value as returned by
 390  
      * getAverageInclusiveTime() if this ExecutionContext has been
 391  
      * executed only once.
 392  
      */
 393  
     public double getAdjAverageInclusiveTime() {
 394  0
         if (getExecutionCount() <= 1) {
 395  0
             return getAverageInclusiveTime();
 396  
         }
 397  
         else {
 398  0
             return (double) (getTotalInclusiveTime() - getInclusiveFirstExecutionTime())
 399  
                                                             / (getExecutionCount() - 1);
 400  
         }
 401  
     }
 402  
 
 403  
     /**
 404  
      * Gets the adjusted average exclusive time of each execution of the ExecutionContext.
 405  
      * Adjusted average exclusive time means the average exclusive time calculated after 
 406  
      * excluding the first execution.
 407  
      *
 408  
      * <p>
 409  
      * Returns 0 if this AggregateExecutionTime does not contain any 
 410  
      * timing information yet. Returns the same value as returned by
 411  
      * getAverageExclusiveTime() if this ExecutionContext has been
 412  
      * executed only once.
 413  
      */
 414  
     public double getAdjAverageExclusiveTime() {
 415  0
         if (getExecutionCount() <= 1) {
 416  0
             return getAverageExclusiveTime();
 417  
         }
 418  
         else {
 419  0
             return (double) (getTotalExclusiveTime() - getExclusiveFirstExecutionTime())
 420  
                                                            / (getExecutionCount() - 1);
 421  
         }
 422  
     }
 423  
     
 424  
     /**
 425  
      * Gets the name of the ExecutionContext.
 426  
      */
 427  
     public String getName(){
 428  0
         return getContext().getName();
 429  
     }    
 430  
 
 431  
     void mergeExecutionCount(AggregateExecutionTime aet) {
 432  21
         mergeExecutionCount(aet.getExecutionCount());
 433  21
     }
 434  
 
 435  
     void mergeExecutionCount(int c) {
 436  79
         count += c;
 437  79
     }
 438  
 
 439  
     void mergeTotalTimes(AggregateExecutionTime aet) {
 440  0
         mergeTotalTimes(aet.getTotalInclusiveTime(), aet.getTotalExclusiveTime());
 441  0
     }
 442  
 
 443  
     void mergeTotalTimes(long totalInclusiveTime, class="keyword">long totalExclusiveTime) {
 444  0
         this.totalInclusiveTime += totalInclusiveTime;
 445  0
         this.totalExclusiveTime += totalExclusiveTime;
 446  0
     }
 447  
 
 448  
     void mergeFirstExecution(AggregateExecutionTime aet) {
 449  21
         mergeFirstExecution(aet.timeOfFirstExecution,
 450  
                 aet.inclusiveFirstExecutionTime,
 451  
                 aet.exclusiveFirstExecutionTime);
 452  21
     }
 453  
 
 454  
     void mergeFirstExecution(long timeOfFirstExecution, class="keyword">long inclusiveTime, class="keyword">long exclusiveTime) {
 455  79
         if (timeOfFirstExecution < this.timeOfFirstExecution) { // the other one executed earlier
 456  55
             this.timeOfFirstExecution = timeOfFirstExecution;
 457  55
             inclusiveFirstExecutionTime = inclusiveTime;
 458  55
             exclusiveFirstExecutionTime = exclusiveTime;
 459  
         }
 460  79
     }
 461  
 
 462  
     void mergeLastExecution(AggregateExecutionTime aet) {
 463  21
         mergeLastExecution(aet.getTimeOfLastExecution(), 
 464  
                 aet.getInclusiveLastExecutionTime(), aet.getExclusiveLastExecutionTime());
 465  21
     }
 466  
 
 467  
     void mergeLastExecution(long timeOfLastExecution, class="keyword">long inclusiveTime,
 468  
             long exclusiveTime) {
 469  79
         if (this.timeOfLastExecution < timeOfLastExecution) { // the other one last executed later
 470  17
             this.timeOfLastExecution = timeOfLastExecution;
 471  17
             inclusiveLastExecutionTime = inclusiveTime;
 472  17
             exclusiveLastExecutionTime = exclusiveTime;
 473  
         }
 474  79
     }
 475  
 
 476  
     void mergeInclusiveTime(AggregateExecutionTime e) {
 477  21
         mergeInclusiveTime(e.getMaxInclusiveTime(), 
 478  
                 e.getMinInclusiveTime(), e.getTotalInclusiveTime());
 479  21
     }
 480  
 
 481  
     void mergeInclusiveTime(long max, class="keyword">long min, class="keyword">long total) {
 482  79
         minInclusiveTime = Math.min(minInclusiveTime, min);
 483  79
         maxInclusiveTime = Math.max(maxInclusiveTime, max);
 484  79
         totalInclusiveTime += total;
 485  79
     }
 486  
 
 487  
     void mergeExclusiveTime(AggregateExecutionTime e) {
 488  21
         mergeExclusiveTime(e.getMaxExclusiveTime(), 
 489  
                 e.getMinExclusiveTime(), e.getTotalExclusiveTime());
 490  21
     }
 491  
 
 492  
     void mergeExclusiveTime(long max, class="keyword">long min, class="keyword">long total) {
 493  79
         minExclusiveTime = Math.min(minExclusiveTime, min);
 494  79
         maxExclusiveTime = Math.max(maxExclusiveTime, max);
 495  79
         totalExclusiveTime += total;
 496  79
     }
 497  
 
 498  
     public void setExclusiveFirstExecutionTime(long exclusiveFirstExecutionTime) {
 499  0
         this.exclusiveFirstExecutionTime = exclusiveFirstExecutionTime;
 500  0
     }
 501  
 
 502  
     public void setExclusiveLastExecutionTime(long exclusiveLastExecutionTime) {
 503  0
         this.exclusiveLastExecutionTime = exclusiveLastExecutionTime;
 504  0
     }
 505  
 
 506  
     public void setInclusiveFirstExecutionTime(long inclusiveFirstExecutionTime) {
 507  0
         this.inclusiveFirstExecutionTime = inclusiveFirstExecutionTime;
 508  0
     }
 509  
 
 510  
     public void setInclusiveLastExecutionTime(long inclusiveLastExecutionTime) {
 511  0
         this.inclusiveLastExecutionTime = inclusiveLastExecutionTime;
 512  0
     }
 513  
 
 514  
     public void setMaxExclusiveTime(long maxExclusiveTime) {
 515  0
         this.maxExclusiveTime = maxExclusiveTime;
 516  0
     }
 517  
 
 518  
     public void setMaxInclusiveTime(long maxInclusiveTime) {
 519  4
         this.maxInclusiveTime = maxInclusiveTime;
 520  4
     }
 521  
 
 522  
     public void setMinExclusiveTime(long minExclusiveTime) {
 523  0
         this.minExclusiveTime = minExclusiveTime;
 524  0
     }
 525  
 
 526  
     public void setMinInclusiveTime(long minInclusiveTime) {
 527  4
         this.minInclusiveTime = minInclusiveTime;
 528  4
     }
 529  
 
 530  
     public void setTimeOfFirstExecution(long timeOfFirstExecution) {
 531  4
         this.timeOfFirstExecution = timeOfFirstExecution;
 532  4
     }
 533  
 
 534  
     public void setTimeOfLastExecution(long timeOfLastExecution) {
 535  5
         this.timeOfLastExecution = timeOfLastExecution;
 536  5
     }
 537  
 
 538  
     public void setTotalExclusiveTime(long totalExclusiveTime) {
 539  0
         this.totalExclusiveTime = totalExclusiveTime;
 540  0
     }
 541  
 
 542  
     public void setTotalInclusiveTime(long totalInclusiveTime) {
 543  2
         this.totalInclusiveTime = totalInclusiveTime;
 544  2
     }
 545  
 
 546  
     public void setExecutionCount(int c) {
 547  2
         this.count = c;
 548  2
     }
 549  
     
 550  
     public void setContext(ExecutionContext context) {
 551  0
         this.ctx = context;
 552  0
     }    
 553  
      
 554  
     /**
 555  
      * Gets the name of the layer to which the ExecutionContext falls under
 556  
      */
 557  
     public String getLayerName() {
 558  100
         return this.layerName;
 559  
     }
 560  
     
 561  
     public void setLayerName(String layer) {
 562  58
         this.layerName = layer;                
 563  58
     }
 564  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.