561460: More comparison queries

FindBugs fixes.

Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=561460
diff --git a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/FindLeaksQuery2.java b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/FindLeaksQuery2.java
index 1113d14..59cb6a2 100644
--- a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/FindLeaksQuery2.java
+++ b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/FindLeaksQuery2.java
@@ -167,7 +167,6 @@
         // Get the last - in case the first is also this snapshot, so has a context provider

         ContextProvider cp = provs.get(provs.size() - 1);

         ArrayInt suspiciousObjects = new ArrayInt();

-        Set<String> suspectNames = new HashSet<String>();

         int i = 0;

         HashMapIntObject<ClassRecord>map = new HashMapIntObject<ClassRecord>();

         final HashMapIntObject<Object>rowmap = new HashMapIntObject<Object>(); 

@@ -185,7 +184,6 @@
                     if (deltaRetained > threshold)

                     {

                         suspiciousObjects.add(objId);

-                        suspectNames.add(cls.getName());

                         rowmap.put(objId, row);

                     }

                     else

@@ -369,54 +367,6 @@
                         .execute(listener);

     }

 

-    private Histogram groupByClasses(int[] dominated, IProgressListener listener) throws SnapshotException

-    {

-        Histogram histogram = snapshot.getHistogram(dominated, listener);

-        if (listener.isCanceled())

-            throw new IProgressListener.OperationCanceledException();

-

-        Collection<ClassHistogramRecord> records = histogram.getClassHistogramRecords();

-        ClassHistogramRecord[] arr = new ClassHistogramRecord[records.size()];

-        int i = 0;

-

-        for (ClassHistogramRecord record : records)

-        {

-            record.setRetainedHeapSize(sumRetainedSize(record.getObjectIds(), snapshot));

-            arr[i++] = record;

-            if (i % 10 == 0 && listener.isCanceled())

-                throw new IProgressListener.OperationCanceledException();

-        }

-

-        Collection<ClassLoaderHistogramRecord> loaderRecords = histogram.getClassLoaderHistogramRecords();

-        ClassLoaderHistogramRecord[] loaderArr = new ClassLoaderHistogramRecord[loaderRecords.size()];

-        i = 0;

-

-        for (ClassLoaderHistogramRecord record : loaderRecords)

-        {

-            long retainedSize = 0;

-            for (ClassHistogramRecord classRecord : record.getClassHistogramRecords())

-            {

-                retainedSize += classRecord.getRetainedHeapSize();

-            }

-

-            record.setRetainedHeapSize(retainedSize);

-            loaderArr[i++] = record;

-        }

-

-        return histogram;

-

-    }

-

-    private long sumRetainedSize(int[] objectIds, ISnapshot snapshot) throws SnapshotException

-    {

-        long sum = 0;

-        for (int id : objectIds)

-        {

-            sum += snapshot.getRetainedHeapSize(id);

-        }

-        return sum;

-    }

-

     /**

      * Find the accumulation point by big drops in the delta size

      * @param bigObjectId

diff --git a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/snapshot/inspections/CompareTablesQuery.java b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/snapshot/inspections/CompareTablesQuery.java
index 16231ae..d37150e 100644
--- a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/snapshot/inspections/CompareTablesQuery.java
+++ b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/snapshot/inspections/CompareTablesQuery.java
@@ -14,6 +14,7 @@
 import java.io.File;

 import java.io.FileReader;

 import java.io.IOException;

+import java.io.Serializable;

 import java.net.URISyntaxException;

 import java.net.URL;

 import java.text.FieldPosition;

@@ -1196,6 +1197,232 @@
         APPROX

     }

 

+    /**

+     * A class to format the difference between two retained sizes.

+     * Similar to {@link org.eclipse.mat.snapshot.query.RetainedSizeDerivedData.RetainedSizeFormat}.

+     * Sorting should use {@link Filter.ValueConverter} so that a dedicated comparator is

+     * not required. See {@link org.eclipse.mat.query.refined.RefinedStructuredResult.NaturalComparator}.

+     */

+    private static class DeltaRetainedBytesFormat extends BytesFormat

