changeset 1834:7db129297a73

Backport - Fix treemap scaling imprecision Reviewed-by: jkang, aazores, neugens Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2015-October/016635.html
author James Aziz <jaziz@redhat.com>
date Wed, 28 Oct 2015 16:22:48 -0400
parents 2649ea55de87
children 0e3d1a118611
files vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SquarifiedTreeMap.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapNode.java vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapNodeTest.java vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeProcessorTest.java
diffstat 4 files changed, 69 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SquarifiedTreeMap.java	Tue Oct 13 17:16:38 2015 -0400
+++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SquarifiedTreeMap.java	Wed Oct 28 16:22:48 2015 -0400
@@ -328,7 +328,7 @@
      * @return the sum of the elements.
      */
     private double getSum(List<TreeMapNode> nodes) {
-        int sum = 0;
+        double sum = 0;
         for (TreeMapNode n : nodes) {
             sum += n.getWeight();
         }
@@ -433,7 +433,7 @@
         
         // recalculate weights in percentage of their sum
         for (TreeMapNode node : elements) {
-            int w = (int) Math.round((node.getWeight()/sum) * totArea);
+            double w = (node.getWeight()/sum) * totArea;
             node.setWeight(w);
         }
     }
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapNode.java	Tue Oct 13 17:16:38 2015 -0400
+++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapNode.java	Wed Oct 28 16:22:48 2015 -0400
@@ -107,8 +107,7 @@
     private String label;
     
     /**
-     * The node's weight which has been set inside the constructor. Note that
-     * this value can be assigned just one time, using the constructor. All 
+     * The node's weight which has been set inside the constructor. All
      * operations which refers to node's weight work on the weight field, that 
      * is used to make calcs.
      */
@@ -329,7 +328,7 @@
      * automatically to 0.
      * @param weight the new weight for this object.
      */
-    public void setWeight(int w) {
+    public void setWeight(double w) {
         this.weight = w < 0 && !allowNonPositiveWeight ? 0 : w;
     }
 
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapNodeTest.java	Tue Oct 13 17:16:38 2015 -0400
+++ b/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapNodeTest.java	Wed Oct 28 16:22:48 2015 -0400
@@ -57,6 +57,7 @@
 public class TreeMapNodeTest {
 
     private TreeMapNode node;
+    private static final double DELTA = 0.001;
 
     @Before
     public void setUp() {
@@ -126,9 +127,9 @@
 
     @Test
     public final void testGetSetWeight() {
-        assertTrue(1 == node.getWeight());
+        assertEquals(1.0, node.getWeight(), DELTA);
         node.setWeight(5);
-        assertTrue(5 == node.getWeight());
+        assertEquals(5.0, node.getWeight(), DELTA);
     }
 
     @Test
@@ -151,22 +152,21 @@
     @Test
     public final void testGetSetRealWeight() {
         node = new TreeMapNode(null, 5);
-        assertTrue(node.getRealWeight() == 5);
+        assertEquals(5.0, node.getRealWeight(), DELTA);
         node.setRealWeight(8);
-        assertTrue(node.getRealWeight() == 8);
+        assertEquals(8.0, node.getRealWeight(), DELTA);
     }
 
     @Test
     public final void testAllowNonPositiveWeight() {
         assertFalse(TreeMapNode.isAllowNonPositiveWeight());
         node.setWeight(-5);
-        assertTrue(node.getWeight() == 1); // the real node weight
-        assertTrue(node.getRealWeight() == 1); 
-
+        assertEquals(1.0, node.getWeight(), DELTA);
+        assertEquals(1.0, node.getRealWeight(), DELTA);
 
         TreeMapNode.setAllowNonPositiveWeight(true);
         node.setWeight(-5);
-        assertTrue(node.getWeight() == -5);
+        assertEquals(-5.0, node.getWeight(), DELTA);
     }
 
     @Test
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeProcessorTest.java	Tue Oct 13 17:16:38 2015 -0400
+++ b/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeProcessorTest.java	Wed Oct 28 16:22:48 2015 -0400
@@ -36,18 +36,21 @@
 
 package com.redhat.thermostat.vm.heap.analysis.client.swing.internal;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.awt.geom.Rectangle2D;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
+import java.util.List;
 
 import org.junit.Before;
 import org.junit.Test;
 
 public class TreeProcessorTest {
 
+    private static final double DELTA = 0.1;
+    private static final double BASE = 2.0;
+
     TreeMapNode node;
     Rectangle2D.Double area;
 
@@ -59,35 +62,35 @@
 
     @Test
     public final void testTreeProcessor() {
-        boolean catched = false;
+        boolean caught = false;
         // this test check all wrong combinations for constructor parameters
         try {
             TreeProcessor.processTreeMap(null, area);
         } catch(NullPointerException e) {
-            catched = true;
+            caught = true;
         }
-        assertTrue(catched);
-        catched = false;
+        assertTrue(caught);
+        caught = false;
 
         try {
             TreeProcessor.processTreeMap(node, null);
         } catch(NullPointerException e) {
-            catched = true;
+            caught = true;
         }
-        assertTrue(catched);
-        catched = false;
+        assertTrue(caught);
+        caught = false;
 
         try {
             TreeProcessor.processTreeMap(null, null);
         } catch(NullPointerException e) {
-            catched = true;
+            caught = true;
         }
-        assertTrue(catched);
+        assertTrue(caught);
     }
 
 
     @Test
-    public final void testProcessTreeMap() {
+    public final void testProcessTreeMapProcessesWholeTree() {
         generateTree(node, 5, 5);
         TreeProcessor.processTreeMap(node, area);
 
@@ -117,4 +120,46 @@
             }
         }
     }
+
+    @Test
+    public final void testProcessTreeMapNodeSizing() {
+        final int numSiblings = 5;
+        final double originalDimension = 64.0;
+        final double smallerDimension = 32.0;
+
+        generateSiblingTree(node, numSiblings);
+
+        TreeProcessor.processTreeMap(node, new Rectangle2D.Double(0, 0, originalDimension, originalDimension));
+        checkNodeWeightRatios(numSiblings);
+
+        //now resize smaller
+        TreeProcessor.processTreeMap(node, new Rectangle2D.Double(0, 0, smallerDimension, smallerDimension));
+
+        //now resize back to original size
+        TreeProcessor.processTreeMap(node, new Rectangle2D.Double(0, 0, originalDimension, originalDimension));
+        //if the first call to checkNodeWeightRatios(numSiblings) worked, this should too
+        checkNodeWeightRatios(numSiblings);
+    }
+
+    private void generateSiblingTree(TreeMapNode root, int numSiblings) {
+        assertTrue(numSiblings > 1);
+        root.addChild(new TreeMapNode(1.0)); //this is not a random weight
+        for(int i = 0; i < (numSiblings - 1); i++) {
+            root.addChild(new TreeMapNode(Math.pow(BASE, i)));
+        }
+    }
+
+    private void checkNodeWeightRatios(int numSiblings) {
+        List<TreeMapNode> children = node.getChildren();
+        assertEquals(numSiblings, children.size());
+        TreeMapNode.sort(children);
+
+        double weight = children.get(0).getWeight();
+        for(int i = 1; i < numSiblings - 1; i++) {
+            double currentWeight = children.get(i).getWeight();
+            //check that the ratio between node weights is approximately 2 (which is the BASE)
+            assertEquals(BASE, weight/currentWeight, DELTA);
+            weight = currentWeight;
+        }
+    }
 }