This is an automated email from the ASF dual-hosted git repository.
amatya pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new 67f45fa7bfc Fix histograms for sketches where min and max are equal
(#15381)
67f45fa7bfc is described below
commit 67f45fa7bfc5eeb17e9ff23b3519fb01520a8360
Author: Magnus Henoch <[email protected]>
AuthorDate: Thu Nov 16 07:01:22 2023 +0000
Fix histograms for sketches where min and max are equal (#15381)
There is a problem with Quantiles sketches and KLL Quantiles sketches.
Queries using the histogram post-aggregator fail if:
- the sketch contains at least one value, and
- the values in the sketch are all equal, and
- the splitPoints argument is not passed to the post-aggregator, and
- the numBins argument is greater than 2 (or not specified, which
leads to the default of 10 being used)
In that case, the query fails and returns this error:
{
"error": "Unknown exception",
"errorClass":
"org.apache.datasketches.common.SketchesArgumentException",
"host": null,
"errorCode": "legacyQueryException",
"persona": "OPERATOR",
"category": "RUNTIME_FAILURE",
"errorMessage": "Values must be unique, monotonically increasing and
not NaN.",
"context": {
"host": null,
"errorClass":
"org.apache.datasketches.common.SketchesArgumentException",
"legacyErrorCode": "Unknown exception"
}
}
This behaviour is undesirable, since the caller doesn't necessarily
know in advance whether the sketch has values that are diverse
enough. With this change, the post-aggregators return [N, 0, 0...]
instead of crashing, where N is the number of values in the sketch,
and the length of the list is equal to numBins. That is what they
already returned for numBins = 2.
Here is an example of a query that would fail:
{"queryType":"timeseries",
"dataSource": {
"type": "inline",
"columnNames": ["foo", "bar"],
"rows": [
["abc", 42.0],
["def", 42.0]
]
},
"intervals":["0000/3000"],
"granularity":"all",
"aggregations":[
{"name":"the_sketch", "fieldName":"bar",
"type":"quantilesDoublesSketch"}],
"postAggregations":[
{"name":"the_histogram",
"type":"quantilesDoublesSketchToHistogram",
"field":{"type":"fieldAccess","fieldName":"the_sketch"},
"numBins": 3}]}
I believe this also fixes issue #10585.
---
.../KllDoublesSketchToHistogramPostAggregator.java | 21 ++-
.../KllFloatsSketchToHistogramPostAggregator.java | 21 ++-
.../DoublesSketchToHistogramPostAggregator.java | 21 ++-
...DoublesSketchToHistogramPostAggregatorTest.java | 152 +++++++++++++++++++++
...lFloatsSketchToHistogramPostAggregatorTest.java | 152 +++++++++++++++++++++
...DoublesSketchToHistogramPostAggregatorTest.java | 152 +++++++++++++++++++++
6 files changed, 510 insertions(+), 9 deletions(-)
diff --git
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/kll/KllDoublesSketchToHistogramPostAggregator.java
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/kll/KllDoublesSketchToHistogramPostAggregator.java
index 90a295e7e8a..54a0022cfac 100644
---
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/kll/KllDoublesSketchToHistogramPostAggregator.java
+++
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/kll/KllDoublesSketchToHistogramPostAggregator.java
@@ -67,7 +67,7 @@ public class KllDoublesSketchToHistogramPostAggregator
implements PostAggregator
public Object compute(final Map<String, Object> combinedAggregators)
{
final KllDoublesSketch sketch = (KllDoublesSketch)
field.compute(combinedAggregators);
- final int numBins = splitPoints != null ? splitPoints.length + 1 :
+ final int numBins = this.splitPoints != null ? this.splitPoints.length + 1
:
(this.numBins != null ? this.numBins.intValue() : DEFAULT_NUM_BINS);
if (numBins < 2) {
throw new IAE("at least 2 bins expected");
@@ -77,8 +77,23 @@ public class KllDoublesSketchToHistogramPostAggregator
implements PostAggregator
Arrays.fill(histogram, Double.NaN);
return histogram;
}
- final double[] histogram = sketch.getPMF(splitPoints != null ? splitPoints
:
- equallySpacedPoints(numBins, sketch.getMinItem(), sketch.getMaxItem()));
+ final double[] splitPoints;
+ if (this.splitPoints != null) {
+ splitPoints = this.splitPoints;
+ } else {
+ final double min = sketch.getMinItem();
+ final double max = sketch.getMaxItem();
+ if (min == max) {
+ // if min is equal to max, we can't create an array of equally spaced
points.
+ // all values would go into the first bucket anyway, and the remaining
+ // buckets are left as zero.
+ final double[] histogram = new double[numBins];
+ histogram[0] = sketch.getN();
+ return histogram;
+ }
+ splitPoints = equallySpacedPoints(numBins, min, max);
+ }
+ final double[] histogram = sketch.getPMF(splitPoints);
for (int i = 0; i < histogram.length; i++) {
histogram[i] *= sketch.getN(); // scale fractions to counts
}
diff --git
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/kll/KllFloatsSketchToHistogramPostAggregator.java
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/kll/KllFloatsSketchToHistogramPostAggregator.java
index 90e0942f80a..a5bfc68f326 100644
---
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/kll/KllFloatsSketchToHistogramPostAggregator.java
+++
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/kll/KllFloatsSketchToHistogramPostAggregator.java
@@ -67,7 +67,7 @@ public class KllFloatsSketchToHistogramPostAggregator
implements PostAggregator
public Object compute(final Map<String, Object> combinedAggregators)
{
final KllFloatsSketch sketch = (KllFloatsSketch)
field.compute(combinedAggregators);
- final int numBins = splitPoints != null ? splitPoints.length + 1 :
+ final int numBins = this.splitPoints != null ? this.splitPoints.length + 1
:
(this.numBins != null ? this.numBins.intValue() : DEFAULT_NUM_BINS);
if (numBins < 2) {
throw new IAE("at least 2 bins expected");
@@ -77,8 +77,23 @@ public class KllFloatsSketchToHistogramPostAggregator
implements PostAggregator
Arrays.fill(histogram, Double.NaN);
return histogram;
}
- final double[] histogram = sketch.getPMF(splitPoints != null ? splitPoints
:
- equallySpacedPoints(numBins, sketch.getMinItem(), sketch.getMaxItem()));
+ final float[] splitPoints;
+ if (this.splitPoints != null) {
+ splitPoints = this.splitPoints;
+ } else {
+ final float min = sketch.getMinItem();
+ final float max = sketch.getMaxItem();
+ if (min == max) {
+ // if min is equal to max, we can't create an array of equally spaced
points.
+ // all values would go into the first bucket anyway, and the remaining
+ // buckets are left as zero.
+ final double[] histogram = new double[numBins];
+ histogram[0] = sketch.getN();
+ return histogram;
+ }
+ splitPoints = equallySpacedPoints(numBins, min, max);
+ }
+ final double[] histogram = sketch.getPMF(splitPoints);
for (int i = 0; i < histogram.length; i++) {
histogram[i] *= sketch.getN(); // scale fractions to counts
}
diff --git
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/quantiles/DoublesSketchToHistogramPostAggregator.java
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/quantiles/DoublesSketchToHistogramPostAggregator.java
index 49d4f84cd4f..7598561f273 100644
---
a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/quantiles/DoublesSketchToHistogramPostAggregator.java
+++
b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/quantiles/DoublesSketchToHistogramPostAggregator.java
@@ -67,7 +67,7 @@ public class DoublesSketchToHistogramPostAggregator
implements PostAggregator
public Object compute(final Map<String, Object> combinedAggregators)
{
final DoublesSketch sketch = (DoublesSketch)
field.compute(combinedAggregators);
- final int numBins = splitPoints != null ? splitPoints.length + 1 :
+ final int numBins = this.splitPoints != null ? this.splitPoints.length + 1
:
(this.numBins != null ? this.numBins.intValue() : DEFAULT_NUM_BINS);
if (numBins < 2) {
throw new IAE("at least 2 bins expected");
@@ -77,8 +77,23 @@ public class DoublesSketchToHistogramPostAggregator
implements PostAggregator
Arrays.fill(histogram, Double.NaN);
return histogram;
}
- final double[] histogram = sketch.getPMF(splitPoints != null ? splitPoints
:
- equallySpacedPoints(numBins, sketch.getMinItem(), sketch.getMaxItem()));
+ final double[] splitPoints;
+ if (this.splitPoints != null) {
+ splitPoints = this.splitPoints;
+ } else {
+ final double min = sketch.getMinItem();
+ final double max = sketch.getMaxItem();
+ if (min == max) {
+ // if min is equal to max, we can't create an array of equally spaced
points.
+ // all values would go into the first bucket anyway, and the remaining
+ // buckets are left as zero.
+ final double[] histogram = new double[numBins];
+ histogram[0] = sketch.getN();
+ return histogram;
+ }
+ splitPoints = equallySpacedPoints(numBins, min, max);
+ }
+ final double[] histogram = sketch.getPMF(splitPoints);
for (int i = 0; i < histogram.length; i++) {
histogram[i] *= sketch.getN(); // scale fractions to counts
}
diff --git
a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/kll/KllDoublesSketchToHistogramPostAggregatorTest.java
b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/kll/KllDoublesSketchToHistogramPostAggregatorTest.java
index e3f55b4fb79..bfb125b42b5 100644
---
a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/kll/KllDoublesSketchToHistogramPostAggregatorTest.java
+++
b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/kll/KllDoublesSketchToHistogramPostAggregatorTest.java
@@ -157,6 +157,36 @@ public class KllDoublesSketchToHistogramPostAggregatorTest
Assert.assertEquals(3.0, histogram[1], 0);
}
+ @Test
+ public void splitPointsEqualValues()
+ {
+ final double[] values = new double[] {6, 6, 6, 6, 6, 6};
+ final TestDoubleColumnSelectorImpl selector = new
TestDoubleColumnSelectorImpl(values);
+
+ final Aggregator agg = new KllDoublesSketchBuildAggregator(selector, 8);
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0; i < values.length; i++) {
+ agg.aggregate();
+ selector.increment();
+ }
+
+ final Map<String, Object> fields = new HashMap<>();
+ fields.put("sketch", agg.get());
+
+ final PostAggregator postAgg = new
KllDoublesSketchToHistogramPostAggregator(
+ "histogram",
+ new FieldAccessPostAggregator("field", "sketch"),
+ new double[] {3.5}, // all values are in the second bin
+ null
+ );
+
+ final double[] histogram = (double[]) postAgg.compute(fields);
+ Assert.assertNotNull(histogram);
+ Assert.assertEquals(2, histogram.length);
+ Assert.assertEquals(0.0, histogram[0], 0);
+ Assert.assertEquals(6.0, histogram[1], 0);
+ }
+
@Test
public void numBins()
{
@@ -187,6 +217,128 @@ public class KllDoublesSketchToHistogramPostAggregatorTest
Assert.assertEquals(3.0, histogram[1], 0);
}
+ @Test
+ public void oneValueTwoBins()
+ {
+ final double[] values = new double[] {1};
+ final TestDoubleColumnSelectorImpl selector = new
TestDoubleColumnSelectorImpl(values);
+
+ final Aggregator agg = new KllDoublesSketchBuildAggregator(selector, 8);
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0; i < values.length; i++) {
+ agg.aggregate();
+ selector.increment();
+ }
+
+ final Map<String, Object> fields = new HashMap<>();
+ fields.put("sketch", agg.get());
+
+ final PostAggregator postAgg = new
KllDoublesSketchToHistogramPostAggregator(
+ "histogram",
+ new FieldAccessPostAggregator("field", "sketch"),
+ null,
+ 2 // two bins, the second is empty
+ );
+
+ final double[] histogram = (double[]) postAgg.compute(fields);
+ Assert.assertNotNull(histogram);
+ Assert.assertEquals(2, histogram.length);
+ Assert.assertEquals(1.0, histogram[0], 0);
+ Assert.assertEquals(0.0, histogram[1], 0);
+ }
+
+ @Test
+ public void oneValueThreeBins()
+ {
+ final double[] values = new double[] {1};
+ final TestDoubleColumnSelectorImpl selector = new
TestDoubleColumnSelectorImpl(values);
+
+ final Aggregator agg = new KllDoublesSketchBuildAggregator(selector, 8);
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0; i < values.length; i++) {
+ agg.aggregate();
+ selector.increment();
+ }
+
+ final Map<String, Object> fields = new HashMap<>();
+ fields.put("sketch", agg.get());
+
+ final PostAggregator postAgg = new
KllDoublesSketchToHistogramPostAggregator(
+ "histogram",
+ new FieldAccessPostAggregator("field", "sketch"),
+ null,
+ 3 // three bins, the second and third are empty
+ );
+
+ final double[] histogram = (double[]) postAgg.compute(fields);
+ Assert.assertNotNull(histogram);
+ Assert.assertEquals(3, histogram.length);
+ Assert.assertEquals(1.0, histogram[0], 0);
+ Assert.assertEquals(0.0, histogram[1], 0);
+ Assert.assertEquals(0.0, histogram[2], 0);
+ }
+
+ @Test
+ public void equalValuesTwoBins()
+ {
+ final double[] values = new double[] {1, 1, 1};
+ final TestDoubleColumnSelectorImpl selector = new
TestDoubleColumnSelectorImpl(values);
+
+ final Aggregator agg = new KllDoublesSketchBuildAggregator(selector, 8);
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0; i < values.length; i++) {
+ agg.aggregate();
+ selector.increment();
+ }
+
+ final Map<String, Object> fields = new HashMap<>();
+ fields.put("sketch", agg.get());
+
+ final PostAggregator postAgg = new
KllDoublesSketchToHistogramPostAggregator(
+ "histogram",
+ new FieldAccessPostAggregator("field", "sketch"),
+ null,
+ 2 // two bins, the second is empty
+ );
+
+ final double[] histogram = (double[]) postAgg.compute(fields);
+ Assert.assertNotNull(histogram);
+ Assert.assertEquals(2, histogram.length);
+ Assert.assertEquals(3.0, histogram[0], 0);
+ Assert.assertEquals(0.0, histogram[1], 0);
+ }
+
+ @Test
+ public void equalValuesThreeBins()
+ {
+ final double[] values = new double[] {1, 1, 1};
+ final TestDoubleColumnSelectorImpl selector = new
TestDoubleColumnSelectorImpl(values);
+
+ final Aggregator agg = new KllDoublesSketchBuildAggregator(selector, 8);
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0; i < values.length; i++) {
+ agg.aggregate();
+ selector.increment();
+ }
+
+ final Map<String, Object> fields = new HashMap<>();
+ fields.put("sketch", agg.get());
+
+ final PostAggregator postAgg = new
KllDoublesSketchToHistogramPostAggregator(
+ "histogram",
+ new FieldAccessPostAggregator("field", "sketch"),
+ null,
+ 3 // three bins, the second and third are empty
+ );
+
+ final double[] histogram = (double[]) postAgg.compute(fields);
+ Assert.assertNotNull(histogram);
+ Assert.assertEquals(3, histogram.length);
+ Assert.assertEquals(3.0, histogram[0], 0);
+ Assert.assertEquals(0.0, histogram[1], 0);
+ Assert.assertEquals(0.0, histogram[2], 0);
+ }
+
@Test
public void testResultArraySignature()
{
diff --git
a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/kll/KllFloatsSketchToHistogramPostAggregatorTest.java
b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/kll/KllFloatsSketchToHistogramPostAggregatorTest.java
index 5b970816f3f..bf5862bec88 100644
---
a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/kll/KllFloatsSketchToHistogramPostAggregatorTest.java
+++
b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/kll/KllFloatsSketchToHistogramPostAggregatorTest.java
@@ -157,6 +157,36 @@ public class KllFloatsSketchToHistogramPostAggregatorTest
Assert.assertEquals(3.0, histogram[1], 0);
}
+ @Test
+ public void splitPointsEqualValues()
+ {
+ final float[] values = new float[] {6, 6, 6, 6, 6, 6};
+ final TestFloatColumnSelector selector = new
TestFloatColumnSelector(values);
+
+ final Aggregator agg = new KllFloatsSketchBuildAggregator(selector, 8);
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0; i < values.length; i++) {
+ agg.aggregate();
+ selector.increment();
+ }
+
+ final Map<String, Object> fields = new HashMap<>();
+ fields.put("sketch", agg.get());
+
+ final PostAggregator postAgg = new
KllFloatsSketchToHistogramPostAggregator(
+ "histogram",
+ new FieldAccessPostAggregator("field", "sketch"),
+ new float[] {3.5f}, // all values are in the second bin
+ null
+ );
+
+ final double[] histogram = (double[]) postAgg.compute(fields);
+ Assert.assertNotNull(histogram);
+ Assert.assertEquals(2, histogram.length);
+ Assert.assertEquals(0.0, histogram[0], 0);
+ Assert.assertEquals(6.0, histogram[1], 0);
+ }
+
@Test
public void numBins()
{
@@ -187,6 +217,128 @@ public class KllFloatsSketchToHistogramPostAggregatorTest
Assert.assertEquals(3.0, histogram[1], 0);
}
+ @Test
+ public void oneValueTwoBins()
+ {
+ final float[] values = new float[] {1};
+ final TestFloatColumnSelector selector = new
TestFloatColumnSelector(values);
+
+ final Aggregator agg = new KllFloatsSketchBuildAggregator(selector, 8);
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0; i < values.length; i++) {
+ agg.aggregate();
+ selector.increment();
+ }
+
+ final Map<String, Object> fields = new HashMap<>();
+ fields.put("sketch", agg.get());
+
+ final PostAggregator postAgg = new
KllFloatsSketchToHistogramPostAggregator(
+ "histogram",
+ new FieldAccessPostAggregator("field", "sketch"),
+ null,
+ 2 // two bins, the second is empty
+ );
+
+ final double[] histogram = (double[]) postAgg.compute(fields);
+ Assert.assertNotNull(histogram);
+ Assert.assertEquals(2, histogram.length);
+ Assert.assertEquals(1.0, histogram[0], 0);
+ Assert.assertEquals(0.0, histogram[1], 0);
+ }
+
+ @Test
+ public void oneValueThreeBins()
+ {
+ final float[] values = new float[] {1};
+ final TestFloatColumnSelector selector = new
TestFloatColumnSelector(values);
+
+ final Aggregator agg = new KllFloatsSketchBuildAggregator(selector, 8);
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0; i < values.length; i++) {
+ agg.aggregate();
+ selector.increment();
+ }
+
+ final Map<String, Object> fields = new HashMap<>();
+ fields.put("sketch", agg.get());
+
+ final PostAggregator postAgg = new
KllFloatsSketchToHistogramPostAggregator(
+ "histogram",
+ new FieldAccessPostAggregator("field", "sketch"),
+ null,
+ 3 // three bins, the second and third are empty
+ );
+
+ final double[] histogram = (double[]) postAgg.compute(fields);
+ Assert.assertNotNull(histogram);
+ Assert.assertEquals(3, histogram.length);
+ Assert.assertEquals(1.0, histogram[0], 0);
+ Assert.assertEquals(0.0, histogram[1], 0);
+ Assert.assertEquals(0.0, histogram[2], 0);
+ }
+
+ @Test
+ public void equalValuesTwoBins()
+ {
+ final float[] values = new float[] {1, 1, 1};
+ final TestFloatColumnSelector selector = new
TestFloatColumnSelector(values);
+
+ final Aggregator agg = new KllFloatsSketchBuildAggregator(selector, 8);
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0; i < values.length; i++) {
+ agg.aggregate();
+ selector.increment();
+ }
+
+ final Map<String, Object> fields = new HashMap<>();
+ fields.put("sketch", agg.get());
+
+ final PostAggregator postAgg = new
KllFloatsSketchToHistogramPostAggregator(
+ "histogram",
+ new FieldAccessPostAggregator("field", "sketch"),
+ null,
+ 2 // two bins, the second is empty
+ );
+
+ final double[] histogram = (double[]) postAgg.compute(fields);
+ Assert.assertNotNull(histogram);
+ Assert.assertEquals(2, histogram.length);
+ Assert.assertEquals(3.0, histogram[0], 0);
+ Assert.assertEquals(0.0, histogram[1], 0);
+ }
+
+ @Test
+ public void equalValuesThreeBins()
+ {
+ final float[] values = new float[] {1, 1, 1};
+ final TestFloatColumnSelector selector = new
TestFloatColumnSelector(values);
+
+ final Aggregator agg = new KllFloatsSketchBuildAggregator(selector, 8);
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0; i < values.length; i++) {
+ agg.aggregate();
+ selector.increment();
+ }
+
+ final Map<String, Object> fields = new HashMap<>();
+ fields.put("sketch", agg.get());
+
+ final PostAggregator postAgg = new
KllFloatsSketchToHistogramPostAggregator(
+ "histogram",
+ new FieldAccessPostAggregator("field", "sketch"),
+ null,
+ 3 // three bins, the second and third are empty
+ );
+
+ final double[] histogram = (double[]) postAgg.compute(fields);
+ Assert.assertNotNull(histogram);
+ Assert.assertEquals(3, histogram.length);
+ Assert.assertEquals(3.0, histogram[0], 0);
+ Assert.assertEquals(0.0, histogram[1], 0);
+ Assert.assertEquals(0.0, histogram[2], 0);
+ }
+
@Test
public void testResultArraySignature()
{
diff --git
a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/quantiles/DoublesSketchToHistogramPostAggregatorTest.java
b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/quantiles/DoublesSketchToHistogramPostAggregatorTest.java
index 2bfc0e53539..94bc7fa1b9d 100644
---
a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/quantiles/DoublesSketchToHistogramPostAggregatorTest.java
+++
b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/quantiles/DoublesSketchToHistogramPostAggregatorTest.java
@@ -157,6 +157,36 @@ public class DoublesSketchToHistogramPostAggregatorTest
Assert.assertEquals(3.0, histogram[1], 0);
}
+ @Test
+ public void splitPointsEqualValues()
+ {
+ final double[] values = new double[] {6, 6, 6, 6, 6, 6};
+ final TestDoubleColumnSelectorImpl selector = new
TestDoubleColumnSelectorImpl(values);
+
+ final Aggregator agg = new DoublesSketchBuildAggregator(selector, 8);
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0; i < values.length; i++) {
+ agg.aggregate();
+ selector.increment();
+ }
+
+ final Map<String, Object> fields = new HashMap<>();
+ fields.put("sketch", agg.get());
+
+ final PostAggregator postAgg = new DoublesSketchToHistogramPostAggregator(
+ "histogram",
+ new FieldAccessPostAggregator("field", "sketch"),
+ new double[] {3.5}, // all values are in the second bin
+ null
+ );
+
+ final double[] histogram = (double[]) postAgg.compute(fields);
+ Assert.assertNotNull(histogram);
+ Assert.assertEquals(2, histogram.length);
+ Assert.assertEquals(0.0, histogram[0], 0);
+ Assert.assertEquals(6.0, histogram[1], 0);
+ }
+
@Test
public void numBins()
{
@@ -187,6 +217,128 @@ public class DoublesSketchToHistogramPostAggregatorTest
Assert.assertEquals(3.0, histogram[1], 0);
}
+ @Test
+ public void oneValueTwoBins()
+ {
+ final double[] values = new double[] {1};
+ final TestDoubleColumnSelectorImpl selector = new
TestDoubleColumnSelectorImpl(values);
+
+ final Aggregator agg = new DoublesSketchBuildAggregator(selector, 8);
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0; i < values.length; i++) {
+ agg.aggregate();
+ selector.increment();
+ }
+
+ final Map<String, Object> fields = new HashMap<>();
+ fields.put("sketch", agg.get());
+
+ final PostAggregator postAgg = new DoublesSketchToHistogramPostAggregator(
+ "histogram",
+ new FieldAccessPostAggregator("field", "sketch"),
+ null,
+ 2 // two bins, the second is empty
+ );
+
+ final double[] histogram = (double[]) postAgg.compute(fields);
+ Assert.assertNotNull(histogram);
+ Assert.assertEquals(2, histogram.length);
+ Assert.assertEquals(1.0, histogram[0], 0);
+ Assert.assertEquals(0.0, histogram[1], 0);
+ }
+
+ @Test
+ public void oneValueThreeBins()
+ {
+ final double[] values = new double[] {1};
+ final TestDoubleColumnSelectorImpl selector = new
TestDoubleColumnSelectorImpl(values);
+
+ final Aggregator agg = new DoublesSketchBuildAggregator(selector, 8);
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0; i < values.length; i++) {
+ agg.aggregate();
+ selector.increment();
+ }
+
+ final Map<String, Object> fields = new HashMap<>();
+ fields.put("sketch", agg.get());
+
+ final PostAggregator postAgg = new DoublesSketchToHistogramPostAggregator(
+ "histogram",
+ new FieldAccessPostAggregator("field", "sketch"),
+ null,
+ 3 // three bins, the second and third are empty
+ );
+
+ final double[] histogram = (double[]) postAgg.compute(fields);
+ Assert.assertNotNull(histogram);
+ Assert.assertEquals(3, histogram.length);
+ Assert.assertEquals(1.0, histogram[0], 0);
+ Assert.assertEquals(0.0, histogram[1], 0);
+ Assert.assertEquals(0.0, histogram[2], 0);
+ }
+
+ @Test
+ public void equalValuesTwoBins()
+ {
+ final double[] values = new double[] {1, 1, 1};
+ final TestDoubleColumnSelectorImpl selector = new
TestDoubleColumnSelectorImpl(values);
+
+ final Aggregator agg = new DoublesSketchBuildAggregator(selector, 8);
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0; i < values.length; i++) {
+ agg.aggregate();
+ selector.increment();
+ }
+
+ final Map<String, Object> fields = new HashMap<>();
+ fields.put("sketch", agg.get());
+
+ final PostAggregator postAgg = new DoublesSketchToHistogramPostAggregator(
+ "histogram",
+ new FieldAccessPostAggregator("field", "sketch"),
+ null,
+ 2 // two bins, the second is empty
+ );
+
+ final double[] histogram = (double[]) postAgg.compute(fields);
+ Assert.assertNotNull(histogram);
+ Assert.assertEquals(2, histogram.length);
+ Assert.assertEquals(3.0, histogram[0], 0);
+ Assert.assertEquals(0.0, histogram[1], 0);
+ }
+
+ @Test
+ public void equalValuesThreeBins()
+ {
+ final double[] values = new double[] {1, 1, 1};
+ final TestDoubleColumnSelectorImpl selector = new
TestDoubleColumnSelectorImpl(values);
+
+ final Aggregator agg = new DoublesSketchBuildAggregator(selector, 8);
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0; i < values.length; i++) {
+ agg.aggregate();
+ selector.increment();
+ }
+
+ final Map<String, Object> fields = new HashMap<>();
+ fields.put("sketch", agg.get());
+
+ final PostAggregator postAgg = new DoublesSketchToHistogramPostAggregator(
+ "histogram",
+ new FieldAccessPostAggregator("field", "sketch"),
+ null,
+ 3 // three bins, the second and third are empty
+ );
+
+ final double[] histogram = (double[]) postAgg.compute(fields);
+ Assert.assertNotNull(histogram);
+ Assert.assertEquals(3, histogram.length);
+ Assert.assertEquals(3.0, histogram[0], 0);
+ Assert.assertEquals(0.0, histogram[1], 0);
+ Assert.assertEquals(0.0, histogram[2], 0);
+ }
+
@Test
public void testResultArraySignature()
{
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]