+    {

+        /**

+         * Converts a encoded stored value to a simple value, losing any

+         * approximation details.

+         */

+        private class DeltaRetainedConverter implements Filter.ValueConverter, Serializable

+        {

+            private static final long serialVersionUID = 1L;

+

+            public double convert(double source)

+            {

+                if (source >= SPECIAL + SPECIAL2)

+                    return source - SPECIAL - SPECIAL2; // +ve approx

+                else if (source >= SPECIAL)

+                    return source - SPECIAL2; // >=

+                else if (source < -SPECIAL - SPECIAL2)

+                    return source + SPECIAL + SPECIAL2; // -ve approx

+                else if (source < -SPECIAL)

+                    return source + SPECIAL2; // <=

+                return source;

+            }

+        }

+

+        /**

+         *

+         */

+        private static final long serialVersionUID = 1L;

+        /*

+         * encode >=, <= for +ve -ve byte values

+         * convert long to double for Filter.ValueConverter

+         * > 1,000,000,000,000,000 means >=

+         * <-1,000,000,000,000,000 means <=

+         * <-3,000,000,000,000,000 means ~

+         *

+         * e.g.

+         * ~=   : 39

+         * ~=3  : 33

+         * ~=0  : 30

+         * >=9  : 29

+         * >=3  : 23

+         * >=-3 : 17

+         * >=-10: 10

+         *

+         * <=9  : -11

+         * <=3  : -17

+         * <=-3 : -23

+         * <=-10: -30

+         *

+         * ~-3  : -33

+         * ~-9  : -39

+         */

+        /**

+         * Break point for special encoding.

+         * Chosen to be big, but to fit precisely in a double

+         * as well as a long.

+         */

+        private long SPECIAL = 1000000000000000L;

+        /**

+         * How much to adjust a value to move it into a different range.

+         */

+        private long SPECIAL2 = SPECIAL * 2;

+        /**

+         * Convert the encoded value to a normal value.

+         */

+        final Filter.ValueConverter converter = new DeltaRetainedConverter();

+

+        /**

+         * Encode a value as greater than or equal.

+         * @param l the raw value

+         * @return the encoded value

+         */

+        private long encodege(long l)

+        {

+            if (l >= SPECIAL)

+                return SPECIAL - 1 + SPECIAL2; // saturate

+            else if (l < -SPECIAL)

+                return encodeun(l); // can't be encoded as GE

+            else

+                return l + SPECIAL2;

+        }

+

+        /**

+         * Encode a value as less than or equal.

+         * @param l the raw value

+         * @return the encoded value

+         */

+        private long encodele(long l)

+        {

+            if (l >= SPECIAL)

+                return encodeun(l); // can't be coded as LE

+            else if (l < -SPECIAL)

+                return -SPECIAL - SPECIAL2; // saturate

+            else

+                return l - SPECIAL2;

+        }

+

+        /**

+         * Encode a value as inexact.

+         * @param l the raw value

+         * @return the encoded value

+         */

+        private long encodeun(long l)

+        {

+            if (l >= 0)

+                if (l >= Long.MAX_VALUE - SPECIAL - SPECIAL2)

+                    return Long.MAX_VALUE; // saturate

+                else

+                    return l + SPECIAL2 + SPECIAL;

+            else if (l <= Long.MIN_VALUE + SPECIAL + SPECIAL2)

+                return Long.MIN_VALUE; // saturate

+            else

+                return l - SPECIAL2 - SPECIAL;

+        }

+

+        /**

+         * Create a formatter for the difference between two retained sizes.

+         * @param encapsulatedNumberFormat

+         * @param encapsulatedDecimalFormat

+         */

+        public DeltaRetainedBytesFormat(Format encapsulatedNumberFormat, Format encapsulatedDecimalFormat)

+        {

+            super(encapsulatedNumberFormat, encapsulatedDecimalFormat);

+        }

+

+        @Override

+        public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos)

