Author: sebb
Date: Mon Aug 24 10:50:25 2009
New Revision: 807146

URL: http://svn.apache.org/viewvc?rev=807146&view=rev
Log:
Genericise StatCalculator

Added:
    
jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/math/StatCalculatorInteger.java
   (with props)
    
jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/math/StatCalculatorLong.java
   (with props)
Modified:
    
jakarta/jmeter/trunk/src/core/org/apache/jmeter/visualizers/SamplingStatCalculator.java
    jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/math/StatCalculator.java
    
jakarta/jmeter/trunk/test/src/org/apache/jorphan/math/TestStatCalculator.java

Modified: 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/visualizers/SamplingStatCalculator.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/visualizers/SamplingStatCalculator.java?rev=807146&r1=807145&r2=807146&view=diff
==============================================================================
--- 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/visualizers/SamplingStatCalculator.java
 (original)
+++ 
jakarta/jmeter/trunk/src/core/org/apache/jmeter/visualizers/SamplingStatCalculator.java
 Mon Aug 24 10:50:25 2009
@@ -25,7 +25,7 @@
 
 import org.apache.jmeter.samplers.SampleResult;
 import org.apache.jorphan.logging.LoggingManager;
-import org.apache.jorphan.math.StatCalculator;
+import org.apache.jorphan.math.StatCalculatorLong;
 import org.apache.log.Logger;
 
 /**
@@ -37,7 +37,7 @@
 public class SamplingStatCalculator {
     private static final Logger log = LoggingManager.getLoggerForClass();
 
-    private final StatCalculator calculator = new StatCalculator();
+    private final StatCalculatorLong calculator = new StatCalculatorLong();
 
     private final List<Sample> storedValues = new Vector<Sample>();
 
@@ -312,7 +312,7 @@
         return maxThroughput;
     }
 
-    public HashMap getDistribution() {
+    public HashMap<Number, Number[]> getDistribution() {
         return calculator.getDistribution();
     }
 

Modified: 
jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/math/StatCalculator.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/math/StatCalculator.java?rev=807146&r1=807145&r2=807146&view=diff
==============================================================================
--- 
jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/math/StatCalculator.java 
(original)
+++ 
jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/math/StatCalculator.java 
Mon Aug 24 10:50:25 2009
@@ -25,27 +25,45 @@
 import java.util.List;
 
 /**
- * This class serves as a way to calculate the median of a list of values. It 
is
- * not threadsafe.
+ * This class serves as a way to calculate the median, max, min etc. of a list 
of values.
+ * It is not threadsafe.
  * 
- * TODO - currently only works properly for Long (because getDistribution() 
assumes Long)
- * Will never work for mixed values (e.g. Long and Integer) so should probably 
be converted to
- * typed class.
  */
