Author: psteitz Date: Fri Apr 16 18:57:07 2021 New Revision: 1888832 URL: http://svn.apache.org/viewvc?rev=1888832&view=rev Log: Replace commons-math with hipparchus, add percentiles to metrics.
Modified: commons/sandbox/performance/trunk/src/dbcp/build.properties.sample commons/sandbox/performance/trunk/src/dbcp/build.xml commons/sandbox/performance/trunk/src/http/build.xml commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/ClientThread.java commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/Statistics.java commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/dbcp/DBCPClientThread.java commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/dbcp/DBCPSoak.java commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/pool/PoolClientThread.java commons/sandbox/performance/trunk/src/pool/build.xml commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/ClientThreadTest.java commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/LoadGeneratorTest.java commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/TesterClientThread.java Modified: commons/sandbox/performance/trunk/src/dbcp/build.properties.sample URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/dbcp/build.properties.sample?rev=1888832&r1=1888831&r2=1888832&view=diff ============================================================================== --- commons/sandbox/performance/trunk/src/dbcp/build.properties.sample (original) +++ commons/sandbox/performance/trunk/src/dbcp/build.properties.sample Fri Apr 16 18:57:07 2021 @@ -16,8 +16,6 @@ # limitations under the License. ############################################################################### -# Copied unchanged from DBCP 2.0 release tag (DBCP_2_0) - # Remote maven repository (used to download dependencies not provided below) mavenRepo=https://repo1.maven.org/maven2 Modified: commons/sandbox/performance/trunk/src/dbcp/build.xml URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/dbcp/build.xml?rev=1888832&r1=1888831&r2=1888832&view=diff ============================================================================== --- commons/sandbox/performance/trunk/src/dbcp/build.xml (original) +++ commons/sandbox/performance/trunk/src/dbcp/build.xml Fri Apr 16 18:57:07 2021 @@ -72,8 +72,12 @@ <target name="get-math"> <get - src="${mavenRepo}/org/apache/commons/commons-math3/3.2/commons-math3-3.2.jar" - dest="${lib}/commons-math3-3.2.jar" + src="${mavenRepo}/org/hipparchus/hipparchus-core/1.8/hipparchus-core-1.8.jar" + dest="${lib}/hipparchus-core-1.8.jar" + usetimestamp="true"/> + <get + src="${mavenRepo}/org/hipparchus/hipparchus-stat/1.8/hipparchus-stat-1.8.jar" + dest="${lib}/hipparchus-stat-1.8.jar" usetimestamp="true"/> </target> Modified: commons/sandbox/performance/trunk/src/http/build.xml URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/http/build.xml?rev=1888832&r1=1888831&r2=1888832&view=diff ============================================================================== --- commons/sandbox/performance/trunk/src/http/build.xml (original) +++ commons/sandbox/performance/trunk/src/http/build.xml Fri Apr 16 18:57:07 2021 @@ -71,9 +71,13 @@ <target name="get-math"> <get - src="${mavenRepo}/org/apache/commons/commons-math3/3.6.1/commons-math3-3.6.1.jar" - dest="${lib}/commons-math-3.6.1.jar" - usetimestamp="true"/> + src="${mavenRepo}/org/hipparchus/hipparchus-core/1.8/hipparchus-core-1.8.jar" + dest="${lib}/hipparchus-core-1.8.jar" + usetimestamp="true"/> + <get + src="${mavenRepo}/org/hipparchus/hipparchus-stat/1.8/hipparchus-stat-1.8.jar" + dest="${lib}/hipparchus-stat-1.8.jar" + usetimestamp="true"/> </target> <target name="get-logging"> Modified: commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/ClientThread.java URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/ClientThread.java?rev=1888832&r1=1888831&r2=1888832&view=diff ============================================================================== --- commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/ClientThread.java (original) +++ commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/ClientThread.java Fri Apr 16 18:57:07 2021 @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,54 +19,63 @@ package org.apache.commons.performance; import java.util.logging.Logger; -import org.apache.commons.math3.random.RandomDataGenerator; -import org.apache.commons.math3.stat.descriptive.SummaryStatistics; +import org.hipparchus.random.RandomDataGenerator; +import org.hipparchus.stat.descriptive.StreamingStatistics; /** * <p> * Base for performance / load test clients. The run method executes init, then - * setup-execute-cleanup in a loop, gathering performance statistics, with time between executions - * based on configuration parameters. The <code>finish</code> method is executed once at the end of - * a run. See {@link #nextDelay()} for details on inter-arrival time computation. + * setup-execute-cleanup in a loop, gathering performance statistics, with time + * between executions based on configuration parameters. The <code>finish</code> + * method is executed once at the end of a run. See {@link #nextDelay()} for + * details on inter-arrival time computation. * </p> - * * <p> - * Subclasses <strong>must</strong> implement <code>execute</code>, which is the basic client - * request action that is executed, and timed, repeatedly. If per-request setup is required, and you - * do not want the time associated with this setup to be included in the reported timings, implement - * <code>setUp</code> and put the setup code there. Similarly for <code>cleanUp</code>. - * Initialization code that needs to be executed once only, before any requests are initiated, - * should be put into <code>init</code> and cleanup code that needs to be executed only once at the - * end of a simulation should be put into <code>finish.</code> + * Subclasses <strong>must</strong> implement <code>execute</code>, which is the + * basic client request action that is executed, and timed, repeatedly. If + * per-request setup is required, and you do not want the time associated with + * this setup to be included in the reported timings, implement + * <code>setUp</code> and put the setup code there. Similarly for + * <code>cleanUp</code>. Initialization code that needs to be executed once + * only, before any requests are initiated, should be put into <code>init</code> + * and cleanup code that needs to be executed only once at the end of a + * simulation should be put into <code>finish.</code> * </p> - * * <p> - * By default, the only statistics accumulated are for the latency of the <code>execute</code> - * method. Additional metrics can be captured and added to the {@link Statistics} for the running - * thread. + * By default, the only statistics accumulated are for the latency of the + * <code>execute</code> method. Additional metrics can be captured and added to + * the {@link Statistics} for the running thread. * </p> - * */ public abstract class ClientThread - implements Runnable { + implements + Runnable { // Inter-arrival time configuration parameters /** Minimum mean time between requests */ private long minDelay; + /** Maximum mean time between requests */ private long maxDelay; + /** Standard deviation of delay distribution */ private double sigma; + /** Delay type - determines how next start times are computed */ private String delayType; + /** Ramp length for cyclic mean delay */ private long rampPeriod; + /** Peak length for cyclic mean delay */ private long peakPeriod; + /** Trough length for cyclic mean delay */ private long troughPeriod; + /** Cycle type */ private final String cycleType; + /** Ramp type */ private String rampType; @@ -76,26 +85,37 @@ public abstract class ClientThread // State data /** Start time of run */ private long startTime; + /** Start time of current period */ private long periodStart; + /** Last mean delay */ private double lastMean; + /** Cycle state constants */ protected static final int RAMPING_UP = 0; + protected static final int RAMPING_DOWN = 1; + protected static final int PEAK_LOAD = 2; + protected static final int TROUGH_LOAD = 3; + /** Cycle state */ private int cycleState = RAMPING_UP; + /** Number of errors */ private long numErrors = 0; + /** Number of misses */ private long numMisses = 0; /** Random data generator */ protected RandomDataGenerator randomData = new RandomDataGenerator(); + /** Statistics container */ protected Statistics stats; + /** Logger shared by client threads */ protected Logger logger; @@ -115,9 +135,10 @@ public abstract class ClientThread * @param logger common logger shared by all clients * @param stats Statistics instance to add results to */ - public ClientThread(long iterations, long minDelay, long maxDelay, double sigma, String delayType, long rampPeriod, - long peakPeriod, long troughPeriod, String cycleType, String rampType, Logger logger, - Statistics stats) { + public ClientThread(long iterations, long minDelay, long maxDelay, + double sigma, String delayType, long rampPeriod, + long peakPeriod, long troughPeriod, String cycleType, + String rampType, Logger logger, Statistics stats) { this.iterations = iterations; this.minDelay = minDelay; this.maxDelay = maxDelay; @@ -146,9 +167,9 @@ public abstract class ClientThread long lastStart = startTime; periodStart = System.currentTimeMillis(); lastMean = maxDelay; // Ramp up, if any, starts here - SummaryStatistics responseStats = new SummaryStatistics(); - SummaryStatistics onTimeStats = new SummaryStatistics(); - SummaryStatistics successStats = new SummaryStatistics(); + StreamingStatistics responseStats = new StreamingStatistics(true); + StreamingStatistics onTimeStats = new StreamingStatistics(true); + StreamingStatistics successStats = new StreamingStatistics(true); for (int i = 0; i < iterations; i++) { boolean onTime = true; boolean success = true; @@ -177,8 +198,10 @@ public abstract class ClientThread success = false; } finally { try { - // TODO: Keep times in ns here, convert stats for ms reporting - responseStats.addValue((System.nanoTime() - start) / 1000f / 1000f); + // TODO: Keep times in ns here, convert stats for ms + // reporting + responseStats + .addValue((System.nanoTime() - start) / 1000f / 1000f); successStats.addValue(success ? 1 : 0); onTimeStats.addValue(onTime ? 1 : 0); cleanUp(); @@ -202,7 +225,8 @@ public abstract class ClientThread // Record statistics stats.addStatistics(responseStats, process, "latency"); stats.addStatistics(onTimeStats, process, "on time startup rate"); - stats.addStatistics(successStats, process, "successful completion rate"); + stats.addStatistics(successStats, process, + "successful completion rate"); // Log accumulated statistics for this thread logger.info(stats.displayProcessStatistics(process)); @@ -236,43 +260,44 @@ public abstract class ClientThread /** * <p> - * Computes the next inter-arrival time (time to wait between requests) based on configured - * values for min/max delay, delay type, cycle type, ramp type and period. Currently supports - * constant (always returning <code>minDelay</code> delay time), Poisson and Gaussian - * distributed random time delays, linear and random ramps, and oscillating / non-oscillating - * cycle types. + * Computes the next inter-arrival time (time to wait between requests) + * based on configured values for min/max delay, delay type, cycle type, + * ramp type and period. Currently supports constant (always returning + * <code>minDelay</code> delay time), Poisson and Gaussian distributed + * random time delays, linear and random ramps, and oscillating / + * non-oscillating cycle types. * </p> - * * <p> - * <strong>loadType</strong> determines whether returned times are deterministic or random. If - * <code>loadType</code> is not "constant", a random value with the specified distribution and - * mean determined by the other parameters is returned. For "gaussian" <code>loadType</code>, + * <strong>loadType</strong> determines whether returned times are + * deterministic or random. If <code>loadType</code> is not "constant", a + * random value with the specified distribution and mean determined by the + * other parameters is returned. For "gaussian" <code>loadType</code>, * <code>sigma</code> is used as used as the standard deviation. * </p> - * * <p> - * <strong>cycleType</strong> determines how the returned times vary over time. "oscillating", - * means times ramp up and down between <code>minDelay</code> and <code>maxDelay.</code> Ramp - * type is controlled by <code>rampType.</code> Linear <code>rampType</code> means the means - * increase or decrease linearly over the time of the period. Random makes random jumps up or - * down toward the next peak or trough. "None" for <code>rampType</code> under oscillating - * <code>cycleType</code> makes the means alternate between peak (<code>minDelay</code>) and - * trough (<code>maxDelay</code>) with no ramp between. + * <strong>cycleType</strong> determines how the returned times vary over + * time. "oscillating", means times ramp up and down between + * <code>minDelay</code> and <code>maxDelay.</code> Ramp type is controlled + * by <code>rampType.</code> Linear <code>rampType</code> means the means + * increase or decrease linearly over the time of the period. Random makes + * random jumps up or down toward the next peak or trough. "None" for + * <code>rampType</code> under oscillating <code>cycleType</code> makes the + * means alternate between peak (<code>minDelay</code>) and trough + * (<code>maxDelay</code>) with no ramp between. * </p> - * * <p> - * Oscillating loads cycle through RAMPING_UP, PEAK_LOAD, RAMPING_DOWN and TROUGH_LOAD states, - * with the amount of time spent in each state determined by <code>rampPeriod</code> (time spent - * increasing on the way up and decreasing on the way down), <code>peakPeriod</code> (time spent - * at peak load, i.e., <code>minDelay</code> mean delay) and <code>troughPeriod</code> (time - * spent at minimum load, i.e., <code>maxDelay</code> mean delay). All times are specified in + * Oscillating loads cycle through RAMPING_UP, PEAK_LOAD, RAMPING_DOWN and + * TROUGH_LOAD states, with the amount of time spent in each state + * determined by <code>rampPeriod</code> (time spent increasing on the way + * up and decreasing on the way down), <code>peakPeriod</code> (time spent + * at peak load, i.e., <code>minDelay</code> mean delay) and + * <code>troughPeriod</code> (time spent at minimum load, i.e., + * <code>maxDelay</code> mean delay). All times are specified in * milliseconds. * </p> - * * <p> * <strong>Examples:</strong> * <ol> - * * <li>Given * * <pre> @@ -286,12 +311,12 @@ public abstract class ClientThread * troughPeriod = 30000 * </pre> * - * load will start at one request every 500 ms, which is "trough load." Load then ramps up - * linearly over the next 10 seconds unil it reaches one request per 250 milliseconds, which is - * "peak load." Peak load is sustained for 20 seconds and then load ramps back down, again - * taking 10 seconds to get down to "trough load," which is sustained for 30 seconds. The cycle - * then repeats.</li> - * + * load will start at one request every 500 ms, which is "trough load." Load + * then ramps up linearly over the next 10 seconds unil it reaches one + * request per 250 milliseconds, which is "peak load." Peak load is + * sustained for 20 seconds and then load ramps back down, again taking 10 + * seconds to get down to "trough load," which is sustained for 30 seconds. + * The cycle then repeats.</li> * <li> * * <pre> @@ -306,11 +331,11 @@ public abstract class ClientThread * sigma = 100 * </pre> * - * produces a load pattern similar to example 1, but in this case the computed delay value is - * fed into a gaussian random number generator as the mean and 100 as the standard deviation - - * i.e., <code>nextDelay</code> returns random, gaussian distributed values with means moving - * according to the cyclic pattern in example 1.</li> - * + * produces a load pattern similar to example 1, but in this case the + * computed delay value is fed into a gaussian random number generator as + * the mean and 100 as the standard deviation - i.e., <code>nextDelay</code> + * returns random, gaussian distributed values with means moving according + * to the cyclic pattern in example 1.</li> * <li> * * <pre> @@ -322,10 +347,9 @@ public abstract class ClientThread * rampPeriod = 10000 * </pre> * - * produces a load pattern that increases linearly from one request every 500ms to one request - * every 250ms and then stays constant at that level until the run is over. Other parameters are - * ignored in this case.</li> - * + * produces a load pattern that increases linearly from one request every + * 500ms to one request every 250ms and then stays constant at that level + * until the run is over. Other parameters are ignored in this case.</li> * <li> * * <pre> @@ -336,8 +360,9 @@ public abstract class ClientThread * rampType = "none" * </pre> * - * produces inter-arrival times that are poisson distributed with mean 250ms. Note that when - * rampType is "none," the value of <code>minDelay</code> is used as the (constant) mean delay.</li> + * produces inter-arrival times that are poisson distributed with mean + * 250ms. Note that when rampType is "none," the value of + * <code>minDelay</code> is used as the (constant) mean delay.</li> * </ol> * * @return next value for delay @@ -350,15 +375,18 @@ public abstract class ClientThread final double delayDifference = dMaxDelay - dMinDelay; final long currentTime = System.currentTimeMillis(); if (cycleType.equals("none")) { - if (rampType.equals("none") || (currentTime - startTime) > rampPeriod) { // ramped up + if (rampType.equals("none") || + (currentTime - startTime) > rampPeriod) { // ramped up targetDelay = dMinDelay; } else if (rampType.equals("linear")) { // single period linear - double prop = (double) (currentTime - startTime) / (double) rampPeriod; + double prop = (double) (currentTime - startTime) / + (double) rampPeriod; targetDelay = dMaxDelay - delayDifference * prop; } else { // Random jumps down to delay - single period // TODO: govern size of jumps as in oscillating // Where we last were as proportion of way down to minDelay - final double lastProp = (dMaxDelay - lastMean) / delayDifference; + final double lastProp = (dMaxDelay - lastMean) / + delayDifference; // Make a random jump toward 1 (1 = all the way down) final double prop = randomData.nextUniform(lastProp, 1); targetDelay = dMaxDelay - delayDifference * prop; @@ -368,7 +396,8 @@ public abstract class ClientThread adjustState(currentTime); targetDelay = computeCyclicDelay(currentTime, dMinDelay, dMaxDelay); } else { - throw new ConfigurationException("Cycle type not supported: " + cycleType); + throw new ConfigurationException("Cycle type not supported: " + + cycleType); } // Remember last mean for ramp up / down @@ -380,20 +409,22 @@ public abstract class ClientThread // Generate and return random deviate if (delayType.equals("gaussian")) { - return Math.round(randomData.nextGaussian(targetDelay, sigma)); + return Math.round(randomData.nextGaussian() * sigma + targetDelay); } else { // must be Poisson return randomData.nextPoisson(targetDelay); } } /** - * Adjusts cycleState, periodStart and lastMean if a cycle state transition needs to happen. + * Adjusts cycleState, periodStart and lastMean if a cycle state transition + * needs to happen. * * @param currentTime current time */ protected void adjustState(long currentTime) { long timeInPeriod = currentTime - periodStart; - if (((cycleState == RAMPING_UP || cycleState == RAMPING_DOWN) && timeInPeriod < rampPeriod) || + if (((cycleState == RAMPING_UP || cycleState == RAMPING_DOWN) && + timeInPeriod < rampPeriod) || (cycleState == PEAK_LOAD && timeInPeriod < peakPeriod) || (cycleState == TROUGH_LOAD && timeInPeriod < troughPeriod)) { return; // No state change @@ -442,11 +473,13 @@ public abstract class ClientThread break; default: - throw new IllegalStateException("Illegal cycle state: " + cycleState); + throw new IllegalStateException("Illegal cycle state: " + + cycleState); } } - protected double computeCyclicDelay(long currentTime, double min, double max) { + protected double computeCyclicDelay(long currentTime, double min, + double max) { // Constant load states if (cycleState == PEAK_LOAD) { @@ -468,7 +501,8 @@ public abstract class ClientThread // Linear ramp type and ramping up or down double diff = max - min; if (rampType.equals("linear")) { - double prop = (double) (currentTime - periodStart) / (double) rampPeriod; + double prop = (double) (currentTime - periodStart) / + (double) rampPeriod; if (cycleState == RAMPING_UP) { return max - diff * prop; } else { @@ -478,12 +512,14 @@ public abstract class ClientThread // Where we last were as proportion of way down to minDelay double lastProp = (max - lastMean) / diff; // Where we would be if this were a linear ramp - double linearProp = (double) (currentTime - periodStart) / (double) rampPeriod; + double linearProp = (double) (currentTime - periodStart) / + (double) rampPeriod; // Need to govern size of jumps, otherwise "convergence" // can be too fast - use linear ramp as governor if ((cycleState == RAMPING_UP && (lastProp > linearProp)) || (cycleState == RAMPING_DOWN && ((1 - lastProp) > linearProp))) - lastProp = (cycleState == RAMPING_UP) ? linearProp : (1 - linearProp); + lastProp = (cycleState == RAMPING_UP) ? linearProp + : (1 - linearProp); double prop = 0; if (cycleState == RAMPING_UP) { // Random jump toward 1 prop = randomData.nextUniform(lastProp, 1); Modified: commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/Statistics.java URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/Statistics.java?rev=1888832&r1=1888831&r2=1888832&view=diff ============================================================================== --- commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/Statistics.java (original) +++ commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/Statistics.java Fri Apr 16 18:57:07 2021 @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -22,74 +22,80 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; -import org.apache.commons.math3.stat.descriptive.AggregateSummaryStatistics; -import org.apache.commons.math3.stat.descriptive.StatisticalSummaryValues; -import org.apache.commons.math3.stat.descriptive.SummaryStatistics; +import org.hipparchus.stat.descriptive.StatisticalSummary; +import org.hipparchus.stat.descriptive.StreamingStatistics; /** * <p> - * Container for {@link SummaryStatistics} accumulated during {@link ClientThread} executions. + * Container for {@link StreamingStatistics} accumulated during + * {@link ClientThread} executions. * </p> - * * <p> - * Maintains a HashMap of {@link SummaryStatistics} instances with a composite key of the form - * (process,type). "Process" typically identifies the client thread and "type" identifies the metric - * - e.g., "latency", "numActive." + * Maintains a HashMap of {@link StreamingStatistics} instances with a composite + * key of the form (process,type). "Process" typically identifies the client + * thread and "type" identifies the metric - e.g., "latency", "numActive." * </p> - * * <p> - * {@link ClientThread#run()} adds one <code>SummaryStatistics</code> instance, with key = (current - * thread id,"latency"). + * {@link ClientThread#run()} adds one {@code StreamingStatistics} instance, + * with key = (current thread id,"latency"). * </p> - * */ public class Statistics - implements Serializable { + implements + Serializable { + + private static final long serialVersionUID = 1L; /** - * Map of SummaryStatistics keyed on <process,type>, where process corresponds to a thread being - * monitored and type is a user-supplied characteristic being measured and tracked. For example, - * <thread name, "latency">. + * Map of SummaryStatistics keyed on <process,type>, where process + * corresponds to a thread being monitored and type is a user-supplied + * characteristic being measured and tracked. For example, <thread name, + * "latency">. */ - private HashMap<StatisticsKey, SummaryStatistics> data = new HashMap<StatisticsKey, SummaryStatistics>(); + private HashMap<StatisticsKey, StreamingStatistics> data = new HashMap<StatisticsKey, StreamingStatistics>(); /** - * Adds the results of the given SummaryStatistics instance under the key <process,type> + * Adds the results of the given SummaryStatistics instance under the key + * <process,type> * * @param stats the SummaryStatistics whose results we are adding * @param process name of the associated process * @param type description of the associated metric */ - public synchronized void addStatistics(SummaryStatistics stats, String process, String type) { + public synchronized void addStatistics(StreamingStatistics stats, + String process, String type) { StatisticsKey key = new StatisticsKey(process, type); data.put(key, stats); } /** - * Retrieves the SummaryStatistics corresponding to the given process and type, if this exists; - * null otherwise. + * Retrieves the SummaryStatistics corresponding to the given process and + * type, if this exists; null otherwise. * * @param process name of the associated process * @param type description of the associated metric - * @return SummaryStatistics for the given <process,type>; null if there is no such element in - * the container + * @return SummaryStatistics for the given <process,type>; null if there is + * no such element in the container */ - public synchronized SummaryStatistics getStatistics(String process, String type) { + public synchronized StreamingStatistics getStatistics(String process, + String type) { StatisticsKey key = new StatisticsKey(process, type); return data.get(key); } /** - * Returns the full list of SummaryStatistics corresponding to the given <code>type</code> - - * i.e, the list of statistics of the given type across processes. For example, - * <code>getStatisticsByType("latency")</code> will return a list of latency summaries, one for - * each process, assuming "latency" is the name of an accumulated metric. + * Returns the full list of SummaryStatistics corresponding to the given + * <code>type</code> - i.e, the list of statistics of the given type across + * processes. For example, <code>getStatisticsByType("latency")</code> will + * return a list of latency summaries, one for each process, assuming + * "latency" is the name of an accumulated metric. * * @param type the type value to get statistics for * @return the List of SummaryStatistics stored under the given type */ - public synchronized List<SummaryStatistics> getStatisticsByType(String type) { - ArrayList<SummaryStatistics> result = new ArrayList<SummaryStatistics>(); + public synchronized List<StreamingStatistics> + getStatisticsByType(String type) { + ArrayList<StreamingStatistics> result = new ArrayList<StreamingStatistics>(); Iterator<StatisticsKey> it = data.keySet().iterator(); while (it.hasNext()) { StatisticsKey key = it.next(); @@ -101,14 +107,16 @@ public class Statistics } /** - * Returns the full list of SummaryStatistics corresponding to the given <code>process</code> - - * i.e, the list of statistics of of different types maintained for the given process. + * Returns the full list of SummaryStatistics corresponding to the given + * <code>process</code> - i.e, the list of statistics of of different types + * maintained for the given process. * * @param process the process to get statistics for * @return the List of SummaryStatistics for the given process */ - public synchronized List<SummaryStatistics> getStatisticsByProcess(String process) { - ArrayList<SummaryStatistics> result = new ArrayList<SummaryStatistics>(); + public synchronized List<StreamingStatistics> + getStatisticsByProcess(String process) { + ArrayList<StreamingStatistics> result = new ArrayList<StreamingStatistics>(); Iterator<StatisticsKey> it = data.keySet().iterator(); while (it.hasNext()) { StatisticsKey key = it.next(); @@ -121,23 +129,23 @@ public class Statistics /** * <p> - * Returns a SummaryStatistics instance describing the mean of the given metric across processes - * - i.e., the "mean of the means", the "min of the means" etc. More precisely, the returned - * SummaryStatistics describes the distribution of the individual process means for the given - * metric. + * Returns a SummaryStatistics instance describing the mean of the given + * metric across processes - i.e., the "mean of the means", the "min of the + * means" etc. More precisely, the returned SummaryStatistics describes the + * distribution of the individual process means for the given metric. * </p> - * * <p> * The same results could be obtained by iterating over the result of { - * {@link #getStatisticsByType(String)} for the given <code>type</code>, extracting the mean and - * adding its value to a SummaryStatistics instance. + * {@link #getStatisticsByType(String)} for the given <code>type</code>, + * extracting the mean and adding its value to a SummaryStatistics instance. * </p> * * @param type the metric to get summary mean statistics for - * @return a SummaryStatistics instance describing the process means for the given metric + * @return a SummaryStatistics instance describing the process means for the + * given metric */ - public synchronized SummaryStatistics getMeanSummary(String type) { - SummaryStatistics result = new SummaryStatistics(); + public synchronized StreamingStatistics getMeanSummary(String type) { + StreamingStatistics result = new StreamingStatistics(); Iterator<StatisticsKey> it = data.keySet().iterator(); while (it.hasNext()) { StatisticsKey key = it.next(); @@ -149,15 +157,16 @@ public class Statistics } /** - * Returns SummaryStatistics for the standard deviation of the given metric across processes. + * Returns SummaryStatistics for the standard deviation of the given metric + * across processes. * * @param type the metric to get summary standard deviation statistics for - * @return a SummaryStatistics instance describing the process standard deviations for the given - * metric + * @return a SummaryStatistics instance describing the process standard + * deviations for the given metric * @see #getMeanSummary(String) */ - public synchronized SummaryStatistics getStdSummary(String type) { - SummaryStatistics result = new SummaryStatistics(); + public synchronized StreamingStatistics getStdSummary(String type) { + StreamingStatistics result = new StreamingStatistics(); Iterator<StatisticsKey> it = data.keySet().iterator(); while (it.hasNext()) { StatisticsKey key = it.next(); @@ -169,14 +178,16 @@ public class Statistics } /** - * Returns SummaryStatistics for the minimum of the given metric across processes. + * Returns SummaryStatistics for the minimum of the given metric across + * processes. * * @param type the metric to get summary minimum statistics for - * @return a SummaryStatistics instance describing the process minima for the given metric + * @return a SummaryStatistics instance describing the process minima for + * the given metric * @see #getMeanSummary(String) */ - public synchronized SummaryStatistics getMinSummary(String type) { - SummaryStatistics result = new SummaryStatistics(); + public synchronized StreamingStatistics getMinSummary(String type) { + StreamingStatistics result = new StreamingStatistics(); Iterator<StatisticsKey> it = data.keySet().iterator(); while (it.hasNext()) { StatisticsKey key = it.next(); @@ -188,14 +199,16 @@ public class Statistics } /** - * Returns SummaryStatistics for the maximum of the given metric across processes. + * Returns SummaryStatistics for the maximum of the given metric across + * processes. * * @param type the metric to get summary maximum statistics for - * @return a SummaryStatistics describing the process maxima for the given metric + * @return a SummaryStatistics describing the process maxima for the given + * metric * @see #getMeanSummary(String) */ - public synchronized SummaryStatistics getMaxSummary(String type) { - SummaryStatistics result = new SummaryStatistics(); + public synchronized StreamingStatistics getMaxSummary(String type) { + StreamingStatistics result = new StreamingStatistics(); Iterator<StatisticsKey> it = data.keySet().iterator(); while (it.hasNext()) { StatisticsKey key = it.next(); @@ -207,22 +220,25 @@ public class Statistics } /** - * Returns overall SummaryStatistics, aggregating the results for metrics of the given type - * across processes. + * Returns overall SummaryStatistics, aggregating the results for metrics of + * the given type across processes. * * @param type the metric to get overall statistics for - * @return a SummaryStatistics instance summarizing the combined dataset for the given metric + * @return a SummaryStatistics instance summarizing the combined dataset for + * the given metric */ - public synchronized StatisticalSummaryValues getOverallSummary(String type) { - ArrayList<SummaryStatistics> contributingStats = new ArrayList<SummaryStatistics>(); + public synchronized StatisticalSummary getOverallSummary(String type) { + final StreamingStatistics combinedStats = new StreamingStatistics(); + // ArrayList<StreamingStatistics> contributingStats = new + // ArrayList<StreamingStatistics>(); Iterator<StatisticsKey> it = data.keySet().iterator(); while (it.hasNext()) { StatisticsKey key = it.next(); if (key.type.equals(type)) { - contributingStats.add(data.get(key)); + combinedStats.aggregate(data.get(key)); } } - return AggregateSummaryStatistics.aggregate(contributingStats); + return combinedStats.getSummary(); } /** @@ -260,9 +276,9 @@ public class Statistics } /** - * Computes and formats display of summary statistics by type, as means of means, etc. with the - * process as the unit of observation. Not currently displayed. TODO: Make inclusion of this - * report configurable. + * Computes and formats display of summary statistics by type, as means of + * means, etc. with the process as the unit of observation. Not currently + * displayed. TODO: Make inclusion of this report configurable. * * @return String representing summaries for each metric */ @@ -295,7 +311,8 @@ public class Statistics } /** - * Displays overall statistics for each metric, aggregating data across threads. + * Displays overall statistics for each metric, aggregating data across + * threads. * * @return overall statistics report */ @@ -316,22 +333,46 @@ public class Statistics } /** - * Displays statistics for the given process + * Displays statistics for the given process. + * <p> + * Processes are thread names of owning threads. * * @param process the process to retrieve metrics for - * @return String representing all currently defined statistics for the given process + * @return String representing all currently defined statistics for the + * given process */ public synchronized String displayProcessStatistics(String process) { - Iterator<String> metricsIterator = getTypes().iterator(); - StringBuffer buffer = new StringBuffer(); + /* + * Statistics are keyed by process and type names. Process names are + * owning thread names. Types are defined in ClientThread + * implementations. See for example "numIdle" and "numActive" in + * DBCPClientThread. + */ + final Iterator<String> metricsIterator = getTypes().iterator(); + final StringBuffer buffer = new StringBuffer(); + final String endl = "\n"; while (metricsIterator.hasNext()) { - String metric = metricsIterator.next(); - buffer.append("*********************************************\n"); + final String metric = metricsIterator.next(); + final StreamingStatistics stats = getStatistics(process, metric); buffer.append(metric.toUpperCase()); buffer.append(" for "); buffer.append(process); - buffer.append(" "); - buffer.append(getStatistics(process, metric).toString()); + buffer.append(endl); + buffer.append("n: ").append(stats.getN()).append(endl); + buffer.append("min: ").append(stats.getMin()).append(" ") + .append("max: ").append(stats.getMax()).append(endl); + buffer.append("mean: ").append(stats.getMean()).append(" ") + .append("std dev: ").append(stats.getStandardDeviation()) + .append(endl); + buffer.append("1%: ").append(stats.getPercentile(1)).append(" ") + .append("5%: ").append(stats.getPercentile(5)).append(" ") + .append("10%: ").append(stats.getPercentile(10)).append(endl); + buffer.append("25%: ").append(stats.getPercentile(25)).append(" ") + .append("median: ").append(stats.getPercentile(50)).append(" ") + .append("75%: ").append(stats.getPercentile(75)).append(endl); + buffer.append("90%: ").append(stats.getPercentile(90)).append(" ") + .append("95%: ").append(stats.getPercentile(95)).append(" ") + .append("99%: ").append(stats.getPercentile(99)).append(endl); buffer.append("\n********************************************\n"); } return buffer.toString(); @@ -341,7 +382,10 @@ public class Statistics * Composite key (<process,type>). */ private static class StatisticsKey - implements Serializable { + implements + Serializable { + + private static final long serialVersionUID = 1L; public StatisticsKey(String process, String type) { this.process = process; @@ -349,6 +393,7 @@ public class Statistics } private String process = null; + private String type = null; @Override @@ -357,7 +402,8 @@ public class Statistics return false; } else { StatisticsKey other = (StatisticsKey) obj; - return (other.process.equals(this.process)) && (other.type.equals(this.type)); + return (other.process.equals(this.process)) && + (other.type.equals(this.type)); } } @@ -365,14 +411,6 @@ public class Statistics public int hashCode() { return 7 + 11 * process.hashCode() + 17 * type.hashCode(); } - - public String getType() { - return type; - } - - public String getProcess() { - return process; - } } } Modified: commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/dbcp/DBCPClientThread.java URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/dbcp/DBCPClientThread.java?rev=1888832&r1=1888831&r2=1888832&view=diff ============================================================================== --- commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/dbcp/DBCPClientThread.java (original) +++ commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/dbcp/DBCPClientThread.java Fri Apr 16 18:57:07 2021 @@ -22,9 +22,9 @@ import java.util.logging.Logger; import javax.sql.DataSource; import org.apache.commons.dbcp2.BasicDataSource; -import org.apache.commons.math3.stat.descriptive.SummaryStatistics; import org.apache.commons.performance.ClientThread; import org.apache.commons.performance.Statistics; +import org.hipparchus.stat.descriptive.StreamingStatistics; /** * Client thread that executes requests in a loop using a configured DataSource, @@ -55,10 +55,10 @@ public class DBCPClientThread String currentQuery = null; /** Statistics on numActive */ - private SummaryStatistics numActiveStats = new SummaryStatistics(); + private StreamingStatistics numActiveStats = new StreamingStatistics(true); /** Statistics on numIdle */ - private SummaryStatistics numIdleStats = new SummaryStatistics(); + private StreamingStatistics numIdleStats = new StreamingStatistics(true); /** Sampling rate for numActive, numIdle */ private double samplingRate; Modified: commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/dbcp/DBCPSoak.java URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/dbcp/DBCPSoak.java?rev=1888832&r1=1888831&r2=1888832&view=diff ============================================================================== --- commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/dbcp/DBCPSoak.java (original) +++ commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/dbcp/DBCPSoak.java Fri Apr 16 18:57:07 2021 @@ -30,7 +30,6 @@ import org.apache.commons.dbcp2.DriverCo import org.apache.commons.dbcp2.DriverManagerConnectionFactory; import org.apache.commons.dbcp2.PoolableConnectionFactory; import org.apache.commons.dbcp2.PoolingDataSource; -import org.apache.commons.math3.random.RandomDataGenerator; import org.apache.commons.performance.ClientThread; import org.apache.commons.performance.ConfigurationException; import org.apache.commons.performance.LoadGenerator; @@ -38,6 +37,7 @@ import org.apache.commons.performance.St import org.apache.commons.pool2.impl.AbandonedConfig; import org.apache.commons.pool2.impl.GenericObjectPool; import org.apache.tomcat.jdbc.pool.PoolProperties; +import org.hipparchus.random.RandomDataGenerator; /** * Configurable load / performance tester for commons dbcp. Uses Commons Modified: commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/pool/PoolClientThread.java URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/pool/PoolClientThread.java?rev=1888832&r1=1888831&r2=1888832&view=diff ============================================================================== --- commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/pool/PoolClientThread.java (original) +++ commons/sandbox/performance/trunk/src/java/org/apache/commons/performance/pool/PoolClientThread.java Fri Apr 16 18:57:07 2021 @@ -18,16 +18,12 @@ import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; -// import org.apache.commons.pool.ObjectPool; -// import org.apache.commons.pool2.ObjectPool; -// import org.apache.commons.pool.KeyedObjectPool; -// import org.apache.commons.pool2.KeyedObjectPool; -import org.apache.commons.math3.random.RandomDataGenerator; -import org.apache.commons.math3.stat.descriptive.SummaryStatistics; import org.apache.commons.performance.ClientThread; import org.apache.commons.performance.Statistics; import org.apache.commons.pool2.KeyedObjectPool; import org.apache.commons.pool2.ObjectPool; +import org.hipparchus.random.RandomDataGenerator; +import org.hipparchus.stat.descriptive.StreamingStatistics; /** * <p> @@ -61,16 +57,16 @@ public class PoolClientThread private final RandomDataGenerator randomData = new RandomDataGenerator(); /** Statistics on numActive */ - private SummaryStatistics numActiveStats = new SummaryStatistics(); + private StreamingStatistics numActiveStats = new StreamingStatistics(true); /** Statistics on numIdle */ - private SummaryStatistics numIdleStats = new SummaryStatistics(); + private StreamingStatistics numIdleStats = new StreamingStatistics(true); /** Sampling rate for numActive, numIdle */ private double samplingRate; /** Statistics on instance idle time */ - private SummaryStatistics instanceIdleTimeStats = new SummaryStatistics(); + private StreamingStatistics instanceIdleTimeStats = new StreamingStatistics(true); /** * Just-borrowed Waiter instance (used to grab idle time stats in cleanUp) @@ -172,9 +168,11 @@ public class PoolClientThread if (randomData.nextUniform(0, 1) < samplingRate) { if (keyedPool2 != null) { numActiveStats.addValue(keyedPool2.getNumActive()); + numIdleStats.addValue(keyedPool2.getNumIdle()); } if (pool2 != null) { numActiveStats.addValue(pool2.getNumActive()); + numIdleStats.addValue(pool2.getNumIdle()); } } if (waiter != null) { Modified: commons/sandbox/performance/trunk/src/pool/build.xml URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/pool/build.xml?rev=1888832&r1=1888831&r2=1888832&view=diff ============================================================================== --- commons/sandbox/performance/trunk/src/pool/build.xml (original) +++ commons/sandbox/performance/trunk/src/pool/build.xml Fri Apr 16 18:57:07 2021 @@ -66,14 +66,16 @@ dest="${lib}/commons-digester-1.8.jar" usetimestamp="true"/> </target> - <target name="get-math"> <get - src="${mavenRepo}/org/apache/commons/commons-math3/3.2/commons-math3-3.2.jar" - dest="${lib}/commons-math3-3.2.jar" - usetimestamp="true"/> + src="${mavenRepo}/org/hipparchus/hipparchus-core/1.8/hipparchus-core-1.8.jar" + dest="${lib}/hipparchus-core-1.8.jar" + usetimestamp="true"/> + <get + src="${mavenRepo}/org/hipparchus/hipparchus-stat/1.8/hipparchus-stat-1.8.jar" + dest="${lib}/hipparchus-stat-1.8.jar" + usetimestamp="true"/> </target> - <target name="get-logging"> <get src="${mavenRepo}/commons-logging/commons-logging/1.0.4/commons-logging-1.0.4.jar" Modified: commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/ClientThreadTest.java URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/ClientThreadTest.java?rev=1888832&r1=1888831&r2=1888832&view=diff ============================================================================== --- commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/ClientThreadTest.java (original) +++ commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/ClientThreadTest.java Fri Apr 16 18:57:07 2021 @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Modified: commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/LoadGeneratorTest.java URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/LoadGeneratorTest.java?rev=1888832&r1=1888831&r2=1888832&view=diff ============================================================================== --- commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/LoadGeneratorTest.java (original) +++ commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/LoadGeneratorTest.java Fri Apr 16 18:57:07 2021 @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -18,36 +18,49 @@ package org.apache.commons.performance; import java.util.logging.Logger; +import org.hipparchus.random.RandomDataGenerator; +import org.hipparchus.stat.descriptive.StreamingStatistics; + import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; -import org.apache.commons.math3.random.RandomDataGenerator; -import org.apache.commons.math3.stat.descriptive.SummaryStatistics; - public class LoadGeneratorTest - extends TestCase { + extends + TestCase { protected TestLoadGenerator generator = null; - protected static Logger logger = Logger.getLogger(LoadGenerator.class.getName()); + + protected static Logger logger = Logger + .getLogger(LoadGenerator.class.getName()); + protected static Statistics stats = new Statistics(); class TestClientThread - extends ClientThread { + extends + ClientThread { private long latency = 50; + private double metricOne = 10d; + private double metricTwo = 20d; - private SummaryStatistics oneStats = new SummaryStatistics(); - private SummaryStatistics twoStats = new SummaryStatistics(); - private SummaryStatistics randomStats = new SummaryStatistics(); + + private StreamingStatistics oneStats = new StreamingStatistics(); + + private StreamingStatistics twoStats = new StreamingStatistics(); + + private StreamingStatistics randomStats = new StreamingStatistics(); + private RandomDataGenerator randomData = new RandomDataGenerator(); - public TestClientThread(long iterations, long minDelay, long maxDelay, double sigma, String delayType, - long rampPeriod, long peakPeriod, long troughPeriod, String cycleType, String rampType, + public TestClientThread(long iterations, long minDelay, long maxDelay, + double sigma, String delayType, long rampPeriod, + long peakPeriod, long troughPeriod, + String cycleType, String rampType, Logger logger, Statistics stats) { - super(iterations, minDelay, maxDelay, sigma, delayType, rampPeriod, peakPeriod, troughPeriod, cycleType, - rampType, logger, stats); + super(iterations, minDelay, maxDelay, sigma, delayType, rampPeriod, + peakPeriod, troughPeriod, cycleType, rampType, logger, stats); } public void setLatency(long latency) { @@ -69,28 +82,37 @@ public class LoadGeneratorTest @Override protected void finish() { - stats.addStatistics(oneStats, Thread.currentThread().getName(), "one"); - stats.addStatistics(twoStats, Thread.currentThread().getName(), "two"); - stats.addStatistics(randomStats, Thread.currentThread().getName(), "random"); + stats.addStatistics(oneStats, Thread.currentThread().getName(), + "one"); + stats.addStatistics(twoStats, Thread.currentThread().getName(), + "two"); + stats.addStatistics(randomStats, Thread.currentThread().getName(), + "random"); } } class TestLoadGenerator - extends LoadGenerator { + extends + LoadGenerator { @Override - protected ClientThread makeClientThread(long iterations, long minDelay, long maxDelay, double sigma, - String delayType, long rampPeriod, long peakPeriod, long troughPeriod, - String cycleType, String rampType, Logger logger, Statistics stats) { - return new TestClientThread(iterations, minDelay, maxDelay, sigma, delayType, rampPeriod, peakPeriod, - troughPeriod, cycleType, rampType, logger, stats); + protected ClientThread + makeClientThread(long iterations, long minDelay, long maxDelay, + double sigma, String delayType, long rampPeriod, + long peakPeriod, long troughPeriod, + String cycleType, String rampType, Logger logger, + Statistics stats) { + return new TestClientThread(iterations, minDelay, maxDelay, sigma, + delayType, rampPeriod, peakPeriod, + troughPeriod, cycleType, rampType, + logger, stats); } @Override protected void parseConfigFile() throws Exception { getDigester().parse(this.getClass() - .getResourceAsStream("/org/apache/commons/performance/pool/config-pool.xml")); + .getResourceAsStream("/org/apache/commons/performance/pool/config-pool.xml")); } } @@ -112,7 +134,7 @@ public class LoadGeneratorTest throws Exception { generator.execute(); Statistics statistics = generator.getStatistics(); - SummaryStatistics stats = null; + StreamingStatistics stats = null; stats = statistics.getMeanSummary("latency"); assertEquals(50, stats.getMean(), 100.0); stats = statistics.getMeanSummary("one"); Modified: commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/TesterClientThread.java URL: http://svn.apache.org/viewvc/commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/TesterClientThread.java?rev=1888832&r1=1888831&r2=1888832&view=diff ============================================================================== --- commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/TesterClientThread.java (original) +++ commons/sandbox/performance/trunk/src/test/org/apache/commons/performance/TesterClientThread.java Fri Apr 16 18:57:07 2021 @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,33 +20,42 @@ package org.apache.commons.performance; import java.util.logging.Logger; /** - * Test ClientThread + * Test ClientThread */ -public class TesterClientThread extends ClientThread { - - /** - * Distribution parameters for simulated service latency. - * To configure constant delay - i.e., the same latency each time, - * supply serviceDelayType = "constant" and meanServiceDelay = the - * desired delay to the constructor. +public class TesterClientThread + extends + ClientThread { + + /** + * Distribution parameters for simulated service latency. To configure + * constant delay - i.e., the same latency each time, supply + * serviceDelayType = "constant" and meanServiceDelay = the desired delay to + * the constructor. */ private final long minServiceDelay; + private final long maxServiceDelay; + private final double meanServiceDelay; + private final double sigmaServiceDelay; + private final String serviceDelayType; - - /** + + /** * Lifecycle events trackers */ private boolean initialized = false; + private boolean finalized = false; + private long setups = 0; + private long tearDowns = 0; - - /** to hurl or not to hurl */ + + /** to hurl or not to hurl */ private boolean hurling = false; - + public boolean isHurling() { return hurling; } @@ -56,26 +65,30 @@ public class TesterClientThread extends } /** Executed once at the beginning of the run */ - protected void init() throws Exception { + protected void init() + throws Exception { initialized = true; } - + /** Executed at the beginning of each iteration */ - protected void setUp() throws Exception { + protected void setUp() + throws Exception { setups++; } - + /** Executed in finally block of iteration try-catch */ - protected void cleanUp() throws Exception { + protected void cleanUp() + throws Exception { tearDowns++; } - + /** Executed once after the run finishes */ - protected void finish() throws Exception { + protected void finish() + throws Exception { finalized = true; } - - public boolean isInitialized() { + + public boolean isInitialized() { return initialized; } @@ -92,45 +105,46 @@ public class TesterClientThread extends } public TesterClientThread(long iterations, long minDelay, long maxDelay, - double sigma, String delayType, long rampPeriod, long peakPeriod, - long troughPeriod, String cycleType, String rampType, - Logger logger, Statistics stats, long minServiceDelay, - long maxServiceDelay, double meanServiceDelay, - double sigmaServiceDelay, String serviceDelayType) { - + double sigma, String delayType, long rampPeriod, + long peakPeriod, long troughPeriod, + String cycleType, String rampType, Logger logger, + Statistics stats, long minServiceDelay, + long maxServiceDelay, double meanServiceDelay, + double sigmaServiceDelay, + String serviceDelayType) { + super(iterations, minDelay, maxDelay, sigma, delayType, rampPeriod, - peakPeriod, troughPeriod, cycleType, rampType, logger, - stats); + peakPeriod, troughPeriod, cycleType, rampType, logger, stats); this.minServiceDelay = minServiceDelay; this.maxServiceDelay = maxServiceDelay; this.meanServiceDelay = meanServiceDelay; this.sigmaServiceDelay = sigmaServiceDelay; this.serviceDelayType = serviceDelayType; } - - /** + + /** * Simulate server latency using service latency parameters */ - public void execute() throws Exception { - if (hurling) { - throw new RuntimeException("Bang!"); - } - if (meanServiceDelay <= 0) { - return; - } - if (serviceDelayType.equals("constant")) { - Thread.sleep(Math.round(meanServiceDelay)); - } else if (serviceDelayType.equals("gaussian")) { - Thread.sleep(Math.round(randomData.nextGaussian( - meanServiceDelay, sigmaServiceDelay))); - } else if (serviceDelayType.equals("poisson")) { - Thread.sleep(Math.round( - randomData.nextPoisson(meanServiceDelay))); - } - else if (serviceDelayType.equals("uniform")) { - Thread.sleep(Math.round( - randomData.nextUniform(minServiceDelay, maxServiceDelay))); - } - + public void execute() + throws Exception { + if (hurling) { + throw new RuntimeException("Bang!"); + } + if (meanServiceDelay <= 0) { + return; + } + if (serviceDelayType.equals("constant")) { + Thread.sleep(Math.round(meanServiceDelay)); + } else if (serviceDelayType.equals("gaussian")) { + Thread.sleep(Math + .round(randomData.nextGaussian() * sigmaServiceDelay + + meanServiceDelay)); + } else if (serviceDelayType.equals("poisson")) { + Thread.sleep(Math.round(randomData.nextPoisson(meanServiceDelay))); + } else if (serviceDelayType.equals("uniform")) { + Thread.sleep(Math.round(randomData.nextUniform(minServiceDelay, + maxServiceDelay))); + } + } }