+        {

+            Number v;

+            if (obj instanceof Bytes)

+                v = ((Bytes)obj).getValue();

+            else

+                v = (Number) obj;

+

+

+            if (v.longValue() >= SPECIAL)

+            {

+                if (v.longValue() >= SPECIAL + SPECIAL2)

+                {

+                    String approx = Messages.CompareTablesQuery_APPROX;

+                    toAppendTo.append(approx);

+                    return super.format(new Bytes(v.longValue() - SPECIAL - SPECIAL2), toAppendTo, pos);

+                }

+                else

+                {

+                    String approx = Messages.CompareTablesQuery_GE;

+                    toAppendTo.append(approx);

+                    return super.format(new Bytes(v.longValue() - SPECIAL2), toAppendTo, pos);

+                }

+            }

+            else if (v.longValue() < -SPECIAL)

+            {

+                if (v.longValue() < -SPECIAL - SPECIAL2)

+                {

+                    String approx = Messages.CompareTablesQuery_APPROX;

+                    toAppendTo.append(approx);

+                    return super.format(new Bytes(v.longValue() + SPECIAL + SPECIAL2), toAppendTo, pos);

+                }

+                else

+                {

+                    String approx = Messages.CompareTablesQuery_LE;

+                    toAppendTo.append(approx);

+                    return super.format(new Bytes(v.longValue() + SPECIAL2), toAppendTo, pos);

+                }

+            }

+            else

+            {

+                return super.format(new Bytes(v.longValue()), toAppendTo, pos);

+            }

+        }

+

+        @Override

+        public Object parseObject(String source, ParsePosition pos)

+        {

+            Object ret;

+            for (String match : new String[] {Messages.CompareTablesQuery_GE, Messages.CompareTablesQuery_LE, Messages.CompareTablesQuery_APPROX})

+            {

+                if (source.regionMatches(pos.getIndex(), match, 0, match.length()))

+                {

+                    int pi = pos.getIndex();

+                    pos.setIndex(pi + match.length());

+                    ret = super.parseObject(source, pos);

+                    if (ret != null)

+                    {

+                        long v;

+                        if (ret instanceof Bytes)

+                        {

+                            v = ((Bytes)ret).getValue();

+                            if (match.equals(Messages.CompareTablesQuery_GE))

+                                v = encodege(v);

+                            else if (match.equals(Messages.CompareTablesQuery_LE))

+                                v = encodele(v);

+                            else if (match.equals(Messages.CompareTablesQuery_APPROX))

+                                v = encodeun(v);

+                            return new Bytes(v);

+                        }

+                        else if (ret instanceof Number)

+                        {

+                            v = ((Number)ret).longValue();

+                            if (match.equals(Messages.CompareTablesQuery_GE))

+                                v = encodege(v);

+                            else if (match.equals(Messages.CompareTablesQuery_LE))

+                                v = encodele(v);

+                            else if (match.equals(Messages.CompareTablesQuery_APPROX))

+                                v = encodeun(v);

+                            return new Bytes(v);

+                        }

+                    }

+                    // >= in front of something else

+                    pos.setErrorIndex(pi + match.length());

+                    pos.setIndex(pi);

+                    ret = null;

+                    return ret;

+                }

+            }

+            ret = super.parseObject(source, pos);

+            return ret;

+        }

+    }

+

     public class TableComparisonResult implements IStructuredResult, IIconProvider

     {

         private Column key;

@@ -2307,224 +2534,6 @@
             }

         }

 

-        /**

-         * A class to format the difference between two retained sizes.

-         * Similar to {@link org.eclipse.mat.snapshot.query.RetainedSizeDerivedData.RetainedSizeFormat}.

-         * Sorting should use {@link Filter.ValueConverter} so that a dedicated comparator is

-         * not required. See {@link org.eclipse.mat.query.refined.RefinedStructuredResult.NaturalComparator}.

-         */

-        private class DeltaRetainedBytesFormat extends BytesFormat

