float computeAdaptiveAverage(int newSample, float average) {
    // We smooth the samples by not using weight() directly until we've
    // had enough data to make it meaningful. We'd like the first weight
    // used to be 1, the second to be 1/2, etc until we have
    // OLD_THRESHOLD/weight samples.
    int countWeight = 0;

    // Avoid division by zero if the counter wraps
    if (!isOld) {
      countWeight = OLD_THRESHOLD / sampleCount;
    }

    int adaptiveWeight = max(weight, countWeight);

    return (100.0f - adaptiveWeight) * average / 100.0f + adaptiveWeight * newSample / 100.0f;
  }
This file is modified from <a
href="https://github.com/openjdk/jdk17/blob/master/src/hotspot/share/gc/shared/gcUtil.hpp">JDK17
AdaptiveWeightedAverage</a>. But some necessary modifications are made to adapt to the usage of
binary allocator:

<p>Adaptive weighted average implementation for memory allocation tracking. During each eviction
cycle, records the peak memory allocation size via sampling, then uses this peak to calculate a
weighted moving average.
iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/binaryallocator/ema/AdaptiveWeightedAverage.java