This is an automated email from the ASF dual-hosted git repository.
xiangfu0 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push:
new b5af5f745ae Prepare t-digest relocation and legacy accuracy baseline
(#19829)
b5af5f745ae is described below
commit b5af5f745aee2728f01056f78bf9038294a45307
Author: Xiang Fu <[email protected]>
AuthorDate: Mon Oct 12 13:25:11 2026 -0700
Prepare t-digest relocation and legacy accuracy baseline (#19829)
Relocate the existing accumulator as TDigestAccumulator without changing
its algorithm or serialized bytes, and freeze the legacy accuracy baseline.
Use a standalone POM to resolve t-digest so the verifier works with an
empty Maven cache.
---
compatibility-verifier/README.md | 13 +
.../tdigest-compatibility/GenerateRankErrors.java | 162 +++++++++++
.../tdigest-compatibility/generate-rank-errors.sh | 84 ++++++
.../PercentileSmartTDigestAggregationFunction.java | 15 +-
.../PercentileTDigestAggregationFunction.java | 47 ++--
...ercentileRawTDigestAggregationFunctionTest.java | 7 +-
...centileSmartTDigestAggregationFunctionTest.java | 17 +-
.../PercentileTDigestAggregationFunctionTest.java | 85 +++---
.../resources/data/tdigest-3.3-k1-rank-errors.csv | 299 +++++++++++++++++++++
.../customobject/tdigest/TDigestAccumulator.java | 52 ++--
10 files changed, 672 insertions(+), 109 deletions(-)
diff --git a/compatibility-verifier/README.md b/compatibility-verifier/README.md
index 209ae098adc..b3a96f92af2 100644
--- a/compatibility-verifier/README.md
+++ b/compatibility-verifier/README.md
@@ -53,3 +53,16 @@ OPTIONAL:
-k, --keep-cluster-on-failure Keep cluster on test failure
-h, --help Prints this help
```
+
+## T-digest accuracy baseline
+
+Run `compatibility-verifier/tdigest-compatibility/generate-rank-errors.sh`
from a checkout with JDK 25+ to verify the
+270 seeded case/input fingerprints and rank-error envelopes in
+`pinot-core/src/test/resources/data/tdigest-3.3-k1-rank-errors.csv`. The
standalone script compiles only the generator,
+Pinot's pinned `f818bae6d75a91228eb3aac95c921bca4aeb2128` utility and the
genuine `com.tdunning:t-digest:3.3` jar;
+it does not depend on the current accumulator or a Pinot build. It fetches the
pinned commit and jar if missing.
+
+The reference environment is Ubuntu x86_64 with Temurin 25. `StrictMath` makes
seeded input fingerprints portable,
+but the legacy library's `Math` trigonometric functions can change exact rank
errors across architectures or JVMs.
+Investigate regeneration differences on the reference environment before
changing the CSV. Use `--update` only
+after intentionally changing the seeded corpus; it writes an unverified
reference that must be reviewed.
diff --git
a/compatibility-verifier/tdigest-compatibility/GenerateRankErrors.java
b/compatibility-verifier/tdigest-compatibility/GenerateRankErrors.java
new file mode 100644
index 00000000000..637836babe8
--- /dev/null
+++ b/compatibility-verifier/tdigest-compatibility/GenerateRankErrors.java
@@ -0,0 +1,162 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import com.tdunning.math.stats.Centroid;
+import com.tdunning.math.stats.TDigest;
+import java.nio.ByteBuffer;
+import java.security.MessageDigest;
+import java.util.Arrays;
+import java.util.HexFormat;
+import java.util.SplittableRandom;
+import org.apache.pinot.segment.local.utils.TDigestUtils;
+
+
+/// Independent legacy rank oracle, run sequentially with the pinned baseline
utility and t-digest 3.3 only.
+public final class GenerateRankErrors {
+ private static final double[] QUANTILES = {0, 0.5, 0.75, 0.95, 0.99, 1};
+ private static final String[] DISTRIBUTIONS = {"UNIFORM", "SKEWED",
"HEAVY_TAIL", "BIMODAL", "DUPLICATE_HEAVY"};
+ private static final String[] ORDERS = {"ORIGINAL", "REVERSED",
"RANDOMIZED"};
+ private static final String[] INPUTS = {"SERVER_LOCAL", "DISTRIBUTED"};
+
+ private GenerateRankErrors() {
+ }
+
+ public static void main(String[] args)
+ throws Exception {
+ System.out.println("# mergeOrders=" + String.join(",", ORDERS));
+ System.out.println("# reducerInputs=" + String.join(",", INPUTS));
+ for (int fanIn : new int[]{8, 32, 128}) {
+ for (int compression : new int[]{20, 100, 1000}) {
+ for (String distribution : DISTRIBUTIONS) {
+ for (String order : ORDERS) {
+ for (String input : INPUTS) {
+ Reference reference = referenceCase(fanIn, compression,
distribution, order, input);
+ System.out.print(fanIn + "/" + compression + "/" + distribution
+ "/" + order + "/" + input
+ + "," + reference.inputSha256());
+ for (double error : reference.rankErrors()) {
+ System.out.print("," + error);
+ }
+ System.out.println();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private record Reference(String inputSha256, double[] rankErrors) {
+ }
+
+ private static Reference referenceCase(int fanIn, int compression, String
distribution, String order, String input)
+ throws Exception {
+ TDigest[] sources = new TDigest[fanIn];
+ double[] raw = new double[fanIn * 64];
+ for (int i = 0; i < fanIn; i++) {
+ TDigest digest = TDigestUtils.createMergingDigest(compression);
+ SplittableRandom random = new SplittableRandom(0x5EEDL + i);
+ for (int j = 0; j < 64; j++) {
+ double value = value(distribution, random.nextDouble());
+ raw[64 * i + j] = value;
+ digest.add(value);
+ }
+ sources[i] = input.equals("DISTRIBUTED") ?
TDigestUtils.deserialize(TDigestUtils.serialize(digest)) : digest;
+ }
+ TDigest result = TDigestUtils.createMergingDigest(compression);
+ int[] sourceIndexes = indexes(fanIn, order);
+ for (int index : sourceIndexes) {
+ if (result.size() == 0) {
+ result = sources[index];
+ } else {
+ result.add(sources[index]);
+ }
+ }
+ // In t-digest 3.3, centroids() calls compress(), forcing the final
public-compression pass before quantiles.
+ for (Centroid centroid : result.centroids()) {
+ if (!Double.isFinite(centroid.mean()) || centroid.count() <= 0) {
+ throw new IllegalStateException("Invalid legacy reference centroid");
+ }
+ }
+ Arrays.sort(raw);
+ double[] errors = new double[QUANTILES.length];
+ for (int i = 0; i < errors.length; i++) {
+ errors[i] = rankError(raw, result.quantile(QUANTILES[i]), QUANTILES[i]);
+ }
+ ByteBuffer encodedRaw = ByteBuffer.allocate(Double.BYTES * raw.length +
Integer.BYTES * sourceIndexes.length);
+ for (double value : raw) {
+ encodedRaw.putDouble(value);
+ }
+ for (int sourceIndex : sourceIndexes) {
+ encodedRaw.putInt(sourceIndex);
+ }
+ String inputSha256 =
HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256").digest(encodedRaw.array()));
+ return new Reference(inputSha256, errors);
+ }
+
+ private static double value(String distribution, double unitValue) {
+ return switch (distribution) {
+ case "UNIFORM" -> unitValue;
+ case "SKEWED" -> StrictMath.pow(unitValue, 8);
+ case "HEAVY_TAIL" -> StrictMath.pow(1 - 0.999 * unitValue, -1.5) - 1;
+ case "BIMODAL" -> unitValue < 0.5 ? 0.1 + 0.2 * unitValue : 0.7 + 0.2 *
unitValue;
+ case "DUPLICATE_HEAVY" -> unitValue < 0.7 ? 0.1 : unitValue < 0.9 ? 0.5
: 0.9;
+ default -> throw new IllegalArgumentException("Unknown distribution: " +
distribution);
+ };
+ }
+
+ private static int[] indexes(int fanIn, String order) {
+ int[] indexes = new int[fanIn];
+ for (int i = 0; i < fanIn; i++) {
+ indexes[i] = i;
+ }
+ if (order.equals("REVERSED")) {
+ for (int i = 0; i < fanIn / 2; i++) {
+ int previous = indexes[i];
+ indexes[i] = indexes[fanIn - i - 1];
+ indexes[fanIn - i - 1] = previous;
+ }
+ } else if (order.equals("RANDOMIZED")) {
+ SplittableRandom random = new SplittableRandom(0xBADC0FFEE0DDF00DL +
fanIn);
+ for (int i = fanIn - 1; i > 0; i--) {
+ int index = random.nextInt(i + 1);
+ int previous = indexes[i];
+ indexes[i] = indexes[index];
+ indexes[index] = previous;
+ }
+ }
+ return indexes;
+ }
+
+ private static double rankError(double[] raw, double value, double quantile)
{
+ for (double observed : raw) {
+ if (Math.abs(observed - value) <= 1e-12 * Math.max(1,
Math.max(Math.abs(observed), Math.abs(value)))) {
+ value = observed;
+ break;
+ }
+ }
+ int lower = 0;
+ int upper = 0;
+ while (lower < raw.length && raw[lower] < value) {
+ lower++;
+ }
+ while (upper < raw.length && raw[upper] <= value) {
+ upper++;
+ }
+ return Math.max(0, Math.max((double) lower / raw.length - quantile,
quantile - (double) upper / raw.length));
+ }
+}
diff --git
a/compatibility-verifier/tdigest-compatibility/generate-rank-errors.sh
b/compatibility-verifier/tdigest-compatibility/generate-rank-errors.sh
new file mode 100755
index 00000000000..87fdea7dd15
--- /dev/null
+++ b/compatibility-verifier/tdigest-compatibility/generate-rank-errors.sh
@@ -0,0 +1,84 @@
+#!/usr/bin/env bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# Regenerate with the pinned legacy utility and 3.3 jar, then compare all case
keys, inputs and rank errors.
+# Use --update to replace the checked-in reference after intentionally
changing the seeded input corpus.
+set -euo pipefail
+# Match the unit-test workflow's Maven Central retry and connection settings,
including standalone runs.
+export MAVEN_OPTS="${MAVEN_OPTS:-}
-Dmaven.wagon.httpconnectionManager.ttlSeconds=25 \
+-Dmaven.wagon.http.retryHandler.count=30 -Dhttp.keepAlive=false
-Dmaven.wagon.http.pool=false"
+TDIGEST_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
+# CI checks this pinned reference on Ubuntu x86_64 with Temurin 25; see
../README.md for portability limits.
+TDIGEST_BASELINE=f818bae6d75a91228eb3aac95c921bca4aeb2128
+TDIGEST_WORK="$TDIGEST_ROOT/pinot-segment-local/target/tdigest-rank-oracle"
+TDIGEST_JAR_DIR="$TDIGEST_ROOT/pinot-segment-local/target/tdigest-legacy-reader"
+TDIGEST_JAR="$TDIGEST_JAR_DIR/t-digest-3.3.jar"
+TDIGEST_REFERENCE="$TDIGEST_ROOT/pinot-core/src/test/resources/data/tdigest-3.3-k1-rank-errors.csv"
+mkdir -p "$TDIGEST_WORK" "$TDIGEST_JAR_DIR"
+if ! git -C "$TDIGEST_ROOT" cat-file -e "$TDIGEST_BASELINE^{commit}"
2>/dev/null; then
+ # Keep shallow CI checkouts bounded without making a developer's full clone
shallow.
+ TDIGEST_FETCH_ARGS=(--no-tags)
+ if [[ "$(git -C "$TDIGEST_ROOT" rev-parse --is-shallow-repository)" == true
]]; then
+ TDIGEST_FETCH_ARGS+=(--depth=1)
+ fi
+ for TDIGEST_ATTEMPT in 1 2 3; do
+ if git -C "$TDIGEST_ROOT" -c http.lowSpeedLimit=1 -c http.lowSpeedTime=30 \
+ fetch "${TDIGEST_FETCH_ARGS[@]}" https://github.com/apache/pinot.git
"$TDIGEST_BASELINE"; then
+ break
+ fi
+ if [[ "$TDIGEST_ATTEMPT" == 3 ]]; then
+ exit 1
+ fi
+ sleep "$((TDIGEST_ATTEMPT * 5))"
+ done
+fi
+git -C "$TDIGEST_ROOT" show \
+
"$TDIGEST_BASELINE:pinot-segment-local/src/main/java/org/apache/pinot/segment/local/utils/TDigestUtils.java"
\
+ > "$TDIGEST_WORK/TDigestUtils.java"
+if [[ ! -s "$TDIGEST_JAR" ]]; then
+ # Resolve the legacy jar without requiring a locally installed Pinot BOM.
+ cat > "$TDIGEST_WORK/pom.xml" <<'POM'
+<project xmlns="http://maven.apache.org/POM/4.0.0">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.pinot.compatibility</groupId>
+ <artifactId>tdigest-rank-oracle</artifactId>
+ <version>1.0</version>
+</project>
+POM
+ "$TDIGEST_ROOT/mvnw" -f "$TDIGEST_WORK/pom.xml" -B -ntp \
+ org.apache.maven.plugins:maven-dependency-plugin:3.8.1:copy \
+ -Dartifact=com.tdunning:t-digest:3.3:jar
"-DoutputDirectory=$TDIGEST_JAR_DIR"
+fi
+javac -cp "$TDIGEST_JAR" -d "$TDIGEST_WORK" \
+ "$TDIGEST_WORK/TDigestUtils.java" \
+
"$TDIGEST_ROOT/compatibility-verifier/tdigest-compatibility/GenerateRankErrors.java"
+# The historical duplicate-boundary assertions abort otherwise valid seeded
3.3 cases.
+java -da -cp "$TDIGEST_WORK:$TDIGEST_JAR" GenerateRankErrors >
"$TDIGEST_WORK/rank-errors.csv"
+TDIGEST_CASE_COUNT="$(awk 'NF && $0 !~ /^#/ {count++} END {print count + 0}'
"$TDIGEST_WORK/rank-errors.csv")"
+if [[ "${1:-}" == --update ]]; then
+ sed '/^# mergeOrders=/,$d' "$TDIGEST_REFERENCE" >
"$TDIGEST_WORK/reference-header.csv"
+ cat "$TDIGEST_WORK/reference-header.csv" "$TDIGEST_WORK/rank-errors.csv" >
"$TDIGEST_REFERENCE"
+ printf 'Independent t-digest 3.3 oracle: reference updated (unverified); %s
case/input fingerprints and rank envelopes written\n' \
+ "$TDIGEST_CASE_COUNT"
+else
+ sed -n '/^# mergeOrders=/,$p' "$TDIGEST_REFERENCE" >
"$TDIGEST_WORK/checked-in-rank-errors.csv"
+ diff -u "$TDIGEST_WORK/checked-in-rank-errors.csv"
"$TDIGEST_WORK/rank-errors.csv"
+ printf 'Independent t-digest 3.3 oracle: %s case/input fingerprints and rank
envelopes verified\n' "$TDIGEST_CASE_COUNT"
+fi
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/PercentileSmartTDigestAggregationFunction.java
b/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/PercentileSmartTDigestAggregationFunction.java
index 062c1ca9252..c0a935d3923 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/PercentileSmartTDigestAggregationFunction.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/PercentileSmartTDigestAggregationFunction.java
@@ -36,6 +36,7 @@ import
org.apache.pinot.core.query.aggregation.AggregationResultHolder;
import org.apache.pinot.core.query.aggregation.ObjectAggregationResultHolder;
import org.apache.pinot.core.query.aggregation.groupby.GroupByResultHolder;
import
org.apache.pinot.core.query.aggregation.groupby.ObjectGroupByResultHolder;
+import org.apache.pinot.segment.local.customobject.tdigest.TDigestAccumulator;
import org.apache.pinot.segment.spi.AggregationFunctionType;
import org.apache.pinot.spi.data.FieldSpec.DataType;
@@ -184,7 +185,7 @@ public class PercentileSmartTDigestAggregationFunction
extends BaseSingleInputAg
}
private TDigest convertValueListToTDigest(DoubleArrayList valueList) {
- TDigest tDigest = new PercentileTDigestAccumulator(_compression);
+ TDigest tDigest = new TDigestAccumulator(_compression);
DoubleListIterator iterator = valueList.iterator();
while (iterator.hasNext()) {
tDigest.add(iterator.nextDouble());
@@ -295,11 +296,11 @@ public class PercentileSmartTDigestAggregationFunction
extends BaseSingleInputAg
@Override
public Object merge(Object intermediateResult1, Object intermediateResult2) {
- if (intermediateResult1 instanceof PercentileTDigestAccumulator) {
- return mergeIntoAccumulator((PercentileTDigestAccumulator)
intermediateResult1, intermediateResult2);
+ if (intermediateResult1 instanceof TDigestAccumulator) {
+ return mergeIntoAccumulator((TDigestAccumulator) intermediateResult1,
intermediateResult2);
}
- if (intermediateResult2 instanceof PercentileTDigestAccumulator) {
- return mergeIntoAccumulator((PercentileTDigestAccumulator)
intermediateResult2, intermediateResult1);
+ if (intermediateResult2 instanceof TDigestAccumulator) {
+ return mergeIntoAccumulator((TDigestAccumulator) intermediateResult2,
intermediateResult1);
}
DoubleArrayList valueList1 = (DoubleArrayList) intermediateResult1;
DoubleArrayList valueList2 = (DoubleArrayList) intermediateResult2;
@@ -307,7 +308,7 @@ public class PercentileSmartTDigestAggregationFunction
extends BaseSingleInputAg
return valueList1.size() > _threshold ?
convertValueListToTDigest(valueList1) : valueList1;
}
- private static PercentileTDigestAccumulator
mergeIntoAccumulator(PercentileTDigestAccumulator accumulator,
+ private static TDigestAccumulator mergeIntoAccumulator(TDigestAccumulator
accumulator,
Object intermediateResult) {
if (intermediateResult instanceof TDigest) {
accumulator.add((TDigest) intermediateResult);
@@ -342,7 +343,7 @@ public class PercentileSmartTDigestAggregationFunction
extends BaseSingleInputAg
if (customObject.getType() ==
ObjectSerDeUtils.ObjectType.TDigest.getValue()) {
// Generic TDigest deserialization returns a plain MergingDigest. Keep
this function's TDigest intermediates as
// accumulators so subsequent merges retain the capacity-preserving
serialization path.
- return
PercentileTDigestAccumulator.forSerializedTDigest(customObject.getBuffer());
+ return TDigestAccumulator.forSerializedTDigest(customObject.getBuffer());
}
return ObjectSerDeUtils.deserialize(customObject);
}
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/PercentileTDigestAggregationFunction.java
b/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/PercentileTDigestAggregationFunction.java
index 3c4f23b96fe..ea8fb75f8b2 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/PercentileTDigestAggregationFunction.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/PercentileTDigestAggregationFunction.java
@@ -30,6 +30,7 @@ import
org.apache.pinot.core.query.aggregation.AggregationResultHolder;
import org.apache.pinot.core.query.aggregation.ObjectAggregationResultHolder;
import org.apache.pinot.core.query.aggregation.groupby.GroupByResultHolder;
import
org.apache.pinot.core.query.aggregation.groupby.ObjectGroupByResultHolder;
+import org.apache.pinot.segment.local.customobject.tdigest.TDigestAccumulator;
import org.apache.pinot.segment.local.utils.TDigestUtils;
import org.apache.pinot.segment.spi.AggregationFunctionType;
import org.apache.pinot.segment.spi.Constants;
@@ -108,12 +109,12 @@ public class PercentileTDigestAggregationFunction extends
BaseSingleInputAggrega
if (blockValSet.getValueType() == DataType.BYTES) {
// Serialized TDigest
byte[][] bytesValues = blockValSet.getBytesValuesSV();
- PercentileTDigestAccumulator.SerializedTDigestInput input =
- new PercentileTDigestAccumulator.SerializedTDigestInput();
+ TDigestAccumulator.SerializedTDigestInput input =
+ new TDigestAccumulator.SerializedTDigestInput();
foldNotNull(length, blockValSet,
- (PercentileTDigestAccumulator) aggregationResultHolder.getResult(),
(current, from, toExclusive) -> {
+ (TDigestAccumulator) aggregationResultHolder.getResult(), (current,
from, toExclusive) -> {
if (current == null) {
- current =
PercentileTDigestAccumulator.forSerializedTDigestWithMergeBuffers(bytesValues[from]);
+ current =
TDigestAccumulator.forSerializedTDigestWithMergeBuffers(bytesValues[from]);
aggregationResultHolder.setValue(current);
}
for (int i = from; i < toExclusive; i++) {
@@ -135,13 +136,13 @@ public class PercentileTDigestAggregationFunction extends
BaseSingleInputAggrega
protected void aggregateSV(int length, AggregationResultHolder
aggregationResultHolder, BlockValSet blockValSet) {
double[] doubleValues = blockValSet.getDoubleValuesSV();
- PercentileTDigestAccumulator accumulator =
getAccumulator(aggregationResultHolder, _compressionFactor);
+ TDigestAccumulator accumulator = getAccumulator(aggregationResultHolder,
_compressionFactor);
forEachNotNull(length, blockValSet, (from, to) ->
accumulator.add(doubleValues, from, to));
}
protected void aggregateMV(int length, AggregationResultHolder
aggregationResultHolder, BlockValSet blockValSet) {
double[][] valuesArray = blockValSet.getDoubleValuesMV();
- PercentileTDigestAccumulator accumulator =
getAccumulator(aggregationResultHolder, _compressionFactor);
+ TDigestAccumulator accumulator = getAccumulator(aggregationResultHolder,
_compressionFactor);
forEachNotNull(length, blockValSet, (from, to) -> {
for (int i = from; i < to; i++) {
double[] values = valuesArray[i];
@@ -157,8 +158,8 @@ public class PercentileTDigestAggregationFunction extends
BaseSingleInputAggrega
if (blockValSet.getValueType() == DataType.BYTES) {
// Serialized TDigest
byte[][] bytesValues = blockValSet.getBytesValuesSV();
- PercentileTDigestAccumulator.SerializedTDigestInput input =
- new PercentileTDigestAccumulator.SerializedTDigestInput();
+ TDigestAccumulator.SerializedTDigestInput input =
+ new TDigestAccumulator.SerializedTDigestInput();
forEachNotNull(length, blockValSet, (from, to) -> {
for (int i = from; i < to; i++) {
int groupKey = groupKeyArray[i];
@@ -206,8 +207,8 @@ public class PercentileTDigestAggregationFunction extends
BaseSingleInputAggrega
if (blockValSet.getValueType() == DataType.BYTES) {
// Serialized TDigest
byte[][] bytesValues = blockValSet.getBytesValuesSV();
- PercentileTDigestAccumulator.SerializedTDigestInput input =
- new PercentileTDigestAccumulator.SerializedTDigestInput();
+ TDigestAccumulator.SerializedTDigestInput input =
+ new TDigestAccumulator.SerializedTDigestInput();
forEachNotNull(length, blockValSet, (from, to) -> {
for (int i = from; i < to; i++) {
int[] groupKeys = groupKeysArray[i];
@@ -277,12 +278,12 @@ public class PercentileTDigestAggregationFunction extends
BaseSingleInputAggrega
if (intermediateResult2.size() == 0L) {
return intermediateResult1;
}
- if (intermediateResult1 instanceof PercentileTDigestAccumulator) {
+ if (intermediateResult1 instanceof TDigestAccumulator) {
intermediateResult1.add(intermediateResult2);
return intermediateResult1;
}
- PercentileTDigestAccumulator accumulator =
-
PercentileTDigestAccumulator.forReduction(intermediateResult1.compression());
+ TDigestAccumulator accumulator =
+ TDigestAccumulator.forReduction(intermediateResult1.compression());
accumulator.add(intermediateResult1);
accumulator.add(intermediateResult2);
return accumulator;
@@ -293,7 +294,7 @@ public class PercentileTDigestAggregationFunction extends
BaseSingleInputAggrega
/// Segment merge-and-rollup uses this method because its configured output
compression can differ from the
/// compression stored in either input digest.
public TDigest mergeWithConfiguredCompression(TDigest intermediateResult1,
TDigest intermediateResult2) {
- PercentileTDigestAccumulator accumulator =
PercentileTDigestAccumulator.forReduction(_compressionFactor);
+ TDigestAccumulator accumulator =
TDigestAccumulator.forReduction(_compressionFactor);
accumulator.add(intermediateResult1);
accumulator.add(intermediateResult2);
accumulator.compress();
@@ -313,7 +314,7 @@ public class PercentileTDigestAggregationFunction extends
BaseSingleInputAggrega
@Override
public TDigest deserializeIntermediateResult(CustomObject customObject) {
- return
PercentileTDigestAccumulator.forSerializedTDigest(customObject.getBuffer());
+ return TDigestAccumulator.forSerializedTDigest(customObject.getBuffer());
}
@Override
@@ -360,21 +361,21 @@ public class PercentileTDigestAggregationFunction extends
BaseSingleInputAggrega
return tDigest;
}
- private static PercentileTDigestAccumulator
getAccumulator(AggregationResultHolder aggregationResultHolder,
+ private static TDigestAccumulator getAccumulator(AggregationResultHolder
aggregationResultHolder,
int compressionFactor) {
- PercentileTDigestAccumulator accumulator =
aggregationResultHolder.getResult();
+ TDigestAccumulator accumulator = aggregationResultHolder.getResult();
if (accumulator == null) {
- accumulator = new PercentileTDigestAccumulator(compressionFactor);
+ accumulator = new TDigestAccumulator(compressionFactor);
aggregationResultHolder.setValue(accumulator);
}
return accumulator;
}
- private static PercentileTDigestAccumulator
getSerializedAccumulator(GroupByResultHolder groupByResultHolder,
- int groupKey, PercentileTDigestAccumulator.SerializedTDigestInput input)
{
- PercentileTDigestAccumulator accumulator =
groupByResultHolder.getResult(groupKey);
+ private static TDigestAccumulator
getSerializedAccumulator(GroupByResultHolder groupByResultHolder,
+ int groupKey, TDigestAccumulator.SerializedTDigestInput input) {
+ TDigestAccumulator accumulator = groupByResultHolder.getResult(groupKey);
if (accumulator == null) {
- accumulator = PercentileTDigestAccumulator.forSerializedTDigest(input);
+ accumulator = TDigestAccumulator.forSerializedTDigest(input);
groupByResultHolder.setValueForKey(groupKey, accumulator);
}
return accumulator;
@@ -390,7 +391,7 @@ public class PercentileTDigestAggregationFunction extends
BaseSingleInputAggrega
int compressionFactor) {
TDigest tDigest = groupByResultHolder.getResult(groupKey);
if (tDigest == null) {
- tDigest = new PercentileTDigestAccumulator(compressionFactor);
+ tDigest = new TDigestAccumulator(compressionFactor);
groupByResultHolder.setValueForKey(groupKey, tDigest);
}
return tDigest;
diff --git
a/pinot-core/src/test/java/org/apache/pinot/core/query/aggregation/function/PercentileRawTDigestAggregationFunctionTest.java
b/pinot-core/src/test/java/org/apache/pinot/core/query/aggregation/function/PercentileRawTDigestAggregationFunctionTest.java
index 277809b12ea..a96af39b46b 100644
---
a/pinot-core/src/test/java/org/apache/pinot/core/query/aggregation/function/PercentileRawTDigestAggregationFunctionTest.java
+++
b/pinot-core/src/test/java/org/apache/pinot/core/query/aggregation/function/PercentileRawTDigestAggregationFunctionTest.java
@@ -25,6 +25,7 @@ import org.apache.pinot.common.CustomObject;
import org.apache.pinot.common.request.context.ExpressionContext;
import org.apache.pinot.core.common.ObjectSerDeUtils;
import org.apache.pinot.segment.local.customobject.SerializedTDigest;
+import org.apache.pinot.segment.local.customobject.tdigest.TDigestAccumulator;
import org.apache.pinot.spi.utils.BytesUtils;
import org.testng.annotations.Test;
@@ -33,7 +34,7 @@ import static org.testng.Assert.assertTrue;
/// Tests that the final result of `percentileRawTDigest` stays readable by a
plain t-digest
-/// [MergingDigest#fromBytes] reader when the intermediate
[PercentileTDigestAccumulator] holds
+/// [MergingDigest#fromBytes] reader when the intermediate
[TDigestAccumulator] holds
/// capacity-preserving state (a digest with more centroids than a freshly
allocated
/// [MergingDigest] of the same compression can hold).
public class PercentileRawTDigestAggregationFunctionTest {
@@ -53,7 +54,7 @@ public class PercentileRawTDigestAggregationFunctionTest {
new PercentileRawTDigestAggregationFunction(EXPRESSION, 50.0, (int)
compression, false);
TDigest intermediateResult = function.deserializeIntermediateResult(
new CustomObject(ObjectSerDeUtils.ObjectType.TDigest.getValue(),
ByteBuffer.wrap(small)));
- assertTrue(intermediateResult instanceof PercentileTDigestAccumulator);
+ assertTrue(intermediateResult instanceof TDigestAccumulator);
SerializedTDigest finalResult =
function.extractFinalResult(intermediateResult);
byte[] serialized = BytesUtils.toBytes(finalResult.toString());
@@ -106,7 +107,7 @@ public class PercentileRawTDigestAggregationFunctionTest {
byte[] verbose = createVerboseUnitCentroidDigest(51, 20.0);
TDigest intermediateResult = function.deserializeIntermediateResult(
new CustomObject(ObjectSerDeUtils.ObjectType.TDigest.getValue(),
ByteBuffer.wrap(verbose)));
- assertTrue(intermediateResult instanceof PercentileTDigestAccumulator);
+ assertTrue(intermediateResult instanceof TDigestAccumulator);
SerializedTDigest finalResult =
function.extractFinalResult(intermediateResult);
byte[] serialized = BytesUtils.toBytes(finalResult.toString());
diff --git
a/pinot-core/src/test/java/org/apache/pinot/core/query/aggregation/function/PercentileSmartTDigestAggregationFunctionTest.java
b/pinot-core/src/test/java/org/apache/pinot/core/query/aggregation/function/PercentileSmartTDigestAggregationFunctionTest.java
index c1f67b24f3a..3ac51525ea1 100644
---
a/pinot-core/src/test/java/org/apache/pinot/core/query/aggregation/function/PercentileSmartTDigestAggregationFunctionTest.java
+++
b/pinot-core/src/test/java/org/apache/pinot/core/query/aggregation/function/PercentileSmartTDigestAggregationFunctionTest.java
@@ -33,6 +33,7 @@ import org.apache.pinot.core.common.ObjectSerDeUtils;
import org.apache.pinot.core.common.SyntheticBlockValSets;
import org.apache.pinot.core.query.aggregation.AggregationResultHolder;
import
org.apache.pinot.core.query.aggregation.groupby.ObjectGroupByResultHolder;
+import org.apache.pinot.segment.local.customobject.tdigest.TDigestAccumulator;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
@@ -49,7 +50,7 @@ public class PercentileSmartTDigestAggregationFunctionTest {
byte[] verbose =
PercentileRawTDigestAggregationFunctionTest.createVerboseUnitCentroidDigest(51,
20.0);
Object intermediateResult = function.deserializeIntermediateResult(
new CustomObject(ObjectSerDeUtils.ObjectType.TDigest.getValue(),
ByteBuffer.wrap(verbose)));
- assertTrue(intermediateResult instanceof PercentileTDigestAccumulator);
+ assertTrue(intermediateResult instanceof TDigestAccumulator);
AggregationFunction.SerializedIntermediateResult serialized =
function.serializeIntermediateResult(intermediateResult);
@@ -58,12 +59,12 @@ public class PercentileSmartTDigestAggregationFunctionTest {
Object roundTripped = function.deserializeIntermediateResult(
new CustomObject(serialized.getType(),
ByteBuffer.wrap(serialized.getBytes())));
- assertTrue(roundTripped instanceof PercentileTDigestAccumulator);
+ assertTrue(roundTripped instanceof TDigestAccumulator);
assertUnitCentroidDigest((TDigest) roundTripped, 51, 20.0);
assertLegacyCompatibleShape(function.serializeIntermediateResult(roundTripped).getBytes(),
20.0);
}
- /// The intermediate result must round-trip through the
[PercentileTDigestAccumulator] so that
+ /// The intermediate result must round-trip through the [TDigestAccumulator]
so that
/// capacity-preserving digests (more centroids than a fresh legacy
[MergingDigest] of the same
/// compression can hold) are not re-encoded into bytes a receiving server
cannot read.
@Test
@@ -75,7 +76,7 @@ public class PercentileSmartTDigestAggregationFunctionTest {
Object intermediateResult = function.deserializeIntermediateResult(
new CustomObject(ObjectSerDeUtils.ObjectType.TDigest.getValue(),
ByteBuffer.wrap(small)));
- assertTrue(intermediateResult instanceof PercentileTDigestAccumulator);
+ assertTrue(intermediateResult instanceof TDigestAccumulator);
AggregationFunction.SerializedIntermediateResult serialized =
function.serializeIntermediateResult(intermediateResult);
@@ -91,7 +92,7 @@ public class PercentileSmartTDigestAggregationFunctionTest {
new CustomObject(serialized.getType(),
ByteBuffer.wrap(serialized.getBytes()))),
function.deserializeIntermediateResult(
new CustomObject(serialized.getType(),
ByteBuffer.wrap(serialized.getBytes()))));
- assertTrue(merged instanceof PercentileTDigestAccumulator);
+ assertTrue(merged instanceof TDigestAccumulator);
assertEquals(((TDigest) merged).size(), 2L * numCentroids);
// The materialized (merged) accumulator must also serialize into
plain-reader-compatible bytes.
@@ -139,7 +140,7 @@ public class PercentileSmartTDigestAggregationFunctionTest {
DoubleArrayList valueList = new DoubleArrayList(new double[]{0.0, 25.0,
50.0});
Object merged = accumulatorFirst ? function.merge(accumulator, valueList)
: function.merge(valueList, accumulator);
- assertTrue(merged instanceof PercentileTDigestAccumulator);
+ assertTrue(merged instanceof TDigestAccumulator);
assertEquals(((TDigest) merged).size(), numCentroids + 3L);
assertEquals(((TDigest) merged).quantile(0.5), (numCentroids - 1.0) /
2.0, 1.0);
TDigest roundTripped = MergingDigest.fromBytes(
@@ -161,7 +162,7 @@ public class PercentileSmartTDigestAggregationFunctionTest {
function.aggregate(values.length, resultHolder,
Map.of(EXPRESSION, SyntheticBlockValSets.Double.create(null, values)));
Object intermediateResult =
function.extractAggregationResult(resultHolder);
- assertTrue(intermediateResult instanceof PercentileTDigestAccumulator);
+ assertTrue(intermediateResult instanceof TDigestAccumulator);
TDigest result = (TDigest) intermediateResult;
assertDuplicateInfinityResult(result, values.length);
TDigest roundTripped = ObjectSerDeUtils.TDIGEST_SER_DE.deserialize(
@@ -175,7 +176,7 @@ public class PercentileSmartTDigestAggregationFunctionTest {
Object second = function.deserializeIntermediateResult(
new CustomObject(serialized.getType(),
ByteBuffer.wrap(serialized.getBytes())));
Object merged = function.merge(first, second);
- assertTrue(merged instanceof PercentileTDigestAccumulator);
+ assertTrue(merged instanceof TDigestAccumulator);
assertDuplicateInfinityResult((TDigest) merged, 2L * values.length);
}
diff --git
a/pinot-core/src/test/java/org/apache/pinot/core/query/aggregation/function/PercentileTDigestAggregationFunctionTest.java
b/pinot-core/src/test/java/org/apache/pinot/core/query/aggregation/function/PercentileTDigestAggregationFunctionTest.java
index cc96299ed40..ef2d3055c1e 100644
---
a/pinot-core/src/test/java/org/apache/pinot/core/query/aggregation/function/PercentileTDigestAggregationFunctionTest.java
+++
b/pinot-core/src/test/java/org/apache/pinot/core/query/aggregation/function/PercentileTDigestAggregationFunctionTest.java
@@ -37,6 +37,7 @@ import org.apache.pinot.core.common.SyntheticBlockValSets;
import org.apache.pinot.core.query.aggregation.AggregationResultHolder;
import
org.apache.pinot.core.query.aggregation.function.AggregationFunction.SerializedIntermediateResult;
import org.apache.pinot.core.query.aggregation.groupby.GroupByResultHolder;
+import org.apache.pinot.segment.local.customobject.tdigest.TDigestAccumulator;
import org.apache.pinot.segment.local.utils.TDigestUtils;
import org.apache.pinot.segment.spi.Constants;
import org.apache.pinot.spi.data.FieldSpec.DataType;
@@ -69,7 +70,7 @@ public class PercentileTDigestAggregationFunctionTest {
Map.of(EXPRESSION, SyntheticBlockValSets.Double.create(null, values)));
TDigest result = function.extractAggregationResult(resultHolder);
- Assert.assertTrue(result instanceof PercentileTDigestAccumulator);
+ Assert.assertTrue(result instanceof TDigestAccumulator);
Assert.assertEquals(result.size(), numRows);
Assert.assertEquals(result.compression(),
PercentileTDigestAggregationFunction.DEFAULT_TDIGEST_COMPRESSION);
if (numRows == 0) {
@@ -187,7 +188,7 @@ public class PercentileTDigestAggregationFunctionTest {
@Test
public void testReverseMergeDoesNotTreatSignedZeroAsSameSign() {
- PercentileTDigestAccumulator accumulator = new
PercentileTDigestAccumulator(10);
+ TDigestAccumulator accumulator = new TDigestAccumulator(10);
accumulator.add(-0.0);
accumulator.compress();
accumulator.add(0.0);
@@ -235,7 +236,7 @@ public class PercentileTDigestAggregationFunctionTest {
double[] values = new double[2 * repetitions];
Arrays.fill(values, 0, repetitions, Double.NEGATIVE_INFINITY);
Arrays.fill(values, repetitions, values.length, Double.POSITIVE_INFINITY);
- PercentileTDigestAccumulator accumulator = new
PercentileTDigestAccumulator(20);
+ TDigestAccumulator accumulator = new TDigestAccumulator(20);
accumulator.add(values, 0, values.length);
double previous = Double.NEGATIVE_INFINITY;
@@ -272,10 +273,10 @@ public class PercentileTDigestAggregationFunctionTest {
shifted.putDouble(1.0);
shifted.putDouble(100.0);
- PercentileTDigestAccumulator actual =
PercentileTDigestAccumulator.forReduction(20.0);
+ TDigestAccumulator actual = TDigestAccumulator.forReduction(20.0);
actual.addSerializedTDigest(legacy.array());
actual.addSerializedTDigest(shifted.array());
- PercentileTDigestAccumulator expected = new
PercentileTDigestAccumulator(20);
+ TDigestAccumulator expected = new TDigestAccumulator(20);
expected.add(new double[]{0.0, 2.0, 10.0, -100.0, 100.0}, 0, 5);
Assert.assertEquals(actual.size(), 5L);
@@ -297,13 +298,13 @@ public class PercentileTDigestAggregationFunctionTest {
long expectedSize = (long) numDigests * valuesPerDigest;
double expectedPercentile = 0.75;
for (TDigest result : new TDigest[]{verboseResult, smallResult}) {
- Assert.assertTrue(result instanceof PercentileTDigestAccumulator);
+ Assert.assertTrue(result instanceof TDigestAccumulator);
Assert.assertEquals(result.size(), expectedSize);
Assert.assertEquals(result.compression(), 100.0);
Assert.assertEquals(result.quantile(0.75), expectedPercentile, 0.005);
Assert.assertEquals(result.getMin(), 0.0);
Assert.assertEquals(result.getMax(), (expectedSize - 1.0) /
expectedSize, 0.000_001);
- Assert.assertTrue(((PercentileTDigestAccumulator) result).toTDigest()
instanceof MergingDigest);
+ Assert.assertTrue(((TDigestAccumulator) result).toTDigest() instanceof
MergingDigest);
}
// The compact source narrows centroids to floats and can take a different
valid merge path. Both results are
// independently bounded against the exact percentile above, so keep their
cross-encoding envelope equally tight.
@@ -464,10 +465,10 @@ public class PercentileTDigestAggregationFunctionTest {
function.aggregateGroupByMV(values.length, groupKeys, resultHolder,
Map.of(EXPRESSION, bytesBlockValSet(values, null)));
- PercentileTDigestAccumulator pendingAccumulator =
resultHolder.getResult(3);
+ TDigestAccumulator pendingAccumulator = resultHolder.getResult(3);
for (String fieldName
: new String[]{"_rawValues", "_centroidMeans", "_outputMeans",
"_incomingMeans"}) {
- Field field =
PercentileTDigestAccumulator.class.getDeclaredField(fieldName);
+ Field field = TDigestAccumulator.class.getDeclaredField(fieldName);
field.setAccessible(true);
Assert.assertNull(field.get(pendingAccumulator));
}
@@ -562,7 +563,7 @@ public class PercentileTDigestAggregationFunctionTest {
/// range guard (every `NaN` comparison is false) and propagate through the
computation.
@Test
public void testQuantileRejectsNaN() {
- PercentileTDigestAccumulator accumulator =
PercentileTDigestAccumulator.forReduction(100.0);
+ TDigestAccumulator accumulator = TDigestAccumulator.forReduction(100.0);
accumulator.add(1.0);
IllegalArgumentException exception =
Assert.expectThrows(IllegalArgumentException.class, () ->
accumulator.quantile(Double.NaN));
@@ -574,7 +575,7 @@ public class PercentileTDigestAggregationFunctionTest {
@Test
public void testCentroidsSaturateWeightExceedingIntegerMaxValue()
throws ReflectiveOperationException {
- PercentileTDigestAccumulator accumulator =
PercentileTDigestAccumulator.forReduction(100.0);
+ TDigestAccumulator accumulator = TDigestAccumulator.forReduction(100.0);
accumulator.add(1.0);
accumulator.compress();
@@ -605,14 +606,14 @@ public class PercentileTDigestAggregationFunctionTest {
oneCentroid.putFloat(1.0F);
TDigest empty = TDigest.createMergingDigest(20.0);
byte[] emptyBytes = ObjectSerDeUtils.TDIGEST_SER_DE.serialize(empty);
- PercentileTDigestAccumulator accumulator =
PercentileTDigestAccumulator.forSerializedTDigest(emptyBytes);
+ TDigestAccumulator accumulator =
TDigestAccumulator.forSerializedTDigest(emptyBytes);
accumulator.addSerializedTDigest(emptyBytes);
- PercentileTDigestAccumulator.SerializedTDigestInput input =
- new PercentileTDigestAccumulator.SerializedTDigestInput();
+ TDigestAccumulator.SerializedTDigestInput input =
+ new TDigestAccumulator.SerializedTDigestInput();
input.reset(oneCentroid.array());
accumulator.addSerializedTDigest(input);
- Field meansField =
PercentileTDigestAccumulator.SerializedTDigestInput.class.getDeclaredField("_means");
+ Field meansField =
TDigestAccumulator.SerializedTDigestInput.class.getDeclaredField("_means");
meansField.setAccessible(true);
Assert.assertEquals(((double[]) meansField.get(input)).length, 3);
Assert.assertEquals(accumulator.toTDigest().size(), 1L);
@@ -622,10 +623,10 @@ public class PercentileTDigestAggregationFunctionTest {
public void testSerializedAccumulatorAllocatesRawBufferLazily()
throws ReflectiveOperationException {
byte[] serializedDigest = createSerializedDigests(1, 100, 100.0, ignored
-> false)[0];
- Field rawValuesField =
PercentileTDigestAccumulator.class.getDeclaredField("_rawValues");
+ Field rawValuesField =
TDigestAccumulator.class.getDeclaredField("_rawValues");
rawValuesField.setAccessible(true);
- PercentileTDigestAccumulator accumulator =
PercentileTDigestAccumulator.forSerializedTDigest(serializedDigest);
+ TDigestAccumulator accumulator =
TDigestAccumulator.forSerializedTDigest(serializedDigest);
Assert.assertNull(rawValuesField.get(accumulator));
accumulator.add(new double[0], 0, 0);
Assert.assertNull(rawValuesField.get(accumulator));
@@ -641,18 +642,18 @@ public class PercentileTDigestAggregationFunctionTest {
Assert.assertEquals(result.getMin(), 0.0);
Assert.assertEquals(result.getMax(), 1.0);
Assert.assertNull(rawValuesField.get(
-
PercentileTDigestAccumulator.forSerializedTDigestWithMergeBuffers(serializedDigest)));
- Assert.assertNotNull(rawValuesField.get(new
PercentileTDigestAccumulator(100)));
+
TDigestAccumulator.forSerializedTDigestWithMergeBuffers(serializedDigest)));
+ Assert.assertNotNull(rawValuesField.get(new TDigestAccumulator(100)));
}
@Test
public void testDirectMergeAtConfiguredCompressionIsNotRepeated()
throws ReflectiveOperationException {
byte[][] serializedDigests = createSerializedDigests(2, 100, 100.0,
ignored -> false);
- PercentileTDigestAccumulator accumulator =
-
PercentileTDigestAccumulator.forSerializedTDigestWithMergeBuffers(serializedDigests[0]);
- PercentileTDigestAccumulator.SerializedTDigestInput input =
- new PercentileTDigestAccumulator.SerializedTDigestInput();
+ TDigestAccumulator accumulator =
+
TDigestAccumulator.forSerializedTDigestWithMergeBuffers(serializedDigests[0]);
+ TDigestAccumulator.SerializedTDigestInput input =
+ new TDigestAccumulator.SerializedTDigestInput();
for (byte[] serializedDigest : serializedDigests) {
input.reset(serializedDigest);
accumulator.addSerializedTDigestDirect(input);
@@ -670,8 +671,8 @@ public class PercentileTDigestAggregationFunctionTest {
TDigest serializedDigest = TDigest.createMergingDigest(100.0);
serializedDigest.add(-1.0);
byte[] serializedBytes =
ObjectSerDeUtils.TDIGEST_SER_DE.serialize(serializedDigest);
- PercentileTDigestAccumulator accumulator =
- PercentileTDigestAccumulator.forSerializedTDigest(serializedBytes);
+ TDigestAccumulator accumulator =
+ TDigestAccumulator.forSerializedTDigest(serializedBytes);
accumulator.addSerializedTDigest(serializedBytes);
double[] rawValues = new double[768];
@@ -693,7 +694,7 @@ public class PercentileTDigestAggregationFunctionTest {
TDigest third = TDigest.createMergingDigest(40.0);
third.add(1.0);
byte[] firstBytes = ObjectSerDeUtils.TDIGEST_SER_DE.serialize(first);
- PercentileTDigestAccumulator accumulator =
PercentileTDigestAccumulator.forSerializedTDigest(firstBytes);
+ TDigestAccumulator accumulator =
TDigestAccumulator.forSerializedTDigest(firstBytes);
accumulator.addSerializedTDigest(firstBytes);
accumulator.addSerializedTDigest(ObjectSerDeUtils.TDIGEST_SER_DE.serialize(second));
accumulator.addSerializedTDigest(ObjectSerDeUtils.TDIGEST_SER_DE.serialize(third));
@@ -830,7 +831,7 @@ public class PercentileTDigestAggregationFunctionTest {
Assert.assertEquals(result.getMin(), 0.0);
Assert.assertEquals(result.getMax(), numCentroids - 1.0);
- byte[] serialized = ((PercentileTDigestAccumulator) result).serialize();
+ byte[] serialized = ((TDigestAccumulator) result).serialize();
TDigest roundTripped =
ObjectSerDeUtils.TDIGEST_SER_DE.deserialize(serialized);
Assert.assertEquals(roundTripped.size(), numCentroids);
Assert.assertEquals(roundTripped.compression(), compression);
@@ -843,7 +844,7 @@ public class PercentileTDigestAggregationFunctionTest {
public void
testPendingLowCompressionDigestSerializesWithLegacyCompatibleCapacity() {
int numCentroids = 51;
byte[] verbose = createVerboseUnitCentroidDigest(numCentroids, 20.0);
- PercentileTDigestAccumulator accumulator =
PercentileTDigestAccumulator.forSerializedTDigest(verbose);
+ TDigestAccumulator accumulator =
TDigestAccumulator.forSerializedTDigest(verbose);
accumulator.addSerializedTDigest(verbose);
ByteBuffer serialized = ByteBuffer.wrap(accumulator.serialize());
@@ -871,7 +872,7 @@ public class PercentileTDigestAggregationFunctionTest {
throws ReflectiveOperationException {
int centroidCount = 51;
double min = 1.0e18;
- PercentileTDigestAccumulator accumulator = new
PercentileTDigestAccumulator(20);
+ TDigestAccumulator accumulator = new TDigestAccumulator(20);
double[] means = new double[70];
double[] weights = new double[70];
for (int i = 0; i < centroidCount; i++) {
@@ -900,7 +901,7 @@ public class PercentileTDigestAggregationFunctionTest {
@Test
public void testCentroidInspectionPreservesWeightedHighMagnitudeMean() {
- PercentileTDigestAccumulator accumulator = new
PercentileTDigestAccumulator(100);
+ TDigestAccumulator accumulator = new TDigestAccumulator(100);
accumulator.add(1.0e308, 2);
long weight = 0L;
@@ -1218,15 +1219,15 @@ public class PercentileTDigestAggregationFunctionTest {
private static void assertPendingSerializedDigestOwnsInputBytes(boolean
reusableInput) {
byte[] bytes = createVerboseUnitCentroidDigest(3, 20.0);
byte[] expected = bytes.clone();
- PercentileTDigestAccumulator accumulator;
+ TDigestAccumulator accumulator;
if (reusableInput) {
- PercentileTDigestAccumulator.SerializedTDigestInput input =
- new PercentileTDigestAccumulator.SerializedTDigestInput();
+ TDigestAccumulator.SerializedTDigestInput input =
+ new TDigestAccumulator.SerializedTDigestInput();
input.reset(bytes);
- accumulator = PercentileTDigestAccumulator.forSerializedTDigest(input);
+ accumulator = TDigestAccumulator.forSerializedTDigest(input);
accumulator.addSerializedTDigest(input);
} else {
- accumulator = PercentileTDigestAccumulator.forSerializedTDigest(bytes);
+ accumulator = TDigestAccumulator.forSerializedTDigest(bytes);
accumulator.addSerializedTDigest(bytes);
}
@@ -1251,20 +1252,20 @@ public class PercentileTDigestAggregationFunctionTest {
}
private static void assertSerializedAccumulatorState(GroupByResultHolder
resultHolder, int groupKey) {
- Assert.assertTrue(resultHolder.getResult(groupKey) instanceof
PercentileTDigestAccumulator);
+ Assert.assertTrue(resultHolder.getResult(groupKey) instanceof
TDigestAccumulator);
}
private static void assertGroupResult(PercentileTDigestAggregationFunction
function,
GroupByResultHolder resultHolder, int groupKey, long expectedSize,
double expectedCompression,
double expectedMin, double expectedMax) {
TDigest result = function.extractGroupByResult(resultHolder, groupKey);
- Assert.assertTrue(result instanceof PercentileTDigestAccumulator);
+ Assert.assertTrue(result instanceof TDigestAccumulator);
Assert.assertEquals(result.size(), expectedSize);
Assert.assertEquals(result.compression(), expectedCompression);
Assert.assertEquals(result.getMin(), expectedMin);
Assert.assertEquals(result.getMax(), expectedMax);
Assert.assertEquals(result.quantile(0.75), 0.75, 0.02);
- Assert.assertTrue(((PercentileTDigestAccumulator) result).toTDigest()
instanceof MergingDigest);
+ Assert.assertTrue(((TDigestAccumulator) result).toTDigest() instanceof
MergingDigest);
}
private static void assertValidReducerResult(TDigest result, double[]
sortedValues, String caseDescription) {
@@ -1456,16 +1457,16 @@ public class PercentileTDigestAggregationFunctionTest {
DISTRIBUTED
}
- private static void setAccumulatorField(PercentileTDigestAccumulator
accumulator, String name, Object value)
+ private static void setAccumulatorField(TDigestAccumulator accumulator,
String name, Object value)
throws ReflectiveOperationException {
- Field field = PercentileTDigestAccumulator.class.getDeclaredField(name);
+ Field field = TDigestAccumulator.class.getDeclaredField(name);
field.setAccessible(true);
field.set(accumulator, value);
}
- private static Object getAccumulatorField(PercentileTDigestAccumulator
accumulator, String name)
+ private static Object getAccumulatorField(TDigestAccumulator accumulator,
String name)
throws ReflectiveOperationException {
- Field field = PercentileTDigestAccumulator.class.getDeclaredField(name);
+ Field field = TDigestAccumulator.class.getDeclaredField(name);
field.setAccessible(true);
return field.get(accumulator);
}
diff --git a/pinot-core/src/test/resources/data/tdigest-3.3-k1-rank-errors.csv
b/pinot-core/src/test/resources/data/tdigest-3.3-k1-rank-errors.csv
new file mode 100644
index 00000000000..b0cf21bcfdd
--- /dev/null
+++ b/pinot-core/src/test/resources/data/tdigest-3.3-k1-rank-errors.csv
@@ -0,0 +1,299 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Independent com.tdunning:t-digest:3.3 K_1 reference, using Pinot's
f818bae6d7 TDigestUtils.
+# Each of the 270 rows retains its merge order and input type. SHA-256 covers
sorted raw big-endian IEEE 754
+# doubles followed by the actual merge permutation's big-endian int source
indices. Tests fingerprint the same
+# index array used by their merge loop before applying the six rank bounds.
+# StrictMath.pow keeps seeded distribution doubles identical across platforms
and JVM execution modes.
+# Generated with -da because historical 3.3 duplicate-boundary assertions
abort valid cases.
+# Regenerate/check from any checkout, including shallow CI, with JDK 25 and
isolated pinned legacy dependencies:
+# bash compatibility-verifier/tdigest-compatibility/generate-rank-errors.sh
+# Append --update only when intentionally regenerating the frozen legacy
references.
+# key,inputSha256,p0,p50,p75,p95,p99,p100
+# mergeOrders=ORIGINAL,REVERSED,RANDOMIZED
+# reducerInputs=SERVER_LOCAL,DISTRIBUTED
+8/20/UNIFORM/ORIGINAL/SERVER_LOCAL,2b5b6395ffa7e214706925409b5b17907d1394bdaddc97121b4e81e9ef4095ad,0.0,0.00390625,0.0,0.004687499999999956,0.004140625000000009,0.0
+8/20/UNIFORM/ORIGINAL/DISTRIBUTED,2b5b6395ffa7e214706925409b5b17907d1394bdaddc97121b4e81e9ef4095ad,0.0,0.00390625,0.0,0.004687499999999956,0.004140625000000009,0.0
+8/20/UNIFORM/REVERSED/SERVER_LOCAL,61940b53f2ed756b5dfe438c073befb8be99f47fec2a4e213685c966c8e8a7bd,0.0,0.00390625,0.0,0.0027343749999999556,0.004140625000000009,0.0
+8/20/UNIFORM/REVERSED/DISTRIBUTED,61940b53f2ed756b5dfe438c073befb8be99f47fec2a4e213685c966c8e8a7bd,0.0,0.00390625,0.0,0.004687499999999956,0.004140625000000009,0.0
+8/20/UNIFORM/RANDOMIZED/SERVER_LOCAL,acbf987573d16bc0aebf381c97767840c5d5f3d244014b365c19ef47034be91d,0.0,0.00390625,0.0,0.004687499999999956,0.004140625000000009,0.0
+8/20/UNIFORM/RANDOMIZED/DISTRIBUTED,acbf987573d16bc0aebf381c97767840c5d5f3d244014b365c19ef47034be91d,0.0,0.00390625,0.0,0.004687499999999956,0.004140625000000009,0.0
+8/20/SKEWED/ORIGINAL/SERVER_LOCAL,4cb59cc45eca0fd1948229e35041ce1806bad967d00d3d3b97c4ccc7ee05d641,0.0,0.0390625,0.0234375,7.812499999999556E-4,0.004140625000000009,0.0
+8/20/SKEWED/ORIGINAL/DISTRIBUTED,4cb59cc45eca0fd1948229e35041ce1806bad967d00d3d3b97c4ccc7ee05d641,0.0,0.037109375,0.0234375,7.812499999999556E-4,0.004140625000000009,0.0
+8/20/SKEWED/REVERSED/SERVER_LOCAL,5daf0134b4fbd17276e71de030268323e5ab879c1e85ef5082db8d88ce24584e,0.0,0.03125,0.021484375,7.812499999999556E-4,0.004140625000000009,0.0
+8/20/SKEWED/REVERSED/DISTRIBUTED,5daf0134b4fbd17276e71de030268323e5ab879c1e85ef5082db8d88ce24584e,0.0,0.037109375,0.0234375,7.812499999999556E-4,0.004140625000000009,0.0
+8/20/SKEWED/RANDOMIZED/SERVER_LOCAL,57415cd78f35601a7aa0fb48fda6c89425966168a2a94f858da818b9ce9e280f,0.0,0.037109375,0.02734375,7.812499999999556E-4,0.004140625000000009,0.0
+8/20/SKEWED/RANDOMIZED/DISTRIBUTED,57415cd78f35601a7aa0fb48fda6c89425966168a2a94f858da818b9ce9e280f,0.0,0.037109375,0.0234375,7.812499999999556E-4,0.004140625000000009,0.0
+8/20/HEAVY_TAIL/ORIGINAL/SERVER_LOCAL,d01786a3ce7703c93efa43ffa9ca70c7edde66d215c79c60f4434fa7a35bc798,0.0,0.021484375,0.02734375,0.007031250000000044,0.004140625000000009,0.0
+8/20/HEAVY_TAIL/ORIGINAL/DISTRIBUTED,d01786a3ce7703c93efa43ffa9ca70c7edde66d215c79c60f4434fa7a35bc798,0.0,0.017578125,0.02734375,0.008984375000000044,0.004140625000000009,0.0
+8/20/HEAVY_TAIL/REVERSED/SERVER_LOCAL,1223f5fc93c733e23feb346661e01fdf1a2608ef49d027ee0877cc2acc7aa7c7,0.0,0.01953125,0.029296875,0.007031250000000044,0.004140625000000009,0.0
+8/20/HEAVY_TAIL/REVERSED/DISTRIBUTED,1223f5fc93c733e23feb346661e01fdf1a2608ef49d027ee0877cc2acc7aa7c7,0.0,0.017578125,0.02734375,0.008984375000000044,0.004140625000000009,0.0
+8/20/HEAVY_TAIL/RANDOMIZED/SERVER_LOCAL,e1a9a5a05ab95785ca0ff35355a0c76ce4f62676d96f857362f2bdaa62063c8e,0.0,0.025390625,0.03125,0.0031250000000000444,0.004140625000000009,0.0
+8/20/HEAVY_TAIL/RANDOMIZED/DISTRIBUTED,e1a9a5a05ab95785ca0ff35355a0c76ce4f62676d96f857362f2bdaa62063c8e,0.0,0.017578125,0.02734375,0.008984375000000044,0.004140625000000009,0.0
+8/20/BIMODAL/ORIGINAL/SERVER_LOCAL,0ca1cd3fe07a1c873f7f3d5e1c665e9cc2a11195bd27d43280d35009562a5750,0.0,0.037109375,0.001953125,0.004687499999999956,0.004140625000000009,0.0
+8/20/BIMODAL/ORIGINAL/DISTRIBUTED,0ca1cd3fe07a1c873f7f3d5e1c665e9cc2a11195bd27d43280d35009562a5750,0.0,0.037109375,0.0,0.004687499999999956,0.004140625000000009,0.0
+8/20/BIMODAL/REVERSED/SERVER_LOCAL,9188cf9b88e121a658c0510d621a5d45134bc34aeda3710dcf31183e98fe91e2,0.0,0.037109375,0.0,0.0027343749999999556,0.004140625000000009,0.0
+8/20/BIMODAL/REVERSED/DISTRIBUTED,9188cf9b88e121a658c0510d621a5d45134bc34aeda3710dcf31183e98fe91e2,0.0,0.037109375,0.0,0.004687499999999956,0.004140625000000009,0.0
+8/20/BIMODAL/RANDOMIZED/SERVER_LOCAL,f789fd297b097be0b22badc7d457d5f9c52ad641064c2e07a3b69a7a7f602ed2,0.0,0.037109375,0.0,0.004687499999999956,0.004140625000000009,0.0
+8/20/BIMODAL/RANDOMIZED/DISTRIBUTED,f789fd297b097be0b22badc7d457d5f9c52ad641064c2e07a3b69a7a7f602ed2,0.0,0.037109375,0.0,0.004687499999999956,0.004140625000000009,0.0
+8/20/DUPLICATE_HEAVY/ORIGINAL/SERVER_LOCAL,0f1c85935deffad7c224de76f2574b8bc35d44b093c858f0e6caefe2dd01bf19,0.0,0.0,0.033203125,0.037890624999999956,0.0,0.0
+8/20/DUPLICATE_HEAVY/ORIGINAL/DISTRIBUTED,0f1c85935deffad7c224de76f2574b8bc35d44b093c858f0e6caefe2dd01bf19,0.0,0.0,0.033203125,0.037890624999999956,0.0,0.0
+8/20/DUPLICATE_HEAVY/REVERSED/SERVER_LOCAL,e9f78e16c71be29d24f0b15897dc912deff1e00d50bd2fb42c3ba2bcba99dc4c,0.0,0.0,0.033203125,0.037890624999999956,0.0,0.0
+8/20/DUPLICATE_HEAVY/REVERSED/DISTRIBUTED,e9f78e16c71be29d24f0b15897dc912deff1e00d50bd2fb42c3ba2bcba99dc4c,0.0,0.0,0.033203125,0.037890624999999956,0.0,0.0
+8/20/DUPLICATE_HEAVY/RANDOMIZED/SERVER_LOCAL,db1f0bf3082f467a83f5b537104a9c9cdcefcaa6f3c33730e02dfc6cb1c80c65,0.0,0.0,0.033203125,0.037890624999999956,0.0,0.0
+8/20/DUPLICATE_HEAVY/RANDOMIZED/DISTRIBUTED,db1f0bf3082f467a83f5b537104a9c9cdcefcaa6f3c33730e02dfc6cb1c80c65,0.0,0.0,0.033203125,0.037890624999999956,0.0,0.0
+8/100/UNIFORM/ORIGINAL/SERVER_LOCAL,2b5b6395ffa7e214706925409b5b17907d1394bdaddc97121b4e81e9ef4095ad,0.0,0.0,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/UNIFORM/ORIGINAL/DISTRIBUTED,2b5b6395ffa7e214706925409b5b17907d1394bdaddc97121b4e81e9ef4095ad,0.0,0.0,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/UNIFORM/REVERSED/SERVER_LOCAL,61940b53f2ed756b5dfe438c073befb8be99f47fec2a4e213685c966c8e8a7bd,0.0,0.0,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/UNIFORM/REVERSED/DISTRIBUTED,61940b53f2ed756b5dfe438c073befb8be99f47fec2a4e213685c966c8e8a7bd,0.0,0.0,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/UNIFORM/RANDOMIZED/SERVER_LOCAL,acbf987573d16bc0aebf381c97767840c5d5f3d244014b365c19ef47034be91d,0.0,0.00390625,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/UNIFORM/RANDOMIZED/DISTRIBUTED,acbf987573d16bc0aebf381c97767840c5d5f3d244014b365c19ef47034be91d,0.0,0.0,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/SKEWED/ORIGINAL/SERVER_LOCAL,4cb59cc45eca0fd1948229e35041ce1806bad967d00d3d3b97c4ccc7ee05d641,0.0,0.00390625,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/SKEWED/ORIGINAL/DISTRIBUTED,4cb59cc45eca0fd1948229e35041ce1806bad967d00d3d3b97c4ccc7ee05d641,0.0,0.00390625,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/SKEWED/REVERSED/SERVER_LOCAL,5daf0134b4fbd17276e71de030268323e5ab879c1e85ef5082db8d88ce24584e,0.0,0.00390625,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/SKEWED/REVERSED/DISTRIBUTED,5daf0134b4fbd17276e71de030268323e5ab879c1e85ef5082db8d88ce24584e,0.0,0.00390625,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/SKEWED/RANDOMIZED/SERVER_LOCAL,57415cd78f35601a7aa0fb48fda6c89425966168a2a94f858da818b9ce9e280f,0.0,0.00390625,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/SKEWED/RANDOMIZED/DISTRIBUTED,57415cd78f35601a7aa0fb48fda6c89425966168a2a94f858da818b9ce9e280f,0.0,0.00390625,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/HEAVY_TAIL/ORIGINAL/SERVER_LOCAL,d01786a3ce7703c93efa43ffa9ca70c7edde66d215c79c60f4434fa7a35bc798,0.0,0.00390625,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/HEAVY_TAIL/ORIGINAL/DISTRIBUTED,d01786a3ce7703c93efa43ffa9ca70c7edde66d215c79c60f4434fa7a35bc798,0.0,0.00390625,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/HEAVY_TAIL/REVERSED/SERVER_LOCAL,1223f5fc93c733e23feb346661e01fdf1a2608ef49d027ee0877cc2acc7aa7c7,0.0,0.00390625,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/HEAVY_TAIL/REVERSED/DISTRIBUTED,1223f5fc93c733e23feb346661e01fdf1a2608ef49d027ee0877cc2acc7aa7c7,0.0,0.00390625,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/HEAVY_TAIL/RANDOMIZED/SERVER_LOCAL,e1a9a5a05ab95785ca0ff35355a0c76ce4f62676d96f857362f2bdaa62063c8e,0.0,0.00390625,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/HEAVY_TAIL/RANDOMIZED/DISTRIBUTED,e1a9a5a05ab95785ca0ff35355a0c76ce4f62676d96f857362f2bdaa62063c8e,0.0,0.00390625,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/BIMODAL/ORIGINAL/SERVER_LOCAL,0ca1cd3fe07a1c873f7f3d5e1c665e9cc2a11195bd27d43280d35009562a5750,0.0,0.0,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/BIMODAL/ORIGINAL/DISTRIBUTED,0ca1cd3fe07a1c873f7f3d5e1c665e9cc2a11195bd27d43280d35009562a5750,0.0,0.0,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/BIMODAL/REVERSED/SERVER_LOCAL,9188cf9b88e121a658c0510d621a5d45134bc34aeda3710dcf31183e98fe91e2,0.0,0.0,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/BIMODAL/REVERSED/DISTRIBUTED,9188cf9b88e121a658c0510d621a5d45134bc34aeda3710dcf31183e98fe91e2,0.0,0.0,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/BIMODAL/RANDOMIZED/SERVER_LOCAL,f789fd297b097be0b22badc7d457d5f9c52ad641064c2e07a3b69a7a7f602ed2,0.0,0.00390625,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/BIMODAL/RANDOMIZED/DISTRIBUTED,f789fd297b097be0b22badc7d457d5f9c52ad641064c2e07a3b69a7a7f602ed2,0.0,0.0,0.0,7.812499999999556E-4,2.3437500000000888E-4,0.0
+8/100/DUPLICATE_HEAVY/ORIGINAL/SERVER_LOCAL,0f1c85935deffad7c224de76f2574b8bc35d44b093c858f0e6caefe2dd01bf19,0.0,0.0,0.0,0.0,0.0,0.0
+8/100/DUPLICATE_HEAVY/ORIGINAL/DISTRIBUTED,0f1c85935deffad7c224de76f2574b8bc35d44b093c858f0e6caefe2dd01bf19,0.0,0.0,0.0,0.0,0.0,0.0
+8/100/DUPLICATE_HEAVY/REVERSED/SERVER_LOCAL,e9f78e16c71be29d24f0b15897dc912deff1e00d50bd2fb42c3ba2bcba99dc4c,0.0,0.0,0.0,0.0,0.0,0.0
+8/100/DUPLICATE_HEAVY/REVERSED/DISTRIBUTED,e9f78e16c71be29d24f0b15897dc912deff1e00d50bd2fb42c3ba2bcba99dc4c,0.0,0.0,0.0,0.0,0.0,0.0
+8/100/DUPLICATE_HEAVY/RANDOMIZED/SERVER_LOCAL,db1f0bf3082f467a83f5b537104a9c9cdcefcaa6f3c33730e02dfc6cb1c80c65,0.0,0.0,0.0,0.0,0.0,0.0
+8/100/DUPLICATE_HEAVY/RANDOMIZED/DISTRIBUTED,db1f0bf3082f467a83f5b537104a9c9cdcefcaa6f3c33730e02dfc6cb1c80c65,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/UNIFORM/ORIGINAL/SERVER_LOCAL,2b5b6395ffa7e214706925409b5b17907d1394bdaddc97121b4e81e9ef4095ad,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/UNIFORM/ORIGINAL/DISTRIBUTED,2b5b6395ffa7e214706925409b5b17907d1394bdaddc97121b4e81e9ef4095ad,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/UNIFORM/REVERSED/SERVER_LOCAL,61940b53f2ed756b5dfe438c073befb8be99f47fec2a4e213685c966c8e8a7bd,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/UNIFORM/REVERSED/DISTRIBUTED,61940b53f2ed756b5dfe438c073befb8be99f47fec2a4e213685c966c8e8a7bd,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/UNIFORM/RANDOMIZED/SERVER_LOCAL,acbf987573d16bc0aebf381c97767840c5d5f3d244014b365c19ef47034be91d,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/UNIFORM/RANDOMIZED/DISTRIBUTED,acbf987573d16bc0aebf381c97767840c5d5f3d244014b365c19ef47034be91d,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/SKEWED/ORIGINAL/SERVER_LOCAL,4cb59cc45eca0fd1948229e35041ce1806bad967d00d3d3b97c4ccc7ee05d641,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/SKEWED/ORIGINAL/DISTRIBUTED,4cb59cc45eca0fd1948229e35041ce1806bad967d00d3d3b97c4ccc7ee05d641,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/SKEWED/REVERSED/SERVER_LOCAL,5daf0134b4fbd17276e71de030268323e5ab879c1e85ef5082db8d88ce24584e,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/SKEWED/REVERSED/DISTRIBUTED,5daf0134b4fbd17276e71de030268323e5ab879c1e85ef5082db8d88ce24584e,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/SKEWED/RANDOMIZED/SERVER_LOCAL,57415cd78f35601a7aa0fb48fda6c89425966168a2a94f858da818b9ce9e280f,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/SKEWED/RANDOMIZED/DISTRIBUTED,57415cd78f35601a7aa0fb48fda6c89425966168a2a94f858da818b9ce9e280f,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/HEAVY_TAIL/ORIGINAL/SERVER_LOCAL,d01786a3ce7703c93efa43ffa9ca70c7edde66d215c79c60f4434fa7a35bc798,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/HEAVY_TAIL/ORIGINAL/DISTRIBUTED,d01786a3ce7703c93efa43ffa9ca70c7edde66d215c79c60f4434fa7a35bc798,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/HEAVY_TAIL/REVERSED/SERVER_LOCAL,1223f5fc93c733e23feb346661e01fdf1a2608ef49d027ee0877cc2acc7aa7c7,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/HEAVY_TAIL/REVERSED/DISTRIBUTED,1223f5fc93c733e23feb346661e01fdf1a2608ef49d027ee0877cc2acc7aa7c7,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/HEAVY_TAIL/RANDOMIZED/SERVER_LOCAL,e1a9a5a05ab95785ca0ff35355a0c76ce4f62676d96f857362f2bdaa62063c8e,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/HEAVY_TAIL/RANDOMIZED/DISTRIBUTED,e1a9a5a05ab95785ca0ff35355a0c76ce4f62676d96f857362f2bdaa62063c8e,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/BIMODAL/ORIGINAL/SERVER_LOCAL,0ca1cd3fe07a1c873f7f3d5e1c665e9cc2a11195bd27d43280d35009562a5750,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/BIMODAL/ORIGINAL/DISTRIBUTED,0ca1cd3fe07a1c873f7f3d5e1c665e9cc2a11195bd27d43280d35009562a5750,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/BIMODAL/REVERSED/SERVER_LOCAL,9188cf9b88e121a658c0510d621a5d45134bc34aeda3710dcf31183e98fe91e2,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/BIMODAL/REVERSED/DISTRIBUTED,9188cf9b88e121a658c0510d621a5d45134bc34aeda3710dcf31183e98fe91e2,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/BIMODAL/RANDOMIZED/SERVER_LOCAL,f789fd297b097be0b22badc7d457d5f9c52ad641064c2e07a3b69a7a7f602ed2,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/BIMODAL/RANDOMIZED/DISTRIBUTED,f789fd297b097be0b22badc7d457d5f9c52ad641064c2e07a3b69a7a7f602ed2,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/DUPLICATE_HEAVY/ORIGINAL/SERVER_LOCAL,0f1c85935deffad7c224de76f2574b8bc35d44b093c858f0e6caefe2dd01bf19,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/DUPLICATE_HEAVY/ORIGINAL/DISTRIBUTED,0f1c85935deffad7c224de76f2574b8bc35d44b093c858f0e6caefe2dd01bf19,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/DUPLICATE_HEAVY/REVERSED/SERVER_LOCAL,e9f78e16c71be29d24f0b15897dc912deff1e00d50bd2fb42c3ba2bcba99dc4c,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/DUPLICATE_HEAVY/REVERSED/DISTRIBUTED,e9f78e16c71be29d24f0b15897dc912deff1e00d50bd2fb42c3ba2bcba99dc4c,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/DUPLICATE_HEAVY/RANDOMIZED/SERVER_LOCAL,db1f0bf3082f467a83f5b537104a9c9cdcefcaa6f3c33730e02dfc6cb1c80c65,0.0,0.0,0.0,0.0,0.0,0.0
+8/1000/DUPLICATE_HEAVY/RANDOMIZED/DISTRIBUTED,db1f0bf3082f467a83f5b537104a9c9cdcefcaa6f3c33730e02dfc6cb1c80c65,0.0,0.0,0.0,0.0,0.0,0.0
+32/20/UNIFORM/ORIGINAL/SERVER_LOCAL,61dcc0d7c9c5cd9c7afb2a19267ebb6cc3da43857063fed35615d7351c35a416,0.0,0.001953125,0.00146484375,0.008593749999999956,2.539062499999911E-4,0.0
+32/20/UNIFORM/ORIGINAL/DISTRIBUTED,61dcc0d7c9c5cd9c7afb2a19267ebb6cc3da43857063fed35615d7351c35a416,0.0,0.001953125,0.0,0.005175781249999956,7.421874999999911E-4,0.0
+32/20/UNIFORM/REVERSED/SERVER_LOCAL,c7a294e37a336c0af8a4f268b7c45756e738e4651ea1523a82352f9587ee13fe,0.0,0.00341796875,0.001953125,0.007128906249999956,7.421874999999911E-4,0.0
+32/20/UNIFORM/REVERSED/DISTRIBUTED,c7a294e37a336c0af8a4f268b7c45756e738e4651ea1523a82352f9587ee13fe,0.0,0.001953125,0.0,0.007617187499999956,7.421874999999911E-4,0.0
+32/20/UNIFORM/RANDOMIZED/SERVER_LOCAL,178be1f39ac1a1ec4497586a908922a5f699bf3c6ba27886a10afc7c9115ca39,0.0,0.0029296875,0.00146484375,0.007617187499999956,7.421874999999911E-4,0.0
+32/20/UNIFORM/RANDOMIZED/DISTRIBUTED,178be1f39ac1a1ec4497586a908922a5f699bf3c6ba27886a10afc7c9115ca39,0.0,0.001953125,0.0,0.005175781249999956,7.421874999999911E-4,0.0
+32/20/SKEWED/ORIGINAL/SERVER_LOCAL,a9f93e503602c95b1950b0f480643dca8cea190bab0788da611b15f79fad4c4e,0.0,0.04150390625,0.02392578125,0.0032226562499999556,7.226562500000089E-4,0.0
+32/20/SKEWED/ORIGINAL/DISTRIBUTED,a9f93e503602c95b1950b0f480643dca8cea190bab0788da611b15f79fad4c4e,0.0,0.0498046875,0.01416015625,0.0012695312499999556,7.421874999999911E-4,0.0
+32/20/SKEWED/REVERSED/SERVER_LOCAL,5e20b25666ff63a398c3a17e9cbdf2dfbb2e6a0fa3f6277f141f732a34f5f109,0.0,0.04736328125,0.01953125,0.0012695312499999556,7.421874999999911E-4,0.0
+32/20/SKEWED/REVERSED/DISTRIBUTED,5e20b25666ff63a398c3a17e9cbdf2dfbb2e6a0fa3f6277f141f732a34f5f109,0.0,0.05078125,0.017578125,0.0027343749999999556,7.421874999999911E-4,0.0
+32/20/SKEWED/RANDOMIZED/SERVER_LOCAL,52311840957c5fecf25a07e5c64d33018fc0a66a835f4978e74a900980efef86,0.0,0.03857421875,0.021484375,0.0027343749999999556,7.226562500000089E-4,0.0
+32/20/SKEWED/RANDOMIZED/DISTRIBUTED,52311840957c5fecf25a07e5c64d33018fc0a66a835f4978e74a900980efef86,0.0,0.0498046875,0.01220703125,0.0012695312499999556,7.421874999999911E-4,0.0
+32/20/HEAVY_TAIL/ORIGINAL/SERVER_LOCAL,6579efd3a84f03c357f68cce51ed22a73a888d747837aa82f5a35b039a27f22d,0.0,0.02099609375,0.0224609375,0.0031250000000000444,0.006582031250000009,0.0
+32/20/HEAVY_TAIL/ORIGINAL/DISTRIBUTED,6579efd3a84f03c357f68cce51ed22a73a888d747837aa82f5a35b039a27f22d,0.0,0.013671875,0.01611328125,0.006542968750000044,0.004628906250000009,0.0
+32/20/HEAVY_TAIL/REVERSED/SERVER_LOCAL,0348e15f1214558db9beada262ed7726941c6593fc513905dcf300ef7bf346d3,0.0,0.01904296875,0.0166015625,0.008007812500000044,0.002675781250000009,0.0
+32/20/HEAVY_TAIL/REVERSED/DISTRIBUTED,0348e15f1214558db9beada262ed7726941c6593fc513905dcf300ef7bf346d3,0.0,0.0205078125,0.02099609375,0.007031250000000044,0.002675781250000009,0.0
+32/20/HEAVY_TAIL/RANDOMIZED/SERVER_LOCAL,6800f740e089980df898f4dbc94b00deccdbb44ad9b734fb4ac8aa978b07a6a2,0.0,0.02099609375,0.02197265625,0.0031250000000000444,0.006582031250000009,0.0
+32/20/HEAVY_TAIL/RANDOMIZED/DISTRIBUTED,6800f740e089980df898f4dbc94b00deccdbb44ad9b734fb4ac8aa978b07a6a2,0.0,0.0146484375,0.029296875,0.006542968750000044,0.003652343750000009,0.0
+32/20/BIMODAL/ORIGINAL/SERVER_LOCAL,c87fe88267dd4d4832f35f4ed91ece2ac61e0f7772effd66f9c77a5278f55a83,0.0,0.01513671875,0.001953125,0.008593749999999956,2.539062499999911E-4,0.0
+32/20/BIMODAL/ORIGINAL/DISTRIBUTED,c87fe88267dd4d4832f35f4ed91ece2ac61e0f7772effd66f9c77a5278f55a83,0.0,0.01513671875,0.0,0.005175781249999956,7.421874999999911E-4,0.0
+32/20/BIMODAL/REVERSED/SERVER_LOCAL,d3e0fcbac5cc9a577e33b91176ad78c30fe1be382738d465c1629bd73276e25f,0.0,0.01513671875,0.001953125,0.007128906249999956,7.421874999999911E-4,0.0
+32/20/BIMODAL/REVERSED/DISTRIBUTED,d3e0fcbac5cc9a577e33b91176ad78c30fe1be382738d465c1629bd73276e25f,0.0,0.01513671875,0.0,0.007617187499999956,7.421874999999911E-4,0.0
+32/20/BIMODAL/RANDOMIZED/SERVER_LOCAL,335862b837f3ee5d73d45d42b96a49a9103af76762b9e72e8ea5a71ba450daad,0.0,0.01513671875,0.00146484375,0.007617187499999956,7.421874999999911E-4,0.0
+32/20/BIMODAL/RANDOMIZED/DISTRIBUTED,335862b837f3ee5d73d45d42b96a49a9103af76762b9e72e8ea5a71ba450daad,0.0,0.01513671875,0.0,0.005175781249999956,7.421874999999911E-4,0.0
+32/20/DUPLICATE_HEAVY/ORIGINAL/SERVER_LOCAL,d189b096392386698724b5def27646e3e6072f17a08d1bfc2134e2013ba16f71,0.0,0.0,0.0341796875,0.047167968749999956,0.0,0.0
+32/20/DUPLICATE_HEAVY/ORIGINAL/DISTRIBUTED,d189b096392386698724b5def27646e3e6072f17a08d1bfc2134e2013ba16f71,0.0,0.2158203125,0.0341796875,0.047167968749999956,0.0,0.0
+32/20/DUPLICATE_HEAVY/REVERSED/SERVER_LOCAL,a6c82c5287ecd813421305a1f3c050dda19d155da98768604b5c738eefce5648,0.0,0.2158203125,0.0341796875,0.047167968749999956,0.0,0.0
+32/20/DUPLICATE_HEAVY/REVERSED/DISTRIBUTED,a6c82c5287ecd813421305a1f3c050dda19d155da98768604b5c738eefce5648,0.0,0.2158203125,0.0341796875,0.047167968749999956,0.0,0.0
+32/20/DUPLICATE_HEAVY/RANDOMIZED/SERVER_LOCAL,6c551072e7fa6127ecb3de46f07cc2229f61ab2c94395abd5ff92932dae886c7,0.0,0.2158203125,0.0341796875,0.047167968749999956,0.0,0.0
+32/20/DUPLICATE_HEAVY/RANDOMIZED/DISTRIBUTED,6c551072e7fa6127ecb3de46f07cc2229f61ab2c94395abd5ff92932dae886c7,0.0,0.2158203125,0.0341796875,0.047167968749999956,0.0,0.0
+32/100/UNIFORM/ORIGINAL/SERVER_LOCAL,61dcc0d7c9c5cd9c7afb2a19267ebb6cc3da43857063fed35615d7351c35a416,0.0,0.0,4.8828125E-4,0.0011718750000000444,7.421874999999911E-4,0.0
+32/100/UNIFORM/ORIGINAL/DISTRIBUTED,61dcc0d7c9c5cd9c7afb2a19267ebb6cc3da43857063fed35615d7351c35a416,0.0,4.8828125E-4,4.8828125E-4,0.0011718750000000444,7.421874999999911E-4,0.0
+32/100/UNIFORM/REVERSED/SERVER_LOCAL,c7a294e37a336c0af8a4f268b7c45756e738e4651ea1523a82352f9587ee13fe,0.0,0.0,4.8828125E-4,6.835937500000444E-4,7.421874999999911E-4,0.0
+32/100/UNIFORM/REVERSED/DISTRIBUTED,c7a294e37a336c0af8a4f268b7c45756e738e4651ea1523a82352f9587ee13fe,0.0,0.0,4.8828125E-4,6.835937500000444E-4,7.421874999999911E-4,0.0
+32/100/UNIFORM/RANDOMIZED/SERVER_LOCAL,178be1f39ac1a1ec4497586a908922a5f699bf3c6ba27886a10afc7c9115ca39,0.0,0.0,9.765625E-4,0.0011718750000000444,7.421874999999911E-4,0.0
+32/100/UNIFORM/RANDOMIZED/DISTRIBUTED,178be1f39ac1a1ec4497586a908922a5f699bf3c6ba27886a10afc7c9115ca39,0.0,4.8828125E-4,9.765625E-4,0.0011718750000000444,7.421874999999911E-4,0.0
+32/100/SKEWED/ORIGINAL/SERVER_LOCAL,a9f93e503602c95b1950b0f480643dca8cea190bab0788da611b15f79fad4c4e,0.0,0.001953125,0.00146484375,0.0011718750000000444,7.421874999999911E-4,0.0
+32/100/SKEWED/ORIGINAL/DISTRIBUTED,a9f93e503602c95b1950b0f480643dca8cea190bab0788da611b15f79fad4c4e,0.0,0.001953125,0.001953125,0.0011718750000000444,7.421874999999911E-4,0.0
+32/100/SKEWED/REVERSED/SERVER_LOCAL,5e20b25666ff63a398c3a17e9cbdf2dfbb2e6a0fa3f6277f141f732a34f5f109,0.0,0.001953125,0.001953125,0.0011718750000000444,7.421874999999911E-4,0.0
+32/100/SKEWED/REVERSED/DISTRIBUTED,5e20b25666ff63a398c3a17e9cbdf2dfbb2e6a0fa3f6277f141f732a34f5f109,0.0,0.001953125,0.001953125,0.0011718750000000444,7.421874999999911E-4,0.0
+32/100/SKEWED/RANDOMIZED/SERVER_LOCAL,52311840957c5fecf25a07e5c64d33018fc0a66a835f4978e74a900980efef86,0.0,0.001953125,0.001953125,0.0011718750000000444,7.421874999999911E-4,0.0
+32/100/SKEWED/RANDOMIZED/DISTRIBUTED,52311840957c5fecf25a07e5c64d33018fc0a66a835f4978e74a900980efef86,0.0,0.001953125,0.001953125,0.0011718750000000444,7.421874999999911E-4,0.0
+32/100/HEAVY_TAIL/ORIGINAL/SERVER_LOCAL,6579efd3a84f03c357f68cce51ed22a73a888d747837aa82f5a35b039a27f22d,0.0,4.8828125E-4,0.00146484375,0.0011718750000000444,7.226562500000089E-4,0.0
+32/100/HEAVY_TAIL/ORIGINAL/DISTRIBUTED,6579efd3a84f03c357f68cce51ed22a73a888d747837aa82f5a35b039a27f22d,0.0,4.8828125E-4,0.001953125,0.0011718750000000444,7.226562500000089E-4,0.0
+32/100/HEAVY_TAIL/REVERSED/SERVER_LOCAL,0348e15f1214558db9beada262ed7726941c6593fc513905dcf300ef7bf346d3,0.0,4.8828125E-4,0.001953125,0.0011718750000000444,7.226562500000089E-4,0.0
+32/100/HEAVY_TAIL/REVERSED/DISTRIBUTED,0348e15f1214558db9beada262ed7726941c6593fc513905dcf300ef7bf346d3,0.0,4.8828125E-4,0.001953125,0.0011718750000000444,7.226562500000089E-4,0.0
+32/100/HEAVY_TAIL/RANDOMIZED/SERVER_LOCAL,6800f740e089980df898f4dbc94b00deccdbb44ad9b734fb4ac8aa978b07a6a2,0.0,4.8828125E-4,0.001953125,0.0011718750000000444,7.226562500000089E-4,0.0
+32/100/HEAVY_TAIL/RANDOMIZED/DISTRIBUTED,6800f740e089980df898f4dbc94b00deccdbb44ad9b734fb4ac8aa978b07a6a2,0.0,4.8828125E-4,0.001953125,0.0011718750000000444,7.226562500000089E-4,0.0
+32/100/BIMODAL/ORIGINAL/SERVER_LOCAL,c87fe88267dd4d4832f35f4ed91ece2ac61e0f7772effd66f9c77a5278f55a83,0.0,0.01513671875,4.8828125E-4,0.0011718750000000444,7.421874999999911E-4,0.0
+32/100/BIMODAL/ORIGINAL/DISTRIBUTED,c87fe88267dd4d4832f35f4ed91ece2ac61e0f7772effd66f9c77a5278f55a83,0.0,0.01513671875,4.8828125E-4,0.0011718750000000444,7.421874999999911E-4,0.0
+32/100/BIMODAL/REVERSED/SERVER_LOCAL,d3e0fcbac5cc9a577e33b91176ad78c30fe1be382738d465c1629bd73276e25f,0.0,0.01513671875,0.0,0.0011718750000000444,7.421874999999911E-4,0.0
+32/100/BIMODAL/REVERSED/DISTRIBUTED,d3e0fcbac5cc9a577e33b91176ad78c30fe1be382738d465c1629bd73276e25f,0.0,0.01513671875,4.8828125E-4,6.835937500000444E-4,7.421874999999911E-4,0.0
+32/100/BIMODAL/RANDOMIZED/SERVER_LOCAL,335862b837f3ee5d73d45d42b96a49a9103af76762b9e72e8ea5a71ba450daad,0.0,0.01513671875,9.765625E-4,0.0011718750000000444,7.421874999999911E-4,0.0
+32/100/BIMODAL/RANDOMIZED/DISTRIBUTED,335862b837f3ee5d73d45d42b96a49a9103af76762b9e72e8ea5a71ba450daad,0.0,0.01513671875,9.765625E-4,0.0011718750000000444,7.421874999999911E-4,0.0
+32/100/DUPLICATE_HEAVY/ORIGINAL/SERVER_LOCAL,d189b096392386698724b5def27646e3e6072f17a08d1bfc2134e2013ba16f71,0.0,0.0,0.0,0.0,0.0,0.0
+32/100/DUPLICATE_HEAVY/ORIGINAL/DISTRIBUTED,d189b096392386698724b5def27646e3e6072f17a08d1bfc2134e2013ba16f71,0.0,0.0,0.0,0.0,0.0,0.0
+32/100/DUPLICATE_HEAVY/REVERSED/SERVER_LOCAL,a6c82c5287ecd813421305a1f3c050dda19d155da98768604b5c738eefce5648,0.0,0.0,0.0341796875,0.0,0.0,0.0
+32/100/DUPLICATE_HEAVY/REVERSED/DISTRIBUTED,a6c82c5287ecd813421305a1f3c050dda19d155da98768604b5c738eefce5648,0.0,0.0,0.0,0.0,0.0,0.0
+32/100/DUPLICATE_HEAVY/RANDOMIZED/SERVER_LOCAL,6c551072e7fa6127ecb3de46f07cc2229f61ab2c94395abd5ff92932dae886c7,0.0,0.0,0.0341796875,0.0,0.0,0.0
+32/100/DUPLICATE_HEAVY/RANDOMIZED/DISTRIBUTED,6c551072e7fa6127ecb3de46f07cc2229f61ab2c94395abd5ff92932dae886c7,0.0,0.0,0.0,0.0,0.0,0.0
+32/1000/UNIFORM/ORIGINAL/SERVER_LOCAL,61dcc0d7c9c5cd9c7afb2a19267ebb6cc3da43857063fed35615d7351c35a416,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/UNIFORM/ORIGINAL/DISTRIBUTED,61dcc0d7c9c5cd9c7afb2a19267ebb6cc3da43857063fed35615d7351c35a416,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/UNIFORM/REVERSED/SERVER_LOCAL,c7a294e37a336c0af8a4f268b7c45756e738e4651ea1523a82352f9587ee13fe,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/UNIFORM/REVERSED/DISTRIBUTED,c7a294e37a336c0af8a4f268b7c45756e738e4651ea1523a82352f9587ee13fe,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/UNIFORM/RANDOMIZED/SERVER_LOCAL,178be1f39ac1a1ec4497586a908922a5f699bf3c6ba27886a10afc7c9115ca39,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/UNIFORM/RANDOMIZED/DISTRIBUTED,178be1f39ac1a1ec4497586a908922a5f699bf3c6ba27886a10afc7c9115ca39,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/SKEWED/ORIGINAL/SERVER_LOCAL,a9f93e503602c95b1950b0f480643dca8cea190bab0788da611b15f79fad4c4e,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/SKEWED/ORIGINAL/DISTRIBUTED,a9f93e503602c95b1950b0f480643dca8cea190bab0788da611b15f79fad4c4e,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/SKEWED/REVERSED/SERVER_LOCAL,5e20b25666ff63a398c3a17e9cbdf2dfbb2e6a0fa3f6277f141f732a34f5f109,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/SKEWED/REVERSED/DISTRIBUTED,5e20b25666ff63a398c3a17e9cbdf2dfbb2e6a0fa3f6277f141f732a34f5f109,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/SKEWED/RANDOMIZED/SERVER_LOCAL,52311840957c5fecf25a07e5c64d33018fc0a66a835f4978e74a900980efef86,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/SKEWED/RANDOMIZED/DISTRIBUTED,52311840957c5fecf25a07e5c64d33018fc0a66a835f4978e74a900980efef86,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/HEAVY_TAIL/ORIGINAL/SERVER_LOCAL,6579efd3a84f03c357f68cce51ed22a73a888d747837aa82f5a35b039a27f22d,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/HEAVY_TAIL/ORIGINAL/DISTRIBUTED,6579efd3a84f03c357f68cce51ed22a73a888d747837aa82f5a35b039a27f22d,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/HEAVY_TAIL/REVERSED/SERVER_LOCAL,0348e15f1214558db9beada262ed7726941c6593fc513905dcf300ef7bf346d3,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/HEAVY_TAIL/REVERSED/DISTRIBUTED,0348e15f1214558db9beada262ed7726941c6593fc513905dcf300ef7bf346d3,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/HEAVY_TAIL/RANDOMIZED/SERVER_LOCAL,6800f740e089980df898f4dbc94b00deccdbb44ad9b734fb4ac8aa978b07a6a2,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/HEAVY_TAIL/RANDOMIZED/DISTRIBUTED,6800f740e089980df898f4dbc94b00deccdbb44ad9b734fb4ac8aa978b07a6a2,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/BIMODAL/ORIGINAL/SERVER_LOCAL,c87fe88267dd4d4832f35f4ed91ece2ac61e0f7772effd66f9c77a5278f55a83,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/BIMODAL/ORIGINAL/DISTRIBUTED,c87fe88267dd4d4832f35f4ed91ece2ac61e0f7772effd66f9c77a5278f55a83,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/BIMODAL/REVERSED/SERVER_LOCAL,d3e0fcbac5cc9a577e33b91176ad78c30fe1be382738d465c1629bd73276e25f,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/BIMODAL/REVERSED/DISTRIBUTED,d3e0fcbac5cc9a577e33b91176ad78c30fe1be382738d465c1629bd73276e25f,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/BIMODAL/RANDOMIZED/SERVER_LOCAL,335862b837f3ee5d73d45d42b96a49a9103af76762b9e72e8ea5a71ba450daad,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/BIMODAL/RANDOMIZED/DISTRIBUTED,335862b837f3ee5d73d45d42b96a49a9103af76762b9e72e8ea5a71ba450daad,0.0,4.8828125E-4,0.0,2.929687499999556E-4,0.0,0.0
+32/1000/DUPLICATE_HEAVY/ORIGINAL/SERVER_LOCAL,d189b096392386698724b5def27646e3e6072f17a08d1bfc2134e2013ba16f71,0.0,0.0,0.0,0.0,0.0,0.0
+32/1000/DUPLICATE_HEAVY/ORIGINAL/DISTRIBUTED,d189b096392386698724b5def27646e3e6072f17a08d1bfc2134e2013ba16f71,0.0,0.0,0.0,0.0,0.0,0.0
+32/1000/DUPLICATE_HEAVY/REVERSED/SERVER_LOCAL,a6c82c5287ecd813421305a1f3c050dda19d155da98768604b5c738eefce5648,0.0,0.0,0.0,0.0,0.0,0.0
+32/1000/DUPLICATE_HEAVY/REVERSED/DISTRIBUTED,a6c82c5287ecd813421305a1f3c050dda19d155da98768604b5c738eefce5648,0.0,0.0,0.0,0.0,0.0,0.0
+32/1000/DUPLICATE_HEAVY/RANDOMIZED/SERVER_LOCAL,6c551072e7fa6127ecb3de46f07cc2229f61ab2c94395abd5ff92932dae886c7,0.0,0.0,0.0,0.0,0.0,0.0
+32/1000/DUPLICATE_HEAVY/RANDOMIZED/DISTRIBUTED,6c551072e7fa6127ecb3de46f07cc2229f61ab2c94395abd5ff92932dae886c7,0.0,0.0,0.0,0.0,0.0,0.0
+128/20/UNIFORM/ORIGINAL/SERVER_LOCAL,22580454f38b4e1ccbee067c733ec7296e9bca4fe0134c829ddb40a5d005dc9f,0.0,0.00244140625,0.0029296875,0.004199218749999956,4.980468749999911E-4,0.0
+128/20/UNIFORM/ORIGINAL/DISTRIBUTED,22580454f38b4e1ccbee067c733ec7296e9bca4fe0134c829ddb40a5d005dc9f,0.0,0.0018310546875,0.0032958984375,0.004809570312499956,8.642578124999911E-4,0.0
+128/20/UNIFORM/REVERSED/SERVER_LOCAL,58ca946e2ccc949bc6bf744ae70774cebad103aed36ff88742c7e42b7ae351ed,0.0,0.0018310546875,0.0030517578125,0.004199218749999956,9.863281249999911E-4,0.0
+128/20/UNIFORM/REVERSED/DISTRIBUTED,58ca946e2ccc949bc6bf744ae70774cebad103aed36ff88742c7e42b7ae351ed,0.0,0.0018310546875,0.0032958984375,0.004687499999999956,9.863281249999911E-4,0.0
+128/20/UNIFORM/RANDOMIZED/SERVER_LOCAL,b89f2c03ace3c39c6d319a819836b932d7168cf0833925af498a7e038d0c4c19,0.0,0.0018310546875,0.0035400390625,0.004321289062499956,8.642578124999911E-4,0.0
+128/20/UNIFORM/RANDOMIZED/DISTRIBUTED,b89f2c03ace3c39c6d319a819836b932d7168cf0833925af498a7e038d0c4c19,0.0,0.0018310546875,0.0029296875,0.0035888671874999556,0.0018408203124999911,0.0
+128/20/SKEWED/ORIGINAL/SERVER_LOCAL,b5c5790fb24501e12858923c0b0934345519d465d61ab73e52f974afc6b06d4d,0.0,0.055908203125,0.0072021484375,0.0021240234374999556,4.980468749999911E-4,0.0
+128/20/SKEWED/ORIGINAL/DISTRIBUTED,b5c5790fb24501e12858923c0b0934345519d465d61ab73e52f974afc6b06d4d,0.0,0.03125,0.0067138671875,0.0024902343749999556,4.980468749999911E-4,0.0
+128/20/SKEWED/REVERSED/SERVER_LOCAL,114d8e3693f008fe07625cef2b549719d9f684ebd4f6955eb92e7458355919b8,0.0,0.0465087890625,0.014892578125,2.929687499999556E-4,4.980468749999911E-4,0.0
+128/20/SKEWED/REVERSED/DISTRIBUTED,114d8e3693f008fe07625cef2b549719d9f684ebd4f6955eb92e7458355919b8,0.0,0.04931640625,0.0115966796875,0.0026123046874999556,8.642578124999911E-4,0.0
+128/20/SKEWED/RANDOMIZED/SERVER_LOCAL,53554a5659d205e1758bef24431306080e87ed04732b5ff145bdbfaefaa4d39c,0.0,0.0400390625,0.0206298828125,0.0026123046874999556,6.201171874999911E-4,0.0
+128/20/SKEWED/RANDOMIZED/DISTRIBUTED,53554a5659d205e1758bef24431306080e87ed04732b5ff145bdbfaefaa4d39c,0.0,0.0504150390625,0.0072021484375,0.0031005859374999556,0.0011083984374999911,0.0
+128/20/HEAVY_TAIL/ORIGINAL/SERVER_LOCAL,32b9e0cb8af10765c75798dfa050af51c050ec52b41ea7623564e2c0ad6e9002,0.0,0.0255126953125,0.0084228515625,0.008251953125000044,0.003041992187500009,0.0
+128/20/HEAVY_TAIL/ORIGINAL/DISTRIBUTED,32b9e0cb8af10765c75798dfa050af51c050ec52b41ea7623564e2c0ad6e9002,0.0,0.024658203125,0.0067138671875,0.012646484375000044,0.003041992187500009,0.0
+128/20/HEAVY_TAIL/REVERSED/SERVER_LOCAL,cb3843baa7289e940b0d6fe3551cb152b4396c483ca60c30481ff623ac0594a2,0.0,0.0220947265625,0.0247802734375,0.006909179687500044,0.002309570312500009,0.0
+128/20/HEAVY_TAIL/REVERSED/DISTRIBUTED,cb3843baa7289e940b0d6fe3551cb152b4396c483ca60c30481ff623ac0594a2,0.0,0.0220947265625,0.0166015625,0.006787109375000044,0.002065429687500009,0.0
+128/20/HEAVY_TAIL/RANDOMIZED/SERVER_LOCAL,e19631ce601457288b0dc219542263606b179e51a898aa119436a6c51c633a09,0.0,0.0172119140625,0.0157470703125,0.005932617187500044,0.002553710937500009,0.0
+128/20/HEAVY_TAIL/RANDOMIZED/DISTRIBUTED,e19631ce601457288b0dc219542263606b179e51a898aa119436a6c51c633a09,0.0,0.02392578125,0.0084228515625,0.004711914062500044,0.0019433593750000089,0.0
+128/20/BIMODAL/ORIGINAL/SERVER_LOCAL,3a83809c9a61956f67288b243e78026402fb8c611dd40aa3aa3894ba6c1ff168,0.0,0.0035400390625,0.0029296875,0.004199218749999956,4.980468749999911E-4,0.0
+128/20/BIMODAL/ORIGINAL/DISTRIBUTED,3a83809c9a61956f67288b243e78026402fb8c611dd40aa3aa3894ba6c1ff168,0.0,0.0035400390625,0.0023193359375,0.004443359374999956,8.642578124999911E-4,0.0
+128/20/BIMODAL/REVERSED/SERVER_LOCAL,7a2b5430ba582f9e2a03123113ecfacea063eb1b235963c0484750ba7336d1a7,0.0,0.0035400390625,0.0029296875,0.004199218749999956,9.863281249999911E-4,0.0
+128/20/BIMODAL/REVERSED/DISTRIBUTED,7a2b5430ba582f9e2a03123113ecfacea063eb1b235963c0484750ba7336d1a7,0.0,0.0035400390625,0.0032958984375,0.004687499999999956,9.863281249999911E-4,0.0
+128/20/BIMODAL/RANDOMIZED/SERVER_LOCAL,eff432160a9c2ade54af5d9681e9f513faebe4fd831f57f1f042b1edc1aceaeb,0.0,0.0035400390625,0.0032958984375,0.004321289062499956,8.642578124999911E-4,0.0
+128/20/BIMODAL/RANDOMIZED/DISTRIBUTED,eff432160a9c2ade54af5d9681e9f513faebe4fd831f57f1f042b1edc1aceaeb,0.0,0.0035400390625,0.0029296875,0.005175781249999956,0.0018408203124999911,0.0
+128/20/DUPLICATE_HEAVY/ORIGINAL/SERVER_LOCAL,fe4029836cd7704d3760f9545981f877667ec6a3560a827297535f1ec5592c6f,0.0,0.0,0.0545654296875,0.052294921874999956,0.0,0.0
+128/20/DUPLICATE_HEAVY/ORIGINAL/DISTRIBUTED,fe4029836cd7704d3760f9545981f877667ec6a3560a827297535f1ec5592c6f,0.0,0.1954345703125,0.0545654296875,0.052294921874999956,0.0,0.0
+128/20/DUPLICATE_HEAVY/REVERSED/SERVER_LOCAL,e8198c00771c7e337f235825e44c1430d875d0b86b32556cc49f695cc48c531a,0.0,0.1954345703125,0.0545654296875,0.052294921874999956,0.0,0.0
+128/20/DUPLICATE_HEAVY/REVERSED/DISTRIBUTED,e8198c00771c7e337f235825e44c1430d875d0b86b32556cc49f695cc48c531a,0.0,0.1954345703125,0.0545654296875,0.052294921874999956,0.0,0.0
+128/20/DUPLICATE_HEAVY/RANDOMIZED/SERVER_LOCAL,144b87295a08d982842ad9f441f52a3218511c348f1fdf3d48f082abe36616b1,0.0,0.1954345703125,0.0545654296875,0.052294921874999956,0.0,0.0
+128/20/DUPLICATE_HEAVY/RANDOMIZED/DISTRIBUTED,144b87295a08d982842ad9f441f52a3218511c348f1fdf3d48f082abe36616b1,0.0,0.0,0.0545654296875,0.052294921874999956,0.0,0.0
+128/100/UNIFORM/ORIGINAL/SERVER_LOCAL,22580454f38b4e1ccbee067c733ec7296e9bca4fe0134c829ddb40a5d005dc9f,0.0,4.8828125E-4,2.44140625E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/100/UNIFORM/ORIGINAL/DISTRIBUTED,22580454f38b4e1ccbee067c733ec7296e9bca4fe0134c829ddb40a5d005dc9f,0.0,2.44140625E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/100/UNIFORM/REVERSED/SERVER_LOCAL,58ca946e2ccc949bc6bf744ae70774cebad103aed36ff88742c7e42b7ae351ed,0.0,1.220703125E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/100/UNIFORM/REVERSED/DISTRIBUTED,58ca946e2ccc949bc6bf744ae70774cebad103aed36ff88742c7e42b7ae351ed,0.0,2.44140625E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/100/UNIFORM/RANDOMIZED/SERVER_LOCAL,b89f2c03ace3c39c6d319a819836b932d7168cf0833925af498a7e038d0c4c19,0.0,2.44140625E-4,2.44140625E-4,3.173828125000444E-4,1.1230468750000888E-4,0.0
+128/100/UNIFORM/RANDOMIZED/DISTRIBUTED,b89f2c03ace3c39c6d319a819836b932d7168cf0833925af498a7e038d0c4c19,0.0,1.220703125E-4,3.662109375E-4,3.173828125000444E-4,1.1230468750000888E-4,0.0
+128/100/SKEWED/ORIGINAL/SERVER_LOCAL,b5c5790fb24501e12858923c0b0934345519d465d61ab73e52f974afc6b06d4d,0.0,0.0018310546875,4.8828125E-4,3.173828125000444E-4,1.1230468750000888E-4,0.0
+128/100/SKEWED/ORIGINAL/DISTRIBUTED,b5c5790fb24501e12858923c0b0934345519d465d61ab73e52f974afc6b06d4d,0.0,0.0018310546875,8.544921875E-4,3.173828125000444E-4,1.1230468750000888E-4,0.0
+128/100/SKEWED/REVERSED/SERVER_LOCAL,114d8e3693f008fe07625cef2b549719d9f684ebd4f6955eb92e7458355919b8,0.0,0.0015869140625,6.103515625E-4,3.173828125000444E-4,1.1230468750000888E-4,0.0
+128/100/SKEWED/REVERSED/DISTRIBUTED,114d8e3693f008fe07625cef2b549719d9f684ebd4f6955eb92e7458355919b8,0.0,0.0020751953125,7.32421875E-4,1.953125000000444E-4,1.1230468750000888E-4,0.0
+128/100/SKEWED/RANDOMIZED/SERVER_LOCAL,53554a5659d205e1758bef24431306080e87ed04732b5ff145bdbfaefaa4d39c,0.0,0.0015869140625,9.765625E-4,3.173828125000444E-4,1.1230468750000888E-4,0.0
+128/100/SKEWED/RANDOMIZED/DISTRIBUTED,53554a5659d205e1758bef24431306080e87ed04732b5ff145bdbfaefaa4d39c,0.0,0.0025634765625,0.0010986328125,3.173828125000444E-4,1.1230468750000888E-4,0.0
+128/100/HEAVY_TAIL/ORIGINAL/SERVER_LOCAL,32b9e0cb8af10765c75798dfa050af51c050ec52b41ea7623564e2c0ad6e9002,0.0,6.103515625E-4,9.765625E-4,0.0019042968750000444,8.447265625000089E-4,0.0
+128/100/HEAVY_TAIL/ORIGINAL/DISTRIBUTED,32b9e0cb8af10765c75798dfa050af51c050ec52b41ea7623564e2c0ad6e9002,0.0,6.103515625E-4,8.544921875E-4,8.056640625000444E-4,3.564453125000089E-4,0.0
+128/100/HEAVY_TAIL/REVERSED/SERVER_LOCAL,cb3843baa7289e940b0d6fe3551cb152b4396c483ca60c30481ff623ac0594a2,0.0,7.32421875E-4,7.32421875E-4,0.0011718750000000444,6.005859375000089E-4,0.0
+128/100/HEAVY_TAIL/REVERSED/DISTRIBUTED,cb3843baa7289e940b0d6fe3551cb152b4396c483ca60c30481ff623ac0594a2,0.0,7.32421875E-4,7.32421875E-4,0.0011718750000000444,6.005859375000089E-4,0.0
+128/100/HEAVY_TAIL/RANDOMIZED/SERVER_LOCAL,e19631ce601457288b0dc219542263606b179e51a898aa119436a6c51c633a09,0.0,7.32421875E-4,0.001220703125,0.0019042968750000444,6.005859375000089E-4,0.0
+128/100/HEAVY_TAIL/RANDOMIZED/DISTRIBUTED,e19631ce601457288b0dc219542263606b179e51a898aa119436a6c51c633a09,0.0,6.103515625E-4,0.0010986328125,0.0019042968750000444,6.005859375000089E-4,0.0
+128/100/BIMODAL/ORIGINAL/SERVER_LOCAL,3a83809c9a61956f67288b243e78026402fb8c611dd40aa3aa3894ba6c1ff168,0.0,0.0035400390625,2.44140625E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/100/BIMODAL/ORIGINAL/DISTRIBUTED,3a83809c9a61956f67288b243e78026402fb8c611dd40aa3aa3894ba6c1ff168,0.0,0.0035400390625,1.220703125E-4,3.173828125000444E-4,1.1230468750000888E-4,0.0
+128/100/BIMODAL/REVERSED/SERVER_LOCAL,7a2b5430ba582f9e2a03123113ecfacea063eb1b235963c0484750ba7336d1a7,0.0,0.0035400390625,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/100/BIMODAL/REVERSED/DISTRIBUTED,7a2b5430ba582f9e2a03123113ecfacea063eb1b235963c0484750ba7336d1a7,0.0,0.0035400390625,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/100/BIMODAL/RANDOMIZED/SERVER_LOCAL,eff432160a9c2ade54af5d9681e9f513faebe4fd831f57f1f042b1edc1aceaeb,0.0,0.0035400390625,3.662109375E-4,3.173828125000444E-4,1.1230468750000888E-4,0.0
+128/100/BIMODAL/RANDOMIZED/DISTRIBUTED,eff432160a9c2ade54af5d9681e9f513faebe4fd831f57f1f042b1edc1aceaeb,0.0,0.0035400390625,2.44140625E-4,3.173828125000444E-4,1.1230468750000888E-4,0.0
+128/100/DUPLICATE_HEAVY/ORIGINAL/SERVER_LOCAL,fe4029836cd7704d3760f9545981f877667ec6a3560a827297535f1ec5592c6f,0.0,0.0,0.0,0.0,0.0,0.0
+128/100/DUPLICATE_HEAVY/ORIGINAL/DISTRIBUTED,fe4029836cd7704d3760f9545981f877667ec6a3560a827297535f1ec5592c6f,0.0,0.0,0.0,0.0,0.0,0.0
+128/100/DUPLICATE_HEAVY/REVERSED/SERVER_LOCAL,e8198c00771c7e337f235825e44c1430d875d0b86b32556cc49f695cc48c531a,0.0,0.0,0.0,0.0,0.0,0.0
+128/100/DUPLICATE_HEAVY/REVERSED/DISTRIBUTED,e8198c00771c7e337f235825e44c1430d875d0b86b32556cc49f695cc48c531a,0.0,0.0,0.0,0.0,0.0,0.0
+128/100/DUPLICATE_HEAVY/RANDOMIZED/SERVER_LOCAL,144b87295a08d982842ad9f441f52a3218511c348f1fdf3d48f082abe36616b1,0.0,0.0,0.0,0.0,0.0,0.0
+128/100/DUPLICATE_HEAVY/RANDOMIZED/DISTRIBUTED,144b87295a08d982842ad9f441f52a3218511c348f1fdf3d48f082abe36616b1,0.0,0.0,0.0,0.0,0.0,0.0
+128/1000/UNIFORM/ORIGINAL/SERVER_LOCAL,22580454f38b4e1ccbee067c733ec7296e9bca4fe0134c829ddb40a5d005dc9f,0.0,2.44140625E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/UNIFORM/ORIGINAL/DISTRIBUTED,22580454f38b4e1ccbee067c733ec7296e9bca4fe0134c829ddb40a5d005dc9f,0.0,2.44140625E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/UNIFORM/REVERSED/SERVER_LOCAL,58ca946e2ccc949bc6bf744ae70774cebad103aed36ff88742c7e42b7ae351ed,0.0,2.44140625E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/UNIFORM/REVERSED/DISTRIBUTED,58ca946e2ccc949bc6bf744ae70774cebad103aed36ff88742c7e42b7ae351ed,0.0,2.44140625E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/UNIFORM/RANDOMIZED/SERVER_LOCAL,b89f2c03ace3c39c6d319a819836b932d7168cf0833925af498a7e038d0c4c19,0.0,2.44140625E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/UNIFORM/RANDOMIZED/DISTRIBUTED,b89f2c03ace3c39c6d319a819836b932d7168cf0833925af498a7e038d0c4c19,0.0,2.44140625E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/SKEWED/ORIGINAL/SERVER_LOCAL,b5c5790fb24501e12858923c0b0934345519d465d61ab73e52f974afc6b06d4d,0.0,1.220703125E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/SKEWED/ORIGINAL/DISTRIBUTED,b5c5790fb24501e12858923c0b0934345519d465d61ab73e52f974afc6b06d4d,0.0,1.220703125E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/SKEWED/REVERSED/SERVER_LOCAL,114d8e3693f008fe07625cef2b549719d9f684ebd4f6955eb92e7458355919b8,0.0,1.220703125E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/SKEWED/REVERSED/DISTRIBUTED,114d8e3693f008fe07625cef2b549719d9f684ebd4f6955eb92e7458355919b8,0.0,1.220703125E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/SKEWED/RANDOMIZED/SERVER_LOCAL,53554a5659d205e1758bef24431306080e87ed04732b5ff145bdbfaefaa4d39c,0.0,1.220703125E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/SKEWED/RANDOMIZED/DISTRIBUTED,53554a5659d205e1758bef24431306080e87ed04732b5ff145bdbfaefaa4d39c,0.0,1.220703125E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/HEAVY_TAIL/ORIGINAL/SERVER_LOCAL,32b9e0cb8af10765c75798dfa050af51c050ec52b41ea7623564e2c0ad6e9002,0.0,2.44140625E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/HEAVY_TAIL/ORIGINAL/DISTRIBUTED,32b9e0cb8af10765c75798dfa050af51c050ec52b41ea7623564e2c0ad6e9002,0.0,2.44140625E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/HEAVY_TAIL/REVERSED/SERVER_LOCAL,cb3843baa7289e940b0d6fe3551cb152b4396c483ca60c30481ff623ac0594a2,0.0,2.44140625E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/HEAVY_TAIL/REVERSED/DISTRIBUTED,cb3843baa7289e940b0d6fe3551cb152b4396c483ca60c30481ff623ac0594a2,0.0,2.44140625E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/HEAVY_TAIL/RANDOMIZED/SERVER_LOCAL,e19631ce601457288b0dc219542263606b179e51a898aa119436a6c51c633a09,0.0,2.44140625E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/HEAVY_TAIL/RANDOMIZED/DISTRIBUTED,e19631ce601457288b0dc219542263606b179e51a898aa119436a6c51c633a09,0.0,2.44140625E-4,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/BIMODAL/ORIGINAL/SERVER_LOCAL,3a83809c9a61956f67288b243e78026402fb8c611dd40aa3aa3894ba6c1ff168,0.0,0.0035400390625,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/BIMODAL/ORIGINAL/DISTRIBUTED,3a83809c9a61956f67288b243e78026402fb8c611dd40aa3aa3894ba6c1ff168,0.0,0.0035400390625,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/BIMODAL/REVERSED/SERVER_LOCAL,7a2b5430ba582f9e2a03123113ecfacea063eb1b235963c0484750ba7336d1a7,0.0,0.0035400390625,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/BIMODAL/REVERSED/DISTRIBUTED,7a2b5430ba582f9e2a03123113ecfacea063eb1b235963c0484750ba7336d1a7,0.0,0.0035400390625,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/BIMODAL/RANDOMIZED/SERVER_LOCAL,eff432160a9c2ade54af5d9681e9f513faebe4fd831f57f1f042b1edc1aceaeb,0.0,0.0035400390625,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/BIMODAL/RANDOMIZED/DISTRIBUTED,eff432160a9c2ade54af5d9681e9f513faebe4fd831f57f1f042b1edc1aceaeb,0.0,0.0035400390625,3.662109375E-4,7.324218750004441E-5,1.1230468750000888E-4,0.0
+128/1000/DUPLICATE_HEAVY/ORIGINAL/SERVER_LOCAL,fe4029836cd7704d3760f9545981f877667ec6a3560a827297535f1ec5592c6f,0.0,0.0,0.0,0.0,0.0,0.0
+128/1000/DUPLICATE_HEAVY/ORIGINAL/DISTRIBUTED,fe4029836cd7704d3760f9545981f877667ec6a3560a827297535f1ec5592c6f,0.0,0.0,0.0,0.0,0.0,0.0
+128/1000/DUPLICATE_HEAVY/REVERSED/SERVER_LOCAL,e8198c00771c7e337f235825e44c1430d875d0b86b32556cc49f695cc48c531a,0.0,0.0,0.0,0.0,0.0,0.0
+128/1000/DUPLICATE_HEAVY/REVERSED/DISTRIBUTED,e8198c00771c7e337f235825e44c1430d875d0b86b32556cc49f695cc48c531a,0.0,0.0,0.0,0.0,0.0,0.0
+128/1000/DUPLICATE_HEAVY/RANDOMIZED/SERVER_LOCAL,144b87295a08d982842ad9f441f52a3218511c348f1fdf3d48f082abe36616b1,0.0,0.0,0.0,0.0,0.0,0.0
+128/1000/DUPLICATE_HEAVY/RANDOMIZED/DISTRIBUTED,144b87295a08d982842ad9f441f52a3218511c348f1fdf3d48f082abe36616b1,0.0,0.0,0.0,0.0,0.0,0.0
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/PercentileTDigestAccumulator.java
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/customobject/tdigest/TDigestAccumulator.java
similarity index 97%
rename from
pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/PercentileTDigestAccumulator.java
rename to
pinot-segment-local/src/main/java/org/apache/pinot/segment/local/customobject/tdigest/TDigestAccumulator.java
index db7f69b994c..d6087382f0b 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/PercentileTDigestAccumulator.java
+++
b/pinot-segment-local/src/main/java/org/apache/pinot/segment/local/customobject/tdigest/TDigestAccumulator.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.pinot.core.query.aggregation.function;
+package org.apache.pinot.segment.local.customobject.tdigest;
import com.tdunning.math.stats.Centroid;
import com.tdunning.math.stats.MergingDigest;
@@ -50,7 +50,7 @@ import org.apache.pinot.segment.local.utils.TDigestUtils;
/// input must be merged. The raw-value buffer remains unallocated for
serialized state until a raw value is added.
///
/// Instances are externally serialized per aggregation or group key and are
not safe for concurrent mutation.
-final class PercentileTDigestAccumulator extends TDigest {
+public final class TDigestAccumulator extends TDigest {
private static final int MIN_RAW_BUFFER_SIZE = 256;
private static final int MAX_RAW_BUFFER_SIZE = 10_000;
private static final int MIN_COMPRESSION = 10;
@@ -100,11 +100,11 @@ final class PercentileTDigestAccumulator extends TDigest {
private double _min = Double.POSITIVE_INFINITY;
private double _max = Double.NEGATIVE_INFINITY;
- PercentileTDigestAccumulator(int compression) {
+ public TDigestAccumulator(int compression) {
this((double) compression, true, true);
}
- private PercentileTDigestAccumulator(double compression, boolean
allocateRawBuffer, boolean allocateMergeBuffers) {
+ private TDigestAccumulator(double compression, boolean allocateRawBuffer,
boolean allocateMergeBuffers) {
if (!(compression > 0.0) || !Double.isFinite(compression)) {
throw new IllegalArgumentException("TDigest compression must be
positive: " + compression);
}
@@ -127,31 +127,31 @@ final class PercentileTDigestAccumulator extends TDigest {
}
}
- static PercentileTDigestAccumulator forSerializedTDigest(byte[] bytes) {
- return new PercentileTDigestAccumulator(readCompression(bytes), false,
false);
+ public static TDigestAccumulator forSerializedTDigest(byte[] bytes) {
+ return new TDigestAccumulator(readCompression(bytes), false, false);
}
- static PercentileTDigestAccumulator
forSerializedTDigest(SerializedTDigestInput input) {
- return new PercentileTDigestAccumulator(input._compression, false, false);
+ public static TDigestAccumulator forSerializedTDigest(SerializedTDigestInput
input) {
+ return new TDigestAccumulator(input._compression, false, false);
}
- static PercentileTDigestAccumulator
forSerializedTDigestWithMergeBuffers(byte[] bytes) {
- return new PercentileTDigestAccumulator(readCompression(bytes), false,
true);
+ public static TDigestAccumulator forSerializedTDigestWithMergeBuffers(byte[]
bytes) {
+ return new TDigestAccumulator(readCompression(bytes), false, true);
}
- static PercentileTDigestAccumulator forSerializedTDigest(ByteBuffer input) {
+ public static TDigestAccumulator forSerializedTDigest(ByteBuffer input) {
byte[] bytes = new byte[input.remaining()];
input.get(bytes);
- PercentileTDigestAccumulator accumulator = forSerializedTDigest(bytes);
+ TDigestAccumulator accumulator = forSerializedTDigest(bytes);
accumulator.addSerializedTDigest(bytes);
return accumulator;
}
- static PercentileTDigestAccumulator forReduction(double compression) {
- return new PercentileTDigestAccumulator(compression, false, false);
+ public static TDigestAccumulator forReduction(double compression) {
+ return new TDigestAccumulator(compression, false, false);
}
- void add(double[] values, int from, int toExclusive) {
+ public void add(double[] values, int from, int toExclusive) {
if (from >= toExclusive) {
return;
}
@@ -212,8 +212,8 @@ final class PercentileTDigestAccumulator extends TDigest {
@Override
public void add(TDigest other) {
- if (other instanceof PercentileTDigestAccumulator) {
- addAccumulator((PercentileTDigestAccumulator) other);
+ if (other instanceof TDigestAccumulator) {
+ addAccumulator((TDigestAccumulator) other);
return;
}
if (other instanceof MergingDigest && other.size() > Integer.MAX_VALUE) {
@@ -239,7 +239,7 @@ final class PercentileTDigestAccumulator extends TDigest {
}
}
- private void addAccumulator(PercentileTDigestAccumulator other) {
+ private void addAccumulator(TDigestAccumulator other) {
if (other._pendingSerializedTDigest != null) {
addSerializedTDigest(other._pendingSerializedTDigest);
return;
@@ -253,7 +253,7 @@ final class PercentileTDigestAccumulator extends TDigest {
_max = Math.max(_max, other._max);
}
- void addSerializedTDigest(byte[] bytes) {
+ public void addSerializedTDigest(byte[] bytes) {
if (!_hasSerializedInput && _numCentroids == 0 && _totalWeight == 0.0 &&
_numRawValues == 0
&& _numIncomingCentroids == 0) {
byte[] retainedBytes = bytes.clone();
@@ -272,7 +272,7 @@ final class PercentileTDigestAccumulator extends TDigest {
_hasSerializedInput = true;
}
- void addSerializedTDigest(SerializedTDigestInput input) {
+ public void addSerializedTDigest(SerializedTDigestInput input) {
if (!_hasSerializedInput && _numCentroids == 0 && _totalWeight == 0.0 &&
_numRawValues == 0
&& _numIncomingCentroids == 0) {
_pendingSerializedTDigest = input.retainBytes();
@@ -286,7 +286,7 @@ final class PercentileTDigestAccumulator extends TDigest {
_hasSerializedInput = true;
}
- void addSerializedTDigestDirect(SerializedTDigestInput input) {
+ public void addSerializedTDigestDirect(SerializedTDigestInput input) {
if (!_hasSerializedInput && _numCentroids == 0 && _totalWeight == 0.0 &&
_numRawValues == 0
&& _numIncomingCentroids == 0) {
_pendingSerializedTDigest = input.retainBytes();
@@ -670,7 +670,7 @@ final class PercentileTDigestAccumulator extends TDigest {
@Override
public void setScaleFunction(ScaleFunction scaleFunction) {
if (scaleFunction != ScaleFunction.K_1) {
- throw new UnsupportedOperationException("PercentileTDigestAccumulator
only supports ScaleFunction.K_1");
+ throw new UnsupportedOperationException("TDigestAccumulator only
supports ScaleFunction.K_1");
}
super.setScaleFunction(scaleFunction);
}
@@ -702,7 +702,7 @@ final class PercentileTDigestAccumulator extends TDigest {
return _max;
}
- byte[] serialize() {
+ public byte[] serialize() {
if (_pendingSerializedTDigest != null) {
getSerializedTotalWeight(_pendingSerializedTDigest);
if (ByteBuffer.wrap(_pendingSerializedTDigest).getInt() ==
VERBOSE_ENCODING) {
@@ -715,7 +715,7 @@ final class PercentileTDigestAccumulator extends TDigest {
return TDigestUtils.makeLegacyCompatible(toVerboseBytes());
}
- TDigest toTDigest() {
+ public TDigest toTDigest() {
if (_pendingSerializedTDigest != null) {
return TDigestUtils.deserialize(_pendingSerializedTDigest);
}
@@ -1436,7 +1436,7 @@ final class PercentileTDigestAccumulator extends TDigest {
/// state. A pending accumulator requests an immutable byte snapshot,
created at most once per reset and shared by
/// the row's group fanout. The input must remain thread-confined and must
not outlive the aggregation call that owns
/// it.
- static final class SerializedTDigestInput {
+ public static final class SerializedTDigestInput {
private byte[] _bytes;
private byte[] _retainedBytes;
private double _min;
@@ -1452,7 +1452,7 @@ final class PercentileTDigestAccumulator extends TDigest {
private double _totalWeight;
private boolean _decoded;
- void reset(byte[] bytes) {
+ public void reset(byte[] bytes) {
_retainedBytes = null;
ByteBuffer input = ByteBuffer.wrap(bytes);
int encoding = input.getInt();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]