EMMA Coverage Report (generated Sun Mar 01 22:06:14 CET 2015)
[all classes][org.h2.engine]

COVERAGE SUMMARY FOR SOURCE FILE [QueryStatisticsData.java]

nameclass, %method, %block, %line, %
QueryStatisticsData.java100% (3/3)100% (10/10)82%  (201/245)78%  (35/45)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class QueryStatisticsData100% (1/1)100% (4/4)60%  (67/111)62%  (16/26)
update (String, long, int): void 100% (1/1)43%  (33/77)44%  (8/18)
<static initializer> 100% (1/1)100% (5/5)100% (1/1)
QueryStatisticsData (): void 100% (1/1)100% (8/8)100% (3/3)
getQueries (): List 100% (1/1)100% (21/21)100% (4/4)
     
class QueryStatisticsData$1100% (1/1)100% (2/2)100% (12/12)100% (2/2)
QueryStatisticsData$1 (): void 100% (1/1)100% (3/3)100% (1/1)
compare (QueryStatisticsData$QueryEntry, QueryStatisticsData$QueryEntry): int 100% (1/1)100% (9/9)100% (1/1)
     
class QueryStatisticsData$QueryEntry100% (1/1)100% (4/4)100% (122/122)100% (18/18)
QueryStatisticsData$QueryEntry (): void 100% (1/1)100% (3/3)100% (1/1)
getExecutionTimeStandardDeviation (): double 100% (1/1)100% (8/8)100% (1/1)
getRowCountStandardDeviation (): double 100% (1/1)100% (8/8)100% (1/1)
update (long, int): void 100% (1/1)100% (103/103)100% (15/15)

1/*
2 * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
3 * and the EPL 1.0 (http://h2database.com/html/license.html).
4 * Initial Developer: H2 Group
5 */
6package org.h2.engine;
7 
8import java.util.ArrayList;
9import java.util.Collections;
10import java.util.Comparator;
11import java.util.HashMap;
12import java.util.HashSet;
13import java.util.Iterator;
14import java.util.List;
15import java.util.Map.Entry;
16 
17/**
18 * Maintains query statistics.
19 */
20public class QueryStatisticsData {
21 
22    private static final int MAX_QUERY_ENTRIES = 100;
23 
24    private static final Comparator<QueryEntry> QUERY_ENTRY_COMPARATOR =
25            new Comparator<QueryEntry>() {
26        @Override
27        public int compare(QueryEntry o1, QueryEntry o2) {
28            return (int) Math.signum(o1.lastUpdateTime - o2.lastUpdateTime);
29        }
30    };
31 
32    private final HashMap<String, QueryEntry> map =
33            new HashMap<String, QueryEntry>();
34 
35    public synchronized List<QueryEntry> getQueries() {
36        // return a copy of the map so we don't have to
37        // worry about external synchronization
38        ArrayList<QueryEntry> list = new ArrayList<QueryEntry>();
39        list.addAll(map.values());
40        // only return the newest 100 entries
41        Collections.sort(list, QUERY_ENTRY_COMPARATOR);
42        return list.subList(0, Math.min(list.size(), MAX_QUERY_ENTRIES));
43    }
44 
45    /**
46     * Update query statistics.
47     *
48     * @param sqlStatement the statement being executed
49     * @param executionTime the time in milliseconds the query/update took to
50     *            execute
51     * @param rowCount the query or update row count
52     */
53    public synchronized void update(String sqlStatement, long executionTime,
54            int rowCount) {
55        QueryEntry entry = map.get(sqlStatement);
56        if (entry == null) {
57            entry = new QueryEntry();
58            entry.sqlStatement = sqlStatement;
59            map.put(sqlStatement, entry);
60        }
61        entry.update(executionTime, rowCount);
62 
63        // Age-out the oldest entries if the map gets too big.
64        // Test against 1.5 x max-size so we don't do this too often
65        if (map.size() > MAX_QUERY_ENTRIES * 1.5f) {
66            // Sort the entries by age
67            ArrayList<QueryEntry> list = new ArrayList<QueryEntry>();
68            list.addAll(map.values());
69            Collections.sort(list, QUERY_ENTRY_COMPARATOR);
70            // Create a set of the oldest 1/3 of the entries
71            HashSet<QueryEntry> oldestSet =
72                    new HashSet<QueryEntry>(list.subList(0, list.size() / 3));
73            // Loop over the map using the set and remove
74            // the oldest 1/3 of the entries.
75            for (Iterator<Entry<String, QueryEntry>> it =
76                    map.entrySet().iterator(); it.hasNext();) {
77                Entry<String, QueryEntry> mapEntry = it.next();
78                if (oldestSet.contains(mapEntry.getValue())) {
79                    it.remove();
80                }
81            }
82        }
83    }
84 
85    /**
86     * The collected statistics for one query.
87     */
88    public static final class QueryEntry {
89 
90        /**
91         * The SQL statement.
92         */
93        public String sqlStatement;
94 
95        /**
96         * The number of times the statement was executed.
97         */
98        public int count;
99 
100        /**
101         * The last time the statistics for this entry were updated,
102         * in milliseconds since 1970.
103         */
104        public long lastUpdateTime;
105 
106        /**
107         * The minimum execution time, in milliseconds.
108         */
109        public long executionTimeMin;
110 
111        /**
112         * The maximum execution time, in milliseconds.
113         */
114        public long executionTimeMax;
115 
116        /**
117         * The total execution time.
118         */
119        public long executionTimeCumulative;
120 
121        /**
122         * The minimum number of rows.
123         */
124        public int rowCountMin;
125 
126        /**
127         * The maximum number of rows.
128         */
129        public int rowCountMax;
130 
131        /**
132         * The total number of rows.
133         */
134        public long rowCountCumulative;
135 
136        /**
137         * The mean execution time.
138         */
139        public double executionTimeMean;
140 
141        /**
142         * The mean number of rows.
143         */
144        public double rowCountMean;
145 
146        // Using Welford's method, see also
147        // http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
148        // http://www.johndcook.com/standard_deviation.html
149 
150        private double executionTimeM2;
151        private double rowCountM2;
152 
153        /**
154         * Update the statistics entry.
155         *
156         * @param time the execution time
157         * @param rows the number of rows
158         */
159        void update(long time, int rows) {
160            count++;
161            executionTimeMin = Math.min(time, executionTimeMin);
162            executionTimeMax = Math.max(time, executionTimeMax);
163            rowCountMin = Math.min(rows, rowCountMin);
164            rowCountMax = Math.max(rows, rowCountMax);
165 
166            double delta = rows - rowCountMean;
167            rowCountMean += delta / count;
168            rowCountM2 += delta * (rows - rowCountMean);
169 
170            delta = time - executionTimeMean;
171            executionTimeMean += delta / count;
172            executionTimeM2 += delta * (time - executionTimeMean);
173 
174            executionTimeCumulative += time;
175            rowCountCumulative += rows;
176            lastUpdateTime = System.currentTimeMillis();
177 
178        }
179 
180        public double getExecutionTimeStandardDeviation() {
181            // population standard deviation
182            return Math.sqrt(executionTimeM2 / count);
183        }
184 
185        public double getRowCountStandardDeviation() {
186            // population standard deviation
187            return Math.sqrt(rowCountM2 / count);
188        }
189 
190    }
191 
192}

[all classes][org.h2.engine]
EMMA 2.0.5312 (C) Vladimir Roubtsov