@Override
  public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations)
      throws MetadataException {
    // set data type
    configurations.setOutputDataType(UDFDataTypeTransformer.transformToUDFDataType(dataType));

    // set access strategy
    if (accessStrategy == AccessStrategy.SIZE_WINDOW) {
      int windowSize = parameters.getInt(WINDOW_SIZE_KEY);
      int slidingStep = parameters.getIntOrDefault(SLIDING_STEP_KEY, windowSize);
      configurations.setAccessStrategy(
          new SlidingSizeWindowAccessStrategy(windowSize, slidingStep));
    } else {
      long timeInterval = parameters.getLong(TIME_INTERVAL_KEY);
      long displayWindowBegin =
          parameters.getLongOrDefault(DISPLAY_WINDOW_BEGIN_KEY, Long.MIN_VALUE);
      long displayWindowEnd = parameters.getLongOrDefault(DISPLAY_WINDOW_END_KEY, Long.MAX_VALUE);
      long slidingStep = parameters.getLongOrDefault(SLIDING_STEP_KEY, timeInterval);
      configurations.setAccessStrategy(
          new SlidingTimeWindowAccessStrategy(
              timeInterval, slidingStep, displayWindowBegin, displayWindowEnd));
    }
  }
For each sliding window, M4 returns the first, last, bottom, top points. The window can be
controlled by either point size or time interval length. The aggregated points in the output
series has been sorted and deduplicated.

<p>SlidingSizeWindow usage Example: "select M4(s1,'windowSize'='10','slidingStep'='10') from
root.vehicle.d1" (windowSize is required, slidingStep is optional.)

<p>SlidingTimeWindow usage Example: "select
M4(s1,'timeInterval'='25','slidingStep'='25','displayWindowBegin'='0','displayWindowEnd'='100')
from root.vehicle.d1" (timeInterval is required, slidingStep/displayWindowBegin/displayWindowEnd
are optional.)
iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/UDTFM4.java