-        {

-            /**

-             *

-             */

-            private static final long serialVersionUID = 1L;

-            /*

-             * encode >=, <= for +ve -ve byte values

-             * convert long to double for Filter.ValueConverter

-             * > 1,000,000,000,000,000 means >=

-             * <-1,000,000,000,000,000 means <=

-             * <-3,000,000,000,000,000 means ~

-             *

-             * e.g.

-             * ~=   : 39

-             * ~=3  : 33

-             * ~=0  : 30

-             * >=9  : 29

-             * >=3  : 23

-             * >=-3 : 17

-             * >=-10: 10

-             *

-             * <=9  : -11

-             * <=3  : -17

-             * <=-3 : -23

-             * <=-10: -30

-             *

-             * ~-3  : -33

-             * ~-9  : -39

-             */

-            /**

-             * Break point for special encoding.

-             * Chosen to be big, but to fit precisely in a double

-             * as well as a long.

-             */

-            private long SPECIAL = 1000000000000000L;

-            /**

-             * How much to adjust a value to move it into a different range.

-             */

-            private long SPECIAL2 = SPECIAL * 2;

-            /**

-             * Convert the encoded value to a normal value.

-             */

-            final Filter.ValueConverter converter = new Filter.ValueConverter()

-            {

-                public double convert(double source)

-                {

-                    if (source >= SPECIAL + SPECIAL2)

-                        return source - SPECIAL - SPECIAL2; // +ve approx

-                    else if (source >= SPECIAL)

-                        return source - SPECIAL2; // >=

-                    else if (source < -SPECIAL - SPECIAL2)

-                        return source + SPECIAL + SPECIAL2; // -ve approx

-                    else if (source < -SPECIAL)

-                        return source + SPECIAL2; // <=

-                    return source;

-                }

-            };

-

-            /**

-             * Encode a value as greater than or equal.

-             * @param l the raw value

-             * @return the encoded value

-             */

-            private long encodege(long l)

-            {

-                if (l >= SPECIAL)

-                    return SPECIAL - 1 + SPECIAL2; // saturate

-                else if (l < -SPECIAL)

-                    return encodeun(l); // can't be encoded as GE

-                else

-                    return l + SPECIAL2;

-            }

-

-            /**

-             * Encode a value as less than or equal.

-             * @param l the raw value

-             * @return the encoded value

-             */

-            private long encodele(long l)

-            {

-                if (l >= SPECIAL)

-                    return encodeun(l); // can't be coded as LE

-                else if (l < -SPECIAL)

-                    return -SPECIAL - SPECIAL2; // saturate

-                else

-                    return l - SPECIAL2;

-            }

-

-            /**

-             * Encode a value as inexact.

-             * @param l the raw value

-             * @return the encoded value

-             */

-            private long encodeun(long l)

-            {

-                if (l >= 0)

-                    if (l >= Long.MAX_VALUE - SPECIAL - SPECIAL2)

-                        return Long.MAX_VALUE; // saturate

-                    else

-                        return l + SPECIAL2 + SPECIAL;

-                else if (l <= Long.MIN_VALUE + SPECIAL + SPECIAL2)

-                    return Long.MIN_VALUE; // saturate

-                else

-                    return l - SPECIAL2 - SPECIAL;

-            }

-

-            /**

-             * Create a formatter for the difference between two retained sizes.

-             * @param encapsulatedNumberFormat

-             * @param encapsulatedDecimalFormat

-             */

-            public DeltaRetainedBytesFormat(Format encapsulatedNumberFormat, Format encapsulatedDecimalFormat)

-            {

-                super(encapsulatedNumberFormat, encapsulatedDecimalFormat);

-            }

-

-            @Override

-            public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos)

-            {

-                Number v;

-                if (obj instanceof Bytes)

-                    v = ((Bytes)obj).getValue();

-                else

-                    v = (Number) obj;

-

-

-                if (v.longValue() >= SPECIAL)

-                {

-                    if (v.longValue() >= SPECIAL + SPECIAL2)

-                    {

-                        String approx = Messages.CompareTablesQuery_APPROX;

-                        toAppendTo.append(approx);

-                        return super.format(new Bytes(v.longValue() - SPECIAL - SPECIAL2), toAppendTo, pos);

-                    }

-                    else

-                    {

-                        String approx = Messages.CompareTablesQuery_GE;

-                        toAppendTo.append(approx);

-                        return super.format(new Bytes(v.longValue() - SPECIAL2), toAppendTo, pos);

-                    }

-                }

-                else if (v.longValue() < -SPECIAL)

-                {

-                    if (v.longValue() < -SPECIAL - SPECIAL2)

-                    {

-                        String approx = Messages.CompareTablesQuery_APPROX;

-                        toAppendTo.append(approx);

-                        return super.format(new Bytes(v.longValue() + SPECIAL + SPECIAL2), toAppendTo, pos);

-                    }

-                    else

-                    {

-                        String approx = Messages.CompareTablesQuery_LE;

-                        toAppendTo.append(approx);

-                        return super.format(new Bytes(v.longValue() + SPECIAL2), toAppendTo, pos);

-                    }

-                }

-                else

-                {

-                    return super.format(new Bytes(v.longValue()), toAppendTo, pos);

-                }

-            }

