2015-10-15 5:28 GMT+09:00 <fschumac...@apache.org>:

> Author: fschumacher
> Date: Wed Oct 14 20:28:55 2015
> New Revision: 1708687
>
> URL: http://svn.apache.org/viewvc?rev=1708687&view=rev
> Log:
> Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=58489
>
> Comparator should follow the rules. If first object has lastInvocation of
> zero,
> we should compare it to the second objects lastInvocation and vice versa.
> When we do that, we can use Long#compare just as well.
>
> Added:
>
> tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/TestSlowQueryComparator.java
> Modified:
>
> tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReport.java
>
> Modified:
> tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReport.java
> URL:
> http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReport.java?rev=1708687&r1=1708686&r2=1708687&view=diff
>
> ==============================================================================
> ---
> tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReport.java
> (original)
> +++
> tomcat/trunk/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/interceptor/SlowQueryReport.java
> Wed Oct 14 20:28:55 2015
> @@ -475,17 +475,7 @@ public class SlowQueryReport extends Abs
>
>          @Override
>          public int compare(QueryStats stats1, QueryStats stats2) {
> -            if (stats1.lastInvocation == 0) return 1;
> -            if (stats2.lastInvocation == 0) return -1;
> -
> -            long result = stats1.lastInvocation - stats2.lastInvocation;
> -            if (result > 0) {
> -                return 1;
> -            } else if (result == 0) {
> -                return 0;
> -            } else {
> -                return -1;
> -            }
> +            return Long.compare(stats1.lastInvocation,
> stats2.lastInvocation);
>          }
>      }
>
>

Hi.

I think this fix does not handle 0 value of lastInvocation correctly.
The older code handles 0 value of lastInvocation as the latest QueryStats.
This new code handles 0 value of lastInvocation as the oldest QueryStats.

I think the fix of this bug is described in comment1.
Or set current time to the lastInvocation in the constructor of QueryStats.





