|
21 | 21 |
|
22 | 22 | package org.elasticsearch.exponentialhistogram; |
23 | 23 |
|
| 24 | +import org.elasticsearch.core.Types; |
24 | 25 | import org.elasticsearch.xcontent.XContentBuilder; |
| 26 | +import org.elasticsearch.xcontent.XContentParser; |
25 | 27 |
|
26 | 28 | import java.io.IOException; |
| 29 | +import java.util.Collections; |
| 30 | +import java.util.List; |
| 31 | +import java.util.Map; |
| 32 | +import java.util.function.BiConsumer; |
27 | 33 |
|
28 | 34 | /** |
29 | 35 | * Handles the serialization of an {@link ExponentialHistogram} to XContent. |
@@ -101,4 +107,54 @@ private static void writeBuckets(XContentBuilder b, String fieldName, Exponentia |
101 | 107 | b.endObject(); |
102 | 108 | } |
103 | 109 |
|
| 110 | + /** |
| 111 | + * Parses an {@link ExponentialHistogram} from the provided {@link XContentParser}. |
| 112 | + * This method is neither optimized, nor does it do any validation of the parsed content. |
| 113 | + * No estimation for missing sum/min/max is done. |
| 114 | + * Therefore only intended for testing! |
| 115 | + * |
| 116 | + * @param xContent the serialized histogram to read |
| 117 | + * @return the deserialized histogram |
| 118 | + * @throws IOException if the XContentParser throws an IOException |
| 119 | + */ |
| 120 | + public static ExponentialHistogram parseForTesting(XContentParser xContent) throws IOException { |
| 121 | + return parseForTesting(xContent.map()); |
| 122 | + } |
| 123 | + |
| 124 | + /** |
| 125 | + * Parses an {@link ExponentialHistogram} from a {@link Map}. |
| 126 | + * This method is neither optimized, nor does it do any validation of the parsed content. |
| 127 | + * No estimation for missing sum/min/max is done. |
| 128 | + * Therefore only intended for testing! |
| 129 | + * |
| 130 | + * @param xContent the serialized histogram as a map |
| 131 | + * @return the deserialized histogram |
| 132 | + */ |
| 133 | + public static ExponentialHistogram parseForTesting(Map<String, Object> xContent) { |
| 134 | + int scale = ((Number) xContent.get(SCALE_FIELD)).intValue(); |
| 135 | + ExponentialHistogramBuilder builder = ExponentialHistogram.builder(scale, ExponentialHistogramCircuitBreaker.noop()); |
| 136 | + |
| 137 | + Map<String, Number> zero = Types.forciblyCast(xContent.getOrDefault(ZERO_FIELD, Collections.emptyMap())); |
| 138 | + double zeroThreshold = zero.getOrDefault(ZERO_THRESHOLD_FIELD, 0).doubleValue(); |
| 139 | + long zeroCount = zero.getOrDefault(ZERO_COUNT_FIELD, 0).longValue(); |
| 140 | + builder.zeroBucket(ZeroBucket.create(zeroThreshold, zeroCount)); |
| 141 | + |
| 142 | + builder.sum(((Number) xContent.getOrDefault(SUM_FIELD, 0)).doubleValue()); |
| 143 | + builder.min(((Number) xContent.getOrDefault(MIN_FIELD, Double.NaN)).doubleValue()); |
| 144 | + builder.max(((Number) xContent.getOrDefault(MAX_FIELD, Double.NaN)).doubleValue()); |
| 145 | + |
| 146 | + parseBuckets(Types.forciblyCast(xContent.getOrDefault(NEGATIVE_FIELD, Collections.emptyMap())), builder::setNegativeBucket); |
| 147 | + parseBuckets(Types.forciblyCast(xContent.getOrDefault(POSITIVE_FIELD, Collections.emptyMap())), builder::setPositiveBucket); |
| 148 | + |
| 149 | + return builder.build(); |
| 150 | + } |
| 151 | + |
| 152 | + private static void parseBuckets(Map<String, List<Number>> serializedBuckets, BiConsumer<Long, Long> bucketSetter) { |
| 153 | + List<Number> indices = serializedBuckets.getOrDefault(BUCKET_INDICES_FIELD, Collections.emptyList()); |
| 154 | + List<Number> counts = serializedBuckets.getOrDefault(BUCKET_COUNTS_FIELD, Collections.emptyList()); |
| 155 | + assert indices.size() == counts.size(); |
| 156 | + for (int i = 0; i < indices.size(); i++) { |
| 157 | + bucketSetter.accept(indices.get(i).longValue(), counts.get(i).longValue()); |
| 158 | + } |
| 159 | + } |
104 | 160 | } |
0 commit comments