-

-            @Override

-            public Object parseObject(String source, ParsePosition pos)

-            {

-                Object ret;

-                for (String match : new String[] {Messages.CompareTablesQuery_GE, Messages.CompareTablesQuery_LE, Messages.CompareTablesQuery_APPROX})

-                {

-                    if (source.regionMatches(pos.getIndex(), match, 0, match.length()))

-                    {

-                        int pi = pos.getIndex();

-                        pos.setIndex(pi + match.length());

-                        ret = super.parseObject(source, pos);

-                        if (ret != null)

-                        {

-                            long v;

-                            if (ret instanceof Bytes)

-                            {

-                                v = ((Bytes)ret).getValue();

-                                if (match == Messages.CompareTablesQuery_GE)

-                                    v = encodege(v);

-                                else if (match == Messages.CompareTablesQuery_LE)

-                                    v = encodele(v);

-                                else if (match == Messages.CompareTablesQuery_APPROX)

-                                    v = encodeun(v);

-                                return new Bytes(v);

-                            }

-                            else if (ret instanceof Number)

-                            {

-                                v = ((Number)ret).longValue();

-                                if (match == Messages.CompareTablesQuery_GE)

-                                    v = encodege(v);

-                                else if (match == Messages.CompareTablesQuery_LE)

-                                    v = encodele(v);

-                                else if (match == Messages.CompareTablesQuery_APPROX)

-                                    v = encodeun(v);

-                                return new Bytes(v);

-                            }

-                        }

-                        // >= in front of something else

-                        pos.setErrorIndex(pi + match.length());

-                        pos.setIndex(pi);

-                        ret = null;

-                        return ret;

-                    }

-                }

-                ret = super.parseObject(source, pos);

-                return ret;

-            }

-        }

-

         private void setFormatter()

         {

             int i = 1;

diff --git a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/snapshot/inspections/MultiplePath2GCRootsQuery.java b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/snapshot/inspections/MultiplePath2GCRootsQuery.java
index c370881..6965390 100644
--- a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/snapshot/inspections/MultiplePath2GCRootsQuery.java
+++ b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/snapshot/inspections/MultiplePath2GCRootsQuery.java
@@ -323,6 +323,14 @@
             return distinctObjects;

         }

 

+        /**

+         * Simple equals to satisfy FindBugs.

+         */

+        @Override

+        public boolean equals(Object o)

+        {

+            return super.equals(o);

+        }

     }

 

     /* package */static class TreeByObject extends Tree implements IIconProvider, IDecorator

diff --git a/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/SnapshotImpl.java b/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/SnapshotImpl.java
index fd7fc4d..b8d85d1 100644
--- a/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/SnapshotImpl.java
+++ b/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/SnapshotImpl.java
@@ -1606,7 +1606,7 @@
      * Shouldn't really be needed as files should have finalizers,

      * but deleting indices does not work.

      */

-    public void finalize()

+    protected void finalize()

     {

         dispose();

     }

diff --git a/plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/snapshot/QueryLookupTest.java b/plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/snapshot/QueryLookupTest.java
index f7e3d8b..b972be7 100644
--- a/plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/snapshot/QueryLookupTest.java
+++ b/plugins/org.eclipse.mat.tests/src/org/eclipse/mat/tests/snapshot/QueryLookupTest.java
@@ -948,7 +948,7 @@
         for (ContextProvider cp : r2.getResultMetaData().getContextProviders())

         {

             //System.out.println(cp+ " " + cp.getLabel());

-            cp.getLabel();

+            assertNotNull(cp.getLabel());

             URL u = cp.getIcon();

             if (u != null)

             {