-
Notifications
You must be signed in to change notification settings - Fork 24.3k
/
InternalHDRPercentilesTests.java
147 lines (127 loc) · 5.27 KB
/
InternalHDRPercentilesTests.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
package org.elasticsearch.search.aggregations.metrics;
import org.HdrHistogram.DoubleHistogram;
import org.elasticsearch.common.util.Maps;
import org.elasticsearch.search.DocValueFormat;
import org.elasticsearch.search.aggregations.support.SamplingContext;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import static java.util.Collections.emptyMap;
import static org.hamcrest.Matchers.equalTo;
public class InternalHDRPercentilesTests extends InternalPercentilesTestCase<InternalHDRPercentiles> {
@Override
protected InternalHDRPercentiles createTestInstance(
String name,
Map<String, Object> metadata,
boolean keyed,
DocValueFormat format,
double[] percents,
double[] values,
boolean empty
) {
if (empty) {
return new InternalHDRPercentiles(name, percents, null, keyed, format, metadata);
}
final DoubleHistogram state = new DoubleHistogram(3);
Arrays.stream(values).forEach(state::recordValue);
return new InternalHDRPercentiles(name, percents, state, keyed, format, metadata);
}
@Override
protected void assertReduced(InternalHDRPercentiles reduced, List<InternalHDRPercentiles> inputs) {
// it is hard to check the values due to the inaccuracy of the algorithm
long totalCount = 0;
for (InternalHDRPercentiles ranks : inputs) {
totalCount += ranks.state.getTotalCount();
}
assertEquals(totalCount, reduced.state.getTotalCount());
}
@Override
protected boolean supportsSampling() {
return true;
}
@Override
protected void assertSampled(InternalHDRPercentiles sampled, InternalHDRPercentiles reduced, SamplingContext samplingContext) {
Iterator<Percentile> it1 = sampled.iterator();
Iterator<Percentile> it2 = reduced.iterator();
while (it1.hasNext() && it2.hasNext()) {
assertThat(it1.next(), equalTo(it2.next()));
}
}
@Override
protected Class<? extends ParsedPercentiles> implementationClass() {
return ParsedHDRPercentiles.class;
}
public void testIterator() {
final double[] percents = randomPercents(false);
final double[] values = new double[frequently() ? randomIntBetween(1, 10) : 0];
for (int i = 0; i < values.length; ++i) {
values[i] = randomDouble();
}
InternalHDRPercentiles aggregation = createTestInstance(
"test",
emptyMap(),
false,
randomNumericDocValueFormat(),
percents,
values,
false
);
Iterator<Percentile> iterator = aggregation.iterator();
Iterator<String> nameIterator = aggregation.valueNames().iterator();
for (double percent : percents) {
assertTrue(iterator.hasNext());
assertTrue(nameIterator.hasNext());
Percentile percentile = iterator.next();
String percentileName = nameIterator.next();
assertEquals(percent, Double.valueOf(percentileName), 0.0d);
assertEquals(percent, percentile.getPercent(), 0.0d);
assertEquals(aggregation.percentile(percent), percentile.getValue(), 0.0d);
assertEquals(aggregation.value(String.valueOf(percent)), percentile.getValue(), 0.0d);
}
assertFalse(iterator.hasNext());
assertFalse(nameIterator.hasNext());
}
@Override
protected InternalHDRPercentiles mutateInstance(InternalHDRPercentiles instance) {
String name = instance.getName();
double[] percents = instance.keys;
DoubleHistogram state = instance.state;
boolean keyed = instance.keyed;
DocValueFormat formatter = instance.formatter();
Map<String, Object> metadata = instance.getMetadata();
switch (between(0, 4)) {
case 0 -> name += randomAlphaOfLength(5);
case 1 -> {
percents = Arrays.copyOf(percents, percents.length + 1);
percents[percents.length - 1] = randomDouble() * 100;
Arrays.sort(percents);
}
case 2 -> {
state = new DoubleHistogram(state);
for (int i = 0; i < between(10, 100); i++) {
state.recordValue(randomDouble());
}
}
case 3 -> keyed = keyed == false;
case 4 -> {
if (metadata == null) {
metadata = Maps.newMapWithExpectedSize(1);
} else {
metadata = new HashMap<>(instance.getMetadata());
}
metadata.put(randomAlphaOfLength(15), randomInt());
}
default -> throw new AssertionError("Illegal randomisation branch");
}
return new InternalHDRPercentiles(name, percents, state, keyed, formatter, metadata);
}
}