-public class StatCalculator {
-    List values = new LinkedList();
+public abstract class StatCalculator<T extends Number & Comparable<T>> {
+    
+    private final List<T> values = new LinkedList<T>();
 
-    double sum = 0;
+    private double sum = 0;
 
-    double sumOfSquares = 0;
+    private double sumOfSquares = 0;
 
-    double mean = 0;
+    private double mean = 0;
 
-    double deviation = 0;
+    private double deviation = 0;
 
-    int count = 0;
+    private int count = 0;
 
-    long bytes = 0;
+    private long bytes = 0;
+
+    private final T ZERO;
+    
+    private final T MAX_VALUE;
+    
+    private final T MIN_VALUE;
+    
+    /**
+     * This constructor is used to set up particular values for the generic 
class instance.
+     *
+     * @param zero - value to return for Median and PercentPoint if there are 
no values
+     * @param min - value to return for minimum if there are no values
+     * @param max - value to return for maximum if there are no values
+     */
+    public StatCalculator(T zero, T min, T max) {
+        super();
+        ZERO = zero;
+        MAX_VALUE = max;
+        MIN_VALUE = min;
+    }
 
     public void clear() {
         values.clear();
@@ -56,32 +74,13 @@
         count = 0;
     }
 
-    public void addValue(long newValue) {
-        Number val = new Long(newValue);
-        addValue(val);
-    }
-
-    public void addValue(int newValue) {
-        Number val = new Integer(newValue);
-        addValue(val);
-    }
-
-    public void addValue(float newValue) {
-        Number val = new Float(newValue);
-        addValue(val);
-    }
-
-    public void addValue(double newValue) {
-        Number val = new Double(newValue);
-        addValue(val);
-    }
 
     public void addBytes(long newValue) {
         bytes += newValue;
     }
 
-    public void addAll(StatCalculator calc) {
-        Iterator<Number> iter = calc.values.iterator();
+    public void addAll(StatCalculator<T> calc) {
+        Iterator<T> iter = calc.values.iterator();
         while (iter.hasNext()) {
             addValue(iter.next());
         }
@@ -89,9 +88,9 @@
 
     public Number getMedian() {
         if (count > 0) {
-            return (Number) values.get((int) (values.size() * .5));
+            return values.get((int) (values.size() * .5));
         }
-        return new Long(0);
+        return ZERO;
     }
 
     public long getTotalBytes() {
@@ -107,11 +106,11 @@
      * @param percent
      * @return number of values less than the percentage
      */
-    public Number getPercentPoint(float percent) {
+    public T getPercentPoint(float percent) {
         if (count > 0) {
-            return (Number) values.get((int) (values.size() * percent));
+            return values.get((int) (values.size() * percent));
         }
-        return new Long(0);
+        return ZERO;
     }
 
     /**
@@ -123,25 +122,30 @@
      * @param percent
      * @return number of values less than the percentage
      */
-    public Number getPercentPoint(double percent) {
+    public T getPercentPoint(double percent) {
         if (count > 0) {
-            return (Number) values.get((int) (values.size() * percent));
+            return values.get((int) (values.size() * percent));
         }
-        return new Long(0);
+        return ZERO;
     }
 
     /**
-     * The method has a limit of 1% as the finest granularity. We do this to
-     * make sure we get a whole number for iterating.
+     * Returns the distribution of the values in the list.
+     * 
+     * TODO round values to reduce the number of distinct entries.
      *
+     * @return map containing either Integer or Long keys; entries are a 
Number array containing the key and the [Integer] count.
+     * TODO - why is the key value also stored in the entry array?
      */
-    public synchronized HashMap getDistribution() {
-        HashMap<Long, Number[]> items = new HashMap<Long, Number[]>();
-        Iterator<Number> itr = this.values.iterator();
+    public synchronized HashMap<Number, Number[]> getDistribution() {
+        HashMap<Number, Number[]> items = new HashMap<Number, Number[]>();
+        Iterator<T> itr = this.values.iterator();
         Number[] dis;
         while (itr.hasNext()) {
-            Number num = itr.next();
-            Long nx = new Long(itr.next().longValue()); // TODO this assumes 
the entries are all Long
+            Number nx = itr.next();
+            if (!(nx instanceof Integer || nx instanceof Long)){
+                nx=new Long(nx.longValue()); // convert to Long unless Integer 
or Long
+            }
             if (items.containsKey(nx)) {
                 dis = items.get(nx);
                 dis[1] = new Integer(dis[1].intValue() + 1);
@@ -164,25 +168,25 @@
         return deviation;
     }
 
-    public Number getMin() {
+    public T getMin() {
         if (count > 0) {
-            return (Number) values.get(0);
+            return values.get(0);
         }
-        return new Long(Long.MIN_VALUE);
+        return MIN_VALUE;
     }
 
-    public Number getMax() {
+    public T getMax() {
         if (count > 0) {
-            return (Number) values.get(count - 1);
+            return values.get(count - 1);
         }
-        return new Long(Long.MAX_VALUE);
+        return MAX_VALUE;
     }
 
     public int getCount() {
         return count;
     }
 
-    public void addValue(Number val) {
+    public void addValue(T val) {
         addSortedValue(val);
         count++;
         double currentVal = val.doubleValue();
@@ -192,10 +196,7 @@
         deviation = Math.sqrt((sumOfSquares / count) - (mean * mean));
     }
 
-    /**
-     * @param val
-     */
-    private void addSortedValue(Number val) {
+    private void addSortedValue(T val) {
         int index = Collections.binarySearch(values, val);
         if (index >= 0 && index < values.size()) {
             values.add(index, val);

Added: 
jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/math/StatCalculatorInteger.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/math/StatCalculatorInteger.java?rev=807146&view=auto
==============================================================================
--- 
jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/math/StatCalculatorInteger.java
 (added)
+++ 
jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/math/StatCalculatorInteger.java
 Mon Aug 24 10:50:25 2009
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+package org.apache.jorphan.math;
+
+/**
+ * StatCalculator for Integer values
+ */
+public class StatCalculatorInteger extends StatCalculator<Integer> {
+
+    public StatCalculatorInteger() {
+        super(new Integer(0), new Integer(Integer.MIN_VALUE), new 
Integer(Integer.MAX_VALUE));
+    }
+
+    public void addValue(int val){
+        super.addValue(new Integer(val));
+    }
+}

Propchange: 
jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/math/StatCalculatorInteger.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/math/StatCalculatorInteger.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: 
jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/math/StatCalculatorLong.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/math/StatCalculatorLong.java?rev=807146&view=auto
==============================================================================
--- 
jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/math/StatCalculatorLong.java
 (added)
+++ 
jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/math/StatCalculatorLong.java
 Mon Aug 24 10:50:25 2009
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+package org.apache.jorphan.math;
+
+/**
+ * StatCalculator for Long values
+ */
+public class StatCalculatorLong extends StatCalculator<Long> {
+
+    public StatCalculatorLong() {
+        super(new Long(0L), new Long(Long.MIN_VALUE), new 
Long(Long.MAX_VALUE));
+    }
+
+    public void addValue(long val){
+        super.addValue(new Long(val));
+    }
+}

Propchange: 
jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/math/StatCalculatorLong.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
jakarta/jmeter/trunk/src/jorphan/org/apache/jorphan/math/StatCalculatorLong.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: 
jakarta/jmeter/trunk/test/src/org/apache/jorphan/math/TestStatCalculator.java
URL: 
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/test/src/org/apache/jorphan/math/TestStatCalculator.java?rev=807146&r1=807145&r2=807146&view=diff
==============================================================================
--- 
jakarta/jmeter/trunk/test/src/org/apache/jorphan/math/TestStatCalculator.java 
(original)
+++ 
jakarta/jmeter/trunk/test/src/org/apache/jorphan/math/TestStatCalculator.java 
Mon Aug 24 10:50:25 2009
@@ -18,11 +18,13 @@
 
 package org.apache.jorphan.math;
 
+import java.util.Map;
+
 import junit.framework.TestCase;
 
 public class TestStatCalculator extends TestCase {
 
-    StatCalculator calc;
+    private StatCalculatorLong calc;
 
     /**
      * 
@@ -40,7 +42,7 @@
 
     @Override
     public void setUp() {
-        calc = new StatCalculator();
+        calc = new StatCalculatorLong();
     }
 
     public void testPercentagePoint() throws Exception {
@@ -77,15 +79,25 @@
     public void testLong(){
         calc.addValue(0L);
         calc.addValue(2L);
-        assertEquals(Long.valueOf(2),calc.getMax());
-        assertEquals(Long.valueOf(0),calc.getMin());
-        calc.getDistribution();
+        calc.addValue(2L);
+        final Long long0 = Long.valueOf(0);
+        final Long long2 = Long.valueOf(2);
+        assertEquals(long2,calc.getMax());
+        assertEquals(long0,calc.getMin());
+        Map<Number, Number[]> map = calc.getDistribution();
+        assertTrue(map.containsKey(long0));
+        assertTrue(map.containsKey(long2));
     }
+    
     public void testInteger(){
-        calc.addValue(0);
-        calc.addValue(2);
-        assertEquals(Integer.valueOf(2),calc.getMax());
-        assertEquals(Integer.valueOf(0),calc.getMin());
-//        calc.getDistribution(); // currently fails with ClassCastException
+        StatCalculatorInteger calci = new StatCalculatorInteger();
+        calci.addValue(0);
+        calci.addValue(2);
+        calci.addValue(2);
+        assertEquals(Integer.valueOf(2),calci.getMax());
+        assertEquals(Integer.valueOf(0),calci.getMin());
+        Map<Number, Number[]> map = calci.getDistribution();
+        assertTrue(map.containsKey(Integer.valueOf(0)));
+        assertTrue(map.containsKey(Integer.valueOf(2)));
     }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: jmeter-dev-unsubscr...@jakarta.apache.org
For additional commands, e-mail: jmeter-dev-h...@jakarta.apache.org

Reply via email to