>
> Added:
> tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/TestSlowQueryComparator.java
> URL:
> http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/TestSlowQueryComparator.java?rev=1708687&view=auto
>
> ==============================================================================
> ---
> tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/TestSlowQueryComparator.java
> (added)
> +++
> tomcat/trunk/modules/jdbc-pool/src/test/java/org/apache/tomcat/jdbc/test/TestSlowQueryComparator.java
> Wed Oct 14 20:28:55 2015
> @@ -0,0 +1,121 @@
> +package org.apache.tomcat.jdbc.test;
> +
> +import java.lang.reflect.Constructor;
> +import java.lang.reflect.InvocationTargetException;
> +import java.util.ArrayList;
> +import java.util.Collections;
> +import java.util.Comparator;
> +import java.util.List;
> +
> +import org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReport.QueryStats;
> +import org.junit.Assert;
> +import org.junit.Test;
> +
> +public class TestSlowQueryComparator {
> +
> +    @Test
> +    public void testBug58489() throws ClassNotFoundException,
> +            InstantiationException, IllegalAccessException,
> +            InvocationTargetException {
> +
> +        long[] testData = { 0, 0, 0, 1444225382010l, 0, 1444225382011l, 0,
> +                1444225382012l, 0, 1444225382056l, 0, 1444225382014l, 0,
> +                1444225382015l, 0, 1444225382016l, 0, 0, 1444225382017l,
> 0,
> +                1444225678350l, 0, 1444225680397l, 0, 1444225382018l,
> +                1444225382019l, 1444225382020l, 0, 1444225382021l, 0,
> +                1444225382022l, 1444225382023l
> +
> +        };
> +
> +        List<QueryStats> stats = new ArrayList<>();
> +
> +        for (int i = 0; i < testData.length; i++) {
> +            QueryStats qs = new QueryStats(String.valueOf(i));
> +            qs.add(0, testData[i]);
> +            stats.add(qs);
> +        }
> +
> +        try {
> +            Collections.sort(stats, createComparator());
> +        } catch (IllegalArgumentException e) {
> +            Assert.fail(e.getMessage());
> +        }
> +    }
> +
> +    @Test
> +    public void testEqualQueryStatsWithNoLastInvocation()
> +            throws ClassNotFoundException, InstantiationException,
> +            IllegalAccessException, IllegalArgumentException,
> +            InvocationTargetException {
> +        Comparator<QueryStats> queryStatsComparator = createComparator();
> +        QueryStats q1 = new QueryStats("abc");
> +        Assert.assertEquals(0, queryStatsComparator.compare(q1, q1));
> +    }
> +
> +    @Test
> +    public void testEqualQueryStatsWithLastInvocation()
> +            throws ClassNotFoundException, InstantiationException,
> +            IllegalAccessException, IllegalArgumentException,
> +            InvocationTargetException {
> +        Comparator<QueryStats> queryStatsComparator = createComparator();
> +        QueryStats q1 = new QueryStats("abc");
> +        q1.add(0, 100);
> +        Assert.assertEquals(0, queryStatsComparator.compare(q1, q1));
> +    }
> +
> +    @Test
> +    public void testQueryStatsOneWithLastInvocation()
> +            throws ClassNotFoundException, InstantiationException,
> +            IllegalAccessException, IllegalArgumentException,
> +            InvocationTargetException {
> +        Comparator<QueryStats> queryStatsComparator = createComparator();
> +        QueryStats q1 = new QueryStats("abc");
> +        QueryStats q2 = new QueryStats("def");
> +        q2.add(0, 100);
> +        Assert.assertEquals(-1, queryStatsComparator.compare(q1, q2));
> +        Assert.assertEquals(1, queryStatsComparator.compare(q2, q1));
> +    }
> +
> +    @Test
> +    public void testQueryStatsBothWithSameLastInvocation()
> +            throws ClassNotFoundException, InstantiationException,
> +            IllegalAccessException, IllegalArgumentException,
> +            InvocationTargetException {
> +        Comparator<QueryStats> queryStatsComparator = createComparator();
> +        QueryStats q1 = new QueryStats("abc");
> +        QueryStats q2 = new QueryStats("def");
> +        q1.add(0, 100);
> +        q2.add(0, 100);
> +        Assert.assertEquals(0, queryStatsComparator.compare(q1, q2));
> +        Assert.assertEquals(0, queryStatsComparator.compare(q2, q1));
> +    }
> +
> +    @Test
> +    public void testQueryStatsBothWithSomeLastInvocation()
> +            throws ClassNotFoundException, InstantiationException,
> +            IllegalAccessException, IllegalArgumentException,
> +            InvocationTargetException {
> +        Comparator<QueryStats> queryStatsComparator = createComparator();
> +        QueryStats q1 = new QueryStats("abc");
> +        QueryStats q2 = new QueryStats("abc");
> +        q1.add(0, 100);
> +        q2.add(0, 150);
> +        Assert.assertEquals(-1, queryStatsComparator.compare(q1, q2));
> +        Assert.assertEquals(1, queryStatsComparator.compare(q2, q1));
> +    }
> +
> +    private Comparator<QueryStats> createComparator()
> +            throws ClassNotFoundException, InstantiationException,
> +            IllegalAccessException, InvocationTargetException {
> +        Class<?> comparatorClass = Class
> +
> .forName("org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReport$QueryStatsComparator");
> +        Constructor<?> comparatorConstructor = comparatorClass
> +                .getDeclaredConstructors()[1];
> +        comparatorConstructor.setAccessible(true);
> +        @SuppressWarnings("unchecked")
> +        Comparator<QueryStats> queryStatsComparator =
> (Comparator<QueryStats>) comparatorConstructor
> +                .newInstance();
> +        return queryStatsComparator;
> +    }
> +
> +}
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: dev-h...@tomcat.apache.org
>
> --
> Keiichi.Fujino
> <dev-h...@tomcat.apache.org>

<dev-h...@tomcat.apache.org>

Reply via email to