private static Block createFixWidthValueBlock(int positionCount, int mapSize) {
   BlockBuilder valueBlockBuilder =
       DOUBLE.createBlockBuilder(new BlockBuilderStatus(), positionCount * mapSize);
   for (int i = 0; i < positionCount * mapSize; i++) {
     DOUBLE.writeDouble(valueBlockBuilder, ThreadLocalRandom.current().nextDouble());
   }
   return valueBlockBuilder.build();
 }
public class TestApproximatePercentileAggregation {
  private static final Block EMPTY_DOUBLE_BLOCK =
      DOUBLE.createBlockBuilder(new BlockBuilderStatus(), 0).build();
  private static final Block EMPTY_LONG_BLOCK =
      BIGINT.createBlockBuilder(new BlockBuilderStatus(), 0).build();

  @Test
  public void testLongPartialStep() throws Exception {
    // regular approx_percentile
    assertAggregation(
        LONG_APPROXIMATE_PERCENTILE_AGGREGATION,
        1.0,
        null,
        createLongsBlock(null, null),
        createRLEBlock(0.5, 2));

    assertAggregation(
        LONG_APPROXIMATE_PERCENTILE_AGGREGATION,
        1.0,
        1L,
        createLongsBlock(null, 1L),
        createRLEBlock(0.5, 2));

    assertAggregation(
        LONG_APPROXIMATE_PERCENTILE_AGGREGATION,
        1.0,
        2L,
        createLongsBlock(null, 1L, 2L, 3L),
        createRLEBlock(0.5, 4));

    assertAggregation(
        LONG_APPROXIMATE_PERCENTILE_AGGREGATION,
        1.0,
        2L,
        createLongsBlock(1L, 2L, 3L),
        createRLEBlock(0.5, 3));

    assertAggregation(
        LONG_APPROXIMATE_PERCENTILE_AGGREGATION,
        1.0,
        3L,
        createLongsBlock(
            1L, null, 2L, 2L, null, 2L, 2L, null, 2L, 2L, null, 3L, 3L, null, 3L, null, 3L, 4L, 5L,
            6L, 7L),
        createRLEBlock(0.5, 21));

    // weighted approx_percentile
    assertAggregation(
        LONG_APPROXIMATE_PERCENTILE_WEIGHTED_AGGREGATION,
        1.0,
        null,
        createLongsBlock(null, null),
        createLongsBlock(1L, 1L),
        createRLEBlock(0.5, 2));

    assertAggregation(
        LONG_APPROXIMATE_PERCENTILE_WEIGHTED_AGGREGATION,
        1.0,
        1L,
        createLongsBlock(null, 1L),
        createLongsBlock(1L, 1L),
        createRLEBlock(0.5, 2));

    assertAggregation(
        LONG_APPROXIMATE_PERCENTILE_WEIGHTED_AGGREGATION,
        1.0,
        2L,
        createLongsBlock(null, 1L, 2L, 3L),
        createLongsBlock(1L, 1L, 1L, 1L),
        createRLEBlock(0.5, 4));

    assertAggregation(
        LONG_APPROXIMATE_PERCENTILE_WEIGHTED_AGGREGATION,
        1.0,
        2L,
        createLongsBlock(1L, 2L, 3L),
        createLongsBlock(1L, 1L, 1L),
        createRLEBlock(0.5, 3));

    assertAggregation(
        LONG_APPROXIMATE_PERCENTILE_WEIGHTED_AGGREGATION,
        1.0,
        3L,
        createLongsBlock(
            1L, null, 2L, null, 2L, null, 2L, null, 3L, null, 3L, null, 3L, 4L, 5L, 6L, 7L),
        createLongsBlock(1L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L),
        createRLEBlock(0.5, 17));
  }

  @Test
  public void testDoublePartialStep() throws Exception {
    // regular approx_percentile
    assertAggregation(
        DOUBLE_APPROXIMATE_PERCENTILE_AGGREGATION,
        1.0,
        null,
        createDoublesBlock(null, null),
        createRLEBlock(0.5, 2));

    assertAggregation(
        DOUBLE_APPROXIMATE_PERCENTILE_AGGREGATION,
        1.0,
        1.0,
        createDoublesBlock(null, 1.0),
        createRLEBlock(0.5, 2));

    assertAggregation(
        DOUBLE_APPROXIMATE_PERCENTILE_AGGREGATION,
        1.0,
        2.0,
        createDoublesBlock(null, 1.0, 2.0, 3.0),
        createRLEBlock(0.5, 4));

    assertAggregation(
        DOUBLE_APPROXIMATE_PERCENTILE_AGGREGATION,
        1.0,
        2.0,
        createDoublesBlock(1.0, 2.0, 3.0),
        createRLEBlock(0.5, 3));

    assertAggregation(
        DOUBLE_APPROXIMATE_PERCENTILE_AGGREGATION,
        1.0,
        3.0,
        createDoublesBlock(
            1.0, null, 2.0, 2.0, null, 2.0, 2.0, null, 2.0, 2.0, null, 3.0, 3.0, null, 3.0, null,
            3.0, 4.0, 5.0, 6.0, 7.0),
        createRLEBlock(0.5, 21));

    // weighted approx_percentile
    assertAggregation(
        DOUBLE_APPROXIMATE_PERCENTILE_WEIGHTED_AGGREGATION,
        1.0,
        null,
        createDoublesBlock(null, null),
        createLongsBlock(1L, 1L),
        createRLEBlock(0.5, 2));

    assertAggregation(
        DOUBLE_APPROXIMATE_PERCENTILE_WEIGHTED_AGGREGATION,
        1.0,
        1.0,
        createDoublesBlock(null, 1.0),
        createLongsBlock(1L, 1L),
        createRLEBlock(0.5, 2));

    assertAggregation(
        DOUBLE_APPROXIMATE_PERCENTILE_WEIGHTED_AGGREGATION,
        1.0,
        2.0,
        createDoublesBlock(null, 1.0, 2.0, 3.0),
        createLongsBlock(1L, 1L, 1L, 1L),
        createRLEBlock(0.5, 4));

    assertAggregation(
        DOUBLE_APPROXIMATE_PERCENTILE_WEIGHTED_AGGREGATION,
        1.0,
        2.0,
        createDoublesBlock(1.0, 2.0, 3.0),
        createLongsBlock(1L, 1L, 1L),
        createRLEBlock(0.5, 3));

    assertAggregation(
        DOUBLE_APPROXIMATE_PERCENTILE_WEIGHTED_AGGREGATION,
        1.0,
        3.0,
        createDoublesBlock(
            1.0, null, 2.0, null, 2.0, null, 2.0, null, 3.0, null, 3.0, null, 3.0, 4.0, 5.0, 6.0,
            7.0),
        createLongsBlock(1L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L),
        createRLEBlock(0.5, 17));
  }
}