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 | */ |
6 | package org.h2.expression; |
7 | |
8 | import java.util.Arrays; |
9 | import java.util.Comparator; |
10 | import org.h2.engine.Constants; |
11 | import org.h2.engine.Database; |
12 | import org.h2.util.ValueHashMap; |
13 | import org.h2.value.CompareMode; |
14 | import org.h2.value.Value; |
15 | import org.h2.value.ValueArray; |
16 | import org.h2.value.ValueLong; |
17 | |
18 | /** |
19 | * Data stored while calculating a HISTOGRAM aggregate. |
20 | */ |
21 | class AggregateDataHistogram extends AggregateData { |
22 | private long count; |
23 | private ValueHashMap<AggregateDataHistogram> distinctValues; |
24 | |
25 | @Override |
26 | void add(Database database, int dataType, boolean distinct, Value v) { |
27 | if (distinctValues == null) { |
28 | distinctValues = ValueHashMap.newInstance(); |
29 | } |
30 | AggregateDataHistogram a = distinctValues.get(v); |
31 | if (a == null) { |
32 | if (distinctValues.size() < Constants.SELECTIVITY_DISTINCT_COUNT) { |
33 | a = new AggregateDataHistogram(); |
34 | distinctValues.put(v, a); |
35 | } |
36 | } |
37 | if (a != null) { |
38 | a.count++; |
39 | } |
40 | } |
41 | |
42 | @Override |
43 | Value getValue(Database database, int dataType, boolean distinct) { |
44 | if (distinct) { |
45 | count = 0; |
46 | groupDistinct(database, dataType); |
47 | } |
48 | ValueArray[] values = new ValueArray[distinctValues.size()]; |
49 | int i = 0; |
50 | for (Value dv : distinctValues.keys()) { |
51 | AggregateDataHistogram d = distinctValues.get(dv); |
52 | values[i] = ValueArray.get(new Value[] { dv, ValueLong.get(d.count) }); |
53 | i++; |
54 | } |
55 | final CompareMode compareMode = database.getCompareMode(); |
56 | Arrays.sort(values, new Comparator<ValueArray>() { |
57 | @Override |
58 | public int compare(ValueArray v1, ValueArray v2) { |
59 | Value a1 = v1.getList()[0]; |
60 | Value a2 = v2.getList()[0]; |
61 | return a1.compareTo(a2, compareMode); |
62 | } |
63 | }); |
64 | Value v = ValueArray.get(values); |
65 | return v.convertTo(dataType); |
66 | } |
67 | |
68 | private void groupDistinct(Database database, int dataType) { |
69 | if (distinctValues == null) { |
70 | return; |
71 | } |
72 | count = 0; |
73 | for (Value v : distinctValues.keys()) { |
74 | add(database, dataType, false, v); |
75 | } |
76 | } |
77 | |
78 | } |