提交 aab00fa3 authored 作者: Thomas Mueller's avatar Thomas Mueller

Formatting / javadocs

上级 ccf8ee20
...@@ -218,8 +218,7 @@ public class SetTypes { ...@@ -218,8 +218,7 @@ public class SetTypes {
* The type of a SET QUERY_STATISTICS_ACTIVE statement. * The type of a SET QUERY_STATISTICS_ACTIVE statement.
*/ */
public static final int QUERY_STATISTICS = 41; public static final int QUERY_STATISTICS = 41;
private static final ArrayList<String> TYPES = New.arrayList(); private static final ArrayList<String> TYPES = New.arrayList();
private SetTypes() { private SetTypes() {
......
...@@ -2094,7 +2094,7 @@ public class Database implements DataHandler { ...@@ -2094,7 +2094,7 @@ public class Database implements DataHandler {
public boolean getQueryStatistics() { public boolean getQueryStatistics() {
return queryStatistics; return queryStatistics;
} }
public QueryStatisticsData getQueryStatisticsData() { public QueryStatisticsData getQueryStatisticsData() {
if (!queryStatistics) { if (!queryStatistics) {
return null; return null;
...@@ -2108,7 +2108,7 @@ public class Database implements DataHandler { ...@@ -2108,7 +2108,7 @@ public class Database implements DataHandler {
} }
return queryStatisticsData; return queryStatisticsData;
} }
/** /**
* Check if the database is currently opening. This is true until all stored * Check if the database is currently opening. This is true until all stored
* SQL statements have been executed. * SQL statements have been executed.
......
/* /*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License, * Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0 * Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html). * (http://h2database.com/html/license.html).
* Initial Developer: H2 Group * Initial Developer: H2 Group
*/ */
package org.h2.engine; package org.h2.engine;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map.Entry;
/** /**
* Maintains query statistics. * Maintains query statistics.
*/ */
public class QueryStatisticsData { public class QueryStatisticsData {
private static final int MAX_QUERY_ENTRIES = 100; private static final int MAX_QUERY_ENTRIES = 100;
private static final Comparator<QueryEntry> QUERY_ENTRY_COMPARATOR = new Comparator<QueryEntry>() { private static final Comparator<QueryEntry> QUERY_ENTRY_COMPARATOR = new Comparator<QueryEntry>() {
@Override @Override
public int compare(QueryEntry o1, QueryEntry o2) { public int compare(QueryEntry o1, QueryEntry o2) {
return (int) Math.signum(o1.lastUpdateTime - o2.lastUpdateTime); return (int) Math.signum(o1.lastUpdateTime - o2.lastUpdateTime);
} }
}; };
private final HashMap<String, QueryEntry> map = new HashMap<String, QueryEntry>(); private final HashMap<String, QueryEntry> map = new HashMap<String, QueryEntry>();
public synchronized List<QueryEntry> getQueries() { public synchronized List<QueryEntry> getQueries() {
// return a copy of the map so we don't have to worry about external synchronization // return a copy of the map so we don't have to
ArrayList<QueryEntry> list = new ArrayList<QueryEntry>(); // worry about external synchronization
list.addAll(map.values()); ArrayList<QueryEntry> list = new ArrayList<QueryEntry>();
// only return the newest 100 entries list.addAll(map.values());
Collections.sort(list, QUERY_ENTRY_COMPARATOR); // only return the newest 100 entries
return list.subList(0, Math.min(list.size(), MAX_QUERY_ENTRIES)); Collections.sort(list, QUERY_ENTRY_COMPARATOR);
} return list.subList(0, Math.min(list.size(), MAX_QUERY_ENTRIES));
}
/**
* Update query statistics. /**
* * Update query statistics.
* @param sqlStatement the statement being executed *
* @param executionTime the time in milliseconds the query/update took to execute * @param sqlStatement the statement being executed
* @param rowCount the query or update row count * @param executionTime the time in milliseconds the query/update took to execute
*/ * @param rowCount the query or update row count
public synchronized void update(String sqlStatement, long executionTime, int rowCount) { */
QueryEntry entry = map.get(sqlStatement); public synchronized void update(String sqlStatement, long executionTime, int rowCount) {
if (entry == null) { QueryEntry entry = map.get(sqlStatement);
entry = new QueryEntry(); if (entry == null) {
entry.sqlStatement = sqlStatement; entry = new QueryEntry();
entry.executionTimeMin = executionTime; map.put(sqlStatement, entry);
entry.executionTimeMax = executionTime; }
entry.rowCountMin = rowCount; entry.update(executionTime, rowCount);
entry.rowCountMax = rowCount;
entry.executionTimeMean = executionTime; // Age-out the oldest entries if the map gets too big.
entry.rowCountMean = rowCount; // Test against 1.5 x max-size so we don't do this too often
map.put(sqlStatement, entry); if (map.size() > MAX_QUERY_ENTRIES * 1.5f) {
} else { // Sort the entries by age
entry.count++; ArrayList<QueryEntry> list = new ArrayList<QueryEntry>();
entry.executionTimeMin = Math.min(executionTime, entry.executionTimeMin); list.addAll(map.values());
entry.executionTimeMax = Math.max(executionTime, entry.executionTimeMax); Collections.sort(list, QUERY_ENTRY_COMPARATOR);
entry.rowCountMin = Math.min(rowCount, entry.rowCountMin); // Create a set of the oldest 1/3 of the entries
entry.rowCountMax = Math.max(rowCount, entry.rowCountMax); HashSet<QueryEntry> oldestSet = new HashSet<QueryEntry>(list.subList(0, list.size() / 3));
// Loop over the map using the set and remove
double delta = rowCount - entry.rowCountMean; // the oldest 1/3 of the entries.
entry.rowCountMean += delta / entry.count; for (Iterator<Entry<String, QueryEntry>> it = map.entrySet().iterator(); it.hasNext();) {
entry.rowCountM2 += delta * (rowCount - entry.rowCountMean); Entry<String, QueryEntry> mapEntry = it.next();
if (oldestSet.contains(mapEntry.getValue())) {
delta = executionTime - entry.executionTimeMean; it.remove();
entry.executionTimeMean += delta / entry.count; }
entry.executionTimeM2 += delta * (executionTime - entry.executionTimeMean); }
} }
entry.executionTimeCumulative += executionTime; }
entry.rowCountCumulative += rowCount;
entry.lastUpdateTime = System.currentTimeMillis(); /**
* The collected statistics for one query.
// Age-out the oldest entries if the map gets too big. */
// Test against 1.5 x max-size so we don't do this too often public static final class QueryEntry {
if (map.size() > MAX_QUERY_ENTRIES * 1.5f) {
// Sort the entries by age /**
ArrayList<QueryEntry> list = new ArrayList<QueryEntry>(); * The SQL statement.
list.addAll(map.values()); */
Collections.sort(list, QUERY_ENTRY_COMPARATOR); public String sqlStatement;
// Create a set of the oldest 1/3 of the entries
HashSet<QueryEntry> oldestSet = new HashSet<QueryEntry>(list.subList(0, list.size() / 3)); /**
// Loop over the map using the set and remove the oldest 1/3 of the * The number of times the statement was executed.
// entries. */
for (Iterator<Map.Entry<String, QueryEntry>> iter = map.entrySet().iterator(); iter.hasNext();) { public int count;
Map.Entry<String, QueryEntry> mapEntry = iter.next();
if (oldestSet.contains(mapEntry.getValue())) { /**
iter.remove(); * The last time the statistics for this entry were updated,
} * in milliseconds since 1970.
} */
} public long lastUpdateTime;
}
/**
/** * The minimum execution time, in milliseconds.
* The collected statistics for one query. */
*/ public long executionTimeMin;
public static final class QueryEntry {
/**
public String sqlStatement; * The maximum execution time, in milliseconds.
*/
public int count = 1; public long executionTimeMax;
public long lastUpdateTime;
public long executionTimeMin; /**
public long executionTimeMax; * The total execution time.
public long executionTimeCumulative; */
public int rowCountMin; public long executionTimeCumulative;
public int rowCountMax;
public long rowCountCumulative; /**
* The minimum number of rows.
// Using Welford's method, see also */
// http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance public int rowCountMin;
// http://www.johndcook.com/standard_deviation.html
public double executionTimeMean; /**
public double executionTimeM2; * The maximum number of rows.
public double rowCountMean; */
public double rowCountM2; public int rowCountMax;
public double getExecutionTimeStandardDeviation() { /**
// population standard deviation * The total number of rows.
return Math.sqrt(executionTimeM2 / count); */
} public long rowCountCumulative;
public double getRowCountStandardDeviation() { /**
// population standard deviation * The mean execution time.
return Math.sqrt(rowCountM2 / count); */
} public double executionTimeMean;
} /**
* The mean number of rows.
} */
public double rowCountMean;
// Using Welford's method, see also
// http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
// http://www.johndcook.com/standard_deviation.html
private double executionTimeM2;
private double rowCountM2;
/**
* Update the statistics entry.
*
* @param time the execution time
* @param rows the number of rows
*/
void update(long time, int rows) {
count++;
executionTimeMin = Math.min(time, executionTimeMin);
executionTimeMax = Math.max(time, executionTimeMax);
rowCountMin = Math.min(rows, rowCountMin);
rowCountMax = Math.max(rows, rowCountMax);
double delta = rows - rowCountMean;
rowCountMean += delta / count;
rowCountM2 += delta * (rows - rowCountMean);
delta = time - executionTimeMean;
executionTimeMean += delta / count;
executionTimeM2 += delta * (time - executionTimeMean);
executionTimeCumulative += time;
rowCountCumulative += rows;
lastUpdateTime = System.currentTimeMillis();
}
public double getExecutionTimeStandardDeviation() {
// population standard deviation
return Math.sqrt(executionTimeM2 / count);
}
public double getRowCountStandardDeviation() {
// population standard deviation
return Math.sqrt(rowCountM2 / count);
}
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论