提交 674102df authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Do not use hash-based collections in aggregates

上级 6ae17fc2
......@@ -10,6 +10,7 @@ import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.TreeMap;
import org.h2.api.ErrorCode;
import org.h2.command.dml.Select;
import org.h2.command.dml.SelectOrderBy;
......@@ -32,7 +33,6 @@ import org.h2.table.ColumnResolver;
import org.h2.table.Table;
import org.h2.table.TableFilter;
import org.h2.util.StatementBuilder;
import org.h2.util.ValueHashMap;
import org.h2.value.CompareMode;
import org.h2.value.DataType;
import org.h2.value.TypeInfo;
......@@ -512,13 +512,13 @@ public class Aggregate extends AbstractAggregate {
}
private Value getHistogram(Session session, AggregateData data) {
ValueHashMap<LongDataCounter> distinctValues = ((AggregateDataDistinctWithCounts) data).getValues();
TreeMap<Value, LongDataCounter> distinctValues = ((AggregateDataDistinctWithCounts) data).getValues();
if (distinctValues == null) {
return ValueArray.getEmpty();
}
ValueArray[] values = new ValueArray[distinctValues.size()];
int i = 0;
for (Entry<Value, LongDataCounter> entry : distinctValues.entries()) {
for (Entry<Value, LongDataCounter> entry : distinctValues.entrySet()) {
LongDataCounter d = entry.getValue();
values[i] = ValueArray.get(new Value[] { entry.getKey(), ValueLong.get(distinct ? 1L : d.count) });
i++;
......@@ -539,14 +539,14 @@ public class Aggregate extends AbstractAggregate {
private Value getMode(Session session, AggregateData data) {
Value v = ValueNull.INSTANCE;
ValueHashMap<LongDataCounter> distinctValues = ((AggregateDataDistinctWithCounts) data).getValues();
TreeMap<Value, LongDataCounter> distinctValues = ((AggregateDataDistinctWithCounts) data).getValues();
if (distinctValues == null) {
return v;
}
long count = 0L;
if (orderByList != null) {
boolean desc = (orderByList.get(0).sortType & SortOrder.DESCENDING) != 0;
for (Entry<Value, LongDataCounter> entry : distinctValues.entries()) {
for (Entry<Value, LongDataCounter> entry : distinctValues.entrySet()) {
long c = entry.getValue().count;
if (c > count) {
v = entry.getKey();
......@@ -565,7 +565,7 @@ public class Aggregate extends AbstractAggregate {
}
}
} else {
for (Entry<Value, LongDataCounter> entry : distinctValues.entries()) {
for (Entry<Value, LongDataCounter> entry : distinctValues.entrySet()) {
long c = entry.getValue().count;
if (c > count) {
v = entry.getKey();
......
......@@ -8,8 +8,8 @@ package org.h2.expression.aggregate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.TreeSet;
import org.h2.engine.Database;
import org.h2.value.Value;
......@@ -47,7 +47,7 @@ class AggregateDataCollecting extends AggregateData implements Iterable<Value> {
}
Collection<Value> c = values;
if (c == null) {
values = c = distinct ? new HashSet<Value>() : new ArrayList<Value>();
values = c = distinct ? new TreeSet<>(database.getCompareMode()) : new ArrayList<Value>();
}
c.add(v);
}
......
......@@ -5,8 +5,8 @@
*/
package org.h2.expression.aggregate;
import java.util.TreeMap;
import org.h2.engine.Database;
import org.h2.util.ValueHashMap;
import org.h2.value.Value;
import org.h2.value.ValueNull;
......@@ -20,7 +20,7 @@ class AggregateDataDistinctWithCounts extends AggregateData {
private final int maxDistinctCount;
private ValueHashMap<LongDataCounter> values;
private TreeMap<Value, LongDataCounter> values;
/**
* Creates new instance of data for aggregate that needs distinct values
......@@ -42,7 +42,7 @@ class AggregateDataDistinctWithCounts extends AggregateData {
return;
}
if (values == null) {
values = new ValueHashMap<>();
values = new TreeMap<>(database.getCompareMode());
}
LongDataCounter a = values.get(v);
if (a == null) {
......@@ -65,7 +65,7 @@ class AggregateDataDistinctWithCounts extends AggregateData {
*
* @return map with values and their counts
*/
ValueHashMap<LongDataCounter> getValues() {
TreeMap<Value, LongDataCounter> getValues() {
return values;
}
......
......@@ -104,3 +104,18 @@ SELECT X, COUNT(*) OVER (ORDER BY X) C FROM VALUES (1), (1), (2), (2), (3) V(X);
> 2 4
> 3 5
> rows: 5
CREATE TABLE TEST (N NUMERIC) AS VALUES (0), (0.0), (NULL);
> ok
SELECT COUNT(*) FROM TEST;
>> 3
SELECT COUNT(N) FROM TEST;
>> 2
SELECT COUNT(DISTINCT N) FROM TEST;
>> 1
DROP TABLE TEST;
> ok
......@@ -57,3 +57,12 @@ SELECT MODE() WITHIN GROUP(ORDER BY V DESC) FROM TEST;
DROP TABLE TEST;
> ok
CREATE TABLE TEST (N NUMERIC) AS VALUES (0), (0.0), (NULL);
> ok
SELECT MODE(N) FROM TEST;
>> 0
DROP TABLE TEST;
> ok
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论