/* * Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Business Objects nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * MachineStatistics.java * Creation date: Jun 23, 2006. * By: Joseph Wong */ package org.openquark.cal.internal.machine.lecc; import java.util.List; import org.openquark.cal.machine.MachineStatistics; /** * An immutable value type for representing machine statistics. * * @author Joseph Wong */ public class LECCMachineStatistics implements MachineStatistics { /** The number of regular classes loaded by the class loaders associated with the modules in the program. */ private final int nRegularClassesLoaded; /** The number of adjunct classes loaded by the class loaders associated with the modules in the program. */ private final int nAdjunctClassesLoaded; /** The number of bytes for regular classes loaded by the class loaders associated with the modules in the program. */ private final int nRegularClassBytesLoaded; /** The number of bytes for adjunct classes loaded by the class loaders associated with the modules in the program. */ private final int nAdjunctClassBytesLoaded; /** Whether timing was performed (and therefore the timing values meaningful). */ private final boolean containsTimings; /** The number of milliseconds spent in generating regular class file data by the class loaders associated with the modules in the program. */ private final long generateRegularClassDataTimeMS; /** The number of milliseconds spent in generating adjunct class file data by the class loaders associated with the modules in the program. */ private final long generateAdjunctClassDataTimeMS; /** The number of milliseconds spent in looking up regular class file data by the class loaders associated with the modules in the program. */ private final long lookupRegularClassDataTimeMS; /** The number of milliseconds spent in looking up adjunct class file data by the class loaders associated with the modules in the program. */ private final long lookupAdjunctClassDataTimeMS; /** The number of milliseconds spent in findClass() for regular classes by the class loaders associated with the modules in the program. */ private final long regularFindClassTimeMS; /** The number of milliseconds spent in findClass() for adjunct classes by the class loaders associated with the modules in the program. */ private final long adjunctFindClassTimeMS; /** * Constructs a MachineStatistics instance. * * @param nRegularClassesLoaded * the number of regular classes loaded by the class loaders associated with the modules in the program. * @param nAdjunctClassesLoaded * the number of adjunct classes loaded by the class loaders associated with the modules in the program. * @param nRegularClassBytesLoaded * the number of bytes for regular classes loaded by the class loaders associated with the modules in the program. * @param nAdjunctClassBytesLoaded * the number of bytes for adjunct classes loaded by the class loaders associated with the modules in the program. * @param containsTimings * whether timing was performed (and therefore the timing values meaningful). * @param generateRegularClassDataTimeMS * number of milliseconds spent in generating regular class file data by the class loaders associated with the modules in the program. * @param generateAdjunctClassDataTimeMS * number of milliseconds spent in generating adjunct class file data by the class loaders associated with the modules in the program. * @param lookupRegularClassDataTimeMS * number of milliseconds spent in looking up regular class file data by the class loaders associated with the modules in the program. * @param lookupAdjunctClassDataTimeMS * number of milliseconds spent in looking up adjunct class file data by the class loaders associated with the modules in the program. * @param regularFindClassTimeMS * number of milliseconds spent in findClass() for regular classes by the class loaders associated with the modules in the program. * @param adjunctFindClassTimeMS * number of milliseconds spent in findClass() for adjunct classes by the class loaders associated with the modules in the program. */ public LECCMachineStatistics( int nRegularClassesLoaded, int nAdjunctClassesLoaded, int nRegularClassBytesLoaded, int nAdjunctClassBytesLoaded, boolean containsTimings, long generateRegularClassDataTimeMS, long generateAdjunctClassDataTimeMS, long lookupRegularClassDataTimeMS, long lookupAdjunctClassDataTimeMS, long regularFindClassTimeMS, long adjunctFindClassTimeMS) { this.nRegularClassesLoaded = nRegularClassesLoaded; this.nAdjunctClassesLoaded = nAdjunctClassesLoaded; this.nRegularClassBytesLoaded = nRegularClassBytesLoaded; this.nAdjunctClassBytesLoaded = nAdjunctClassBytesLoaded; this.containsTimings = containsTimings; this.generateRegularClassDataTimeMS = generateRegularClassDataTimeMS; this.generateAdjunctClassDataTimeMS = generateAdjunctClassDataTimeMS; this.lookupRegularClassDataTimeMS = lookupRegularClassDataTimeMS; this.lookupAdjunctClassDataTimeMS = lookupAdjunctClassDataTimeMS; this.regularFindClassTimeMS = regularFindClassTimeMS; this.adjunctFindClassTimeMS = adjunctFindClassTimeMS; } /** * Calculates the averages of the given statistics. * @param statsList the list of statistics. * @return a MachineStatistics containing the averages of the given statistics. */ public static LECCMachineStatistics getAverage(List<MachineStatistics> statsList) { int totalNRegularClassesLoaded = 0; int totalNAdjunctClassesLoaded = 0; int totalNRegularBytesLoaded = 0; int totalNAdjunctBytesLoaded = 0; long totalGenerateRegularClassDataTimeMS = 0; long totalGenerateAdjunctClassDataTimeMS = 0; long totalLookupRegularClassDataTimeMS = 0; long totalLookupAdjunctClassDataTimeMS = 0; long totalRegularFindClassTimeMS = 0; long totalAdjunctFindClassTimeMS = 0; int nStats = statsList.size(); if (nStats == 0) { return new LECCMachineStatistics(0, 0, 0, 0, false, 0, 0, 0, 0, 0, 0); } int nStatsWithTimings = 0; for (int i = 0; i < nStats; i++) { LECCMachineStatistics stats = (LECCMachineStatistics)statsList.get(i); totalNRegularClassesLoaded += stats.getNRegularClassesLoaded(); totalNAdjunctClassesLoaded += stats.getNAdjunctClassesLoaded(); totalNRegularBytesLoaded += stats.getNRegularClassBytesLoaded(); totalNAdjunctBytesLoaded += stats.getNAdjunctClassBytesLoaded(); if (stats.containsTimings) { nStatsWithTimings++; totalGenerateRegularClassDataTimeMS += stats.getGenerateRegularClassDataTimeMS(); totalGenerateAdjunctClassDataTimeMS += stats.getGenerateAdjunctClassDataTimeMS(); totalLookupRegularClassDataTimeMS += stats.getLookupRegularClassDataTimeMS(); totalLookupAdjunctClassDataTimeMS += stats.getLookupAdjunctClassDataTimeMS(); totalRegularFindClassTimeMS += stats.getRegularFindClassTimeMS(); totalAdjunctFindClassTimeMS += stats.getAdjunctFindClassTimeMS(); } } final long averageGenerateRegularClassDataTimeMS; final long averageGenerateAdjunctClassDataTimeMS; final long averageLookupRegularClassDataTimeMS; final long averageLookupAdjunctClassDataTimeMS; final long averageRegularFindClassTimeMS; final long averageAdjunctFindClassTimeMS; if (nStatsWithTimings > 0) { averageGenerateRegularClassDataTimeMS = totalGenerateRegularClassDataTimeMS / nStatsWithTimings; averageGenerateAdjunctClassDataTimeMS = totalGenerateAdjunctClassDataTimeMS / nStatsWithTimings; averageLookupRegularClassDataTimeMS = totalLookupRegularClassDataTimeMS / nStatsWithTimings; averageLookupAdjunctClassDataTimeMS = totalLookupAdjunctClassDataTimeMS / nStatsWithTimings; averageRegularFindClassTimeMS = totalRegularFindClassTimeMS / nStatsWithTimings; averageAdjunctFindClassTimeMS = totalAdjunctFindClassTimeMS / nStatsWithTimings; } else { averageGenerateRegularClassDataTimeMS = 0; averageGenerateAdjunctClassDataTimeMS = 0; averageLookupRegularClassDataTimeMS = 0; averageLookupAdjunctClassDataTimeMS = 0; averageRegularFindClassTimeMS = 0; averageAdjunctFindClassTimeMS = 0; } return new LECCMachineStatistics( totalNRegularClassesLoaded / nStats, totalNAdjunctClassesLoaded / nStats, totalNRegularBytesLoaded / nStats, totalNAdjunctBytesLoaded / nStats, nStatsWithTimings > 0, averageGenerateRegularClassDataTimeMS, averageGenerateAdjunctClassDataTimeMS, averageLookupRegularClassDataTimeMS, averageLookupAdjunctClassDataTimeMS, averageRegularFindClassTimeMS, averageAdjunctFindClassTimeMS); } /** * Calculates the incremental difference of the given statistics. For adjunct-based statistics, the value is calculated by * the formula (stats for all modules after - (stats for all modules before - stats for given module before)). * * @param programBefore the statistics for the entire program, the "before" snapshot * @param programAfter the statistics for the entire program, the "after" snapshot * @param moduleBefore the statistics for one particular module, the "before" snapshot * @return a MachineStatistics containing the incremental difference calculated from the given statistics. */ public static LECCMachineStatistics getIncrementalStatistics(LECCMachineStatistics programBefore, LECCMachineStatistics programAfter, LECCMachineStatistics moduleBefore) { int totalNRegularClassesLoaded = programAfter.nRegularClassesLoaded - programBefore.nRegularClassesLoaded; int totalNAdjunctClassesLoaded = programAfter.nAdjunctClassesLoaded - (programBefore.nAdjunctClassesLoaded - moduleBefore.nAdjunctClassesLoaded); int totalNRegularBytesLoaded = programAfter.nRegularClassBytesLoaded - programBefore.nRegularClassBytesLoaded; int totalNAdjunctBytesLoaded = programAfter.nAdjunctClassBytesLoaded - (programBefore.nAdjunctClassBytesLoaded - moduleBefore.nAdjunctClassBytesLoaded); long totalGenerateRegularClassDataTimeMS = programAfter.generateRegularClassDataTimeMS - programBefore.generateRegularClassDataTimeMS; long totalGenerateAdjunctClassDataTimeMS = programAfter.generateAdjunctClassDataTimeMS - (programBefore.generateAdjunctClassDataTimeMS - moduleBefore.generateAdjunctClassDataTimeMS); long totalLookupRegularClassDataTimeMS = programAfter.lookupRegularClassDataTimeMS - programBefore.lookupRegularClassDataTimeMS; long totalLookupAdjunctClassDataTimeMS = programAfter.lookupAdjunctClassDataTimeMS - (programBefore.lookupAdjunctClassDataTimeMS - moduleBefore.lookupAdjunctClassDataTimeMS); long totalRegularFindClassTimeMS = programAfter.regularFindClassTimeMS - programBefore.regularFindClassTimeMS; long totalAdjunctFindClassTimeMS = programAfter.adjunctFindClassTimeMS - (programBefore.adjunctFindClassTimeMS - moduleBefore.adjunctFindClassTimeMS); return new LECCMachineStatistics( totalNRegularClassesLoaded, totalNAdjunctClassesLoaded, totalNRegularBytesLoaded, totalNAdjunctBytesLoaded, programAfter.containsTimings, totalGenerateRegularClassDataTimeMS, totalGenerateAdjunctClassDataTimeMS, totalLookupRegularClassDataTimeMS, totalLookupAdjunctClassDataTimeMS, totalRegularFindClassTimeMS, totalAdjunctFindClassTimeMS); } /** * {@inheritDoc} */ @Override public String toString() { String result = "#classes loaded (regular/adjunct): " + nRegularClassesLoaded + "/" + nAdjunctClassesLoaded + "\n" + "#class bytes loaded (regular/adjunct): " + nRegularClassBytesLoaded + "/" + nAdjunctClassBytesLoaded + "\n"; if (containsTimings) { result += "class data generation time (regular/adjunct): " + generateRegularClassDataTimeMS + "/" + generateAdjunctClassDataTimeMS + " ms\n" + "class data lookup time (regular/adjunct): " + lookupRegularClassDataTimeMS + "/" + lookupAdjunctClassDataTimeMS + " ms\n" + "time spent in findClass() (regular/adjunct): " + regularFindClassTimeMS + "/" + adjunctFindClassTimeMS + " ms\n"; } return result; } /** * @return the number of classes loaded by the class loaders associated with the modules in the program. */ public int getNClassesLoaded() { return nRegularClassesLoaded + nAdjunctClassesLoaded; } /** * @return the number of regular classes loaded by the class loaders associated with the modules in the program. */ public int getNRegularClassesLoaded() { return nRegularClassesLoaded; } /** * @return the number of adjunct classes loaded by the class loaders associated with the modules in the program. */ public int getNAdjunctClassesLoaded() { return nAdjunctClassesLoaded; } /** * @return the number of bytes for classes loaded by the class loaders associated with the modules in the program. */ public int getNClassBytesLoaded() { return nRegularClassBytesLoaded + nAdjunctClassBytesLoaded; } /** * @return the number of bytes for regular classes loaded by the class loaders associated with the modules in the program. */ public int getNRegularClassBytesLoaded() { return nRegularClassBytesLoaded; } /** * @return the number of bytes for adjunct classes loaded by the class loaders associated with the modules in the program. */ public int getNAdjunctClassBytesLoaded() { return nAdjunctClassBytesLoaded; } /** * @return whether timing was performed (and therefore the timing values meaningful). */ public boolean containsTimings() { return containsTimings; } /** * @return number of milliseconds spent in generating class file data by the class loaders associated with the modules in the program. */ public long getGenerateClassDataTimeMS() { return generateRegularClassDataTimeMS + generateAdjunctClassDataTimeMS; } /** * @return number of milliseconds spent in generating regular class file data by the class loaders associated with the modules in the program. */ public long getGenerateRegularClassDataTimeMS() { return generateRegularClassDataTimeMS; } /** * @return number of milliseconds spent in generating adjunct class file data by the class loaders associated with the modules in the program. */ public long getGenerateAdjunctClassDataTimeMS() { return generateAdjunctClassDataTimeMS; } /** * @return number of milliseconds spent in looking up class file data by the class loaders associated with the modules in the program. */ public long getLookupClassDataTimeMS() { return lookupRegularClassDataTimeMS + lookupAdjunctClassDataTimeMS; } /** * @return number of milliseconds spent in looking up regular class file data by the class loaders associated with the modules in the program. */ public long getLookupRegularClassDataTimeMS() { return lookupRegularClassDataTimeMS; } /** * @return number of milliseconds spent in looking up adjunct class file data by the class loaders associated with the modules in the program. */ public long getLookupAdjunctClassDataTimeMS() { return lookupAdjunctClassDataTimeMS; } /** * @return number of milliseconds spent in findClass() by the class loaders associated with the modules in the program. */ public long getFindClassTimeMS() { return regularFindClassTimeMS + adjunctFindClassTimeMS; } /** * @return number of milliseconds spent in findClass() for regular classes by the class loaders associated with the modules in the program. */ public long getRegularFindClassTimeMS() { return regularFindClassTimeMS; } /** * @return number of milliseconds spent in findClass() for adjunct classes by the class loaders associated with the modules in the program. */ public long getAdjunctFindClassTimeMS() { return adjunctFindClassTimeMS; } }