docs: private void rescale(long now, long next) {
          lockForRescale();
          try {
              if (nextScaleTime.compareAndSet(next, now + RESCALE_THRESHOLD)) {
                  final long oldStartTime = startTime;
                  this.startTime = currentTimeInSeconds();
                  final double scalingFactor = exp(-alpha * (startTime - oldStartTime));
                  if (Double.compare(scalingFactor, 0) == 0) {
                      values.clear();
                  } else {
                      final ArrayList<Double> keys = new ArrayList<Double>(values.keySet());
                      for (Double key : keys) {
                          final WeightedSample sample = values.remove(key);
                          final WeightedSample newSample = new WeightedSample(sample.value, sample.weight * scalingFactor);
                          values.put(key * scalingFactor, newSample);
                      }
                  }
  
                  // make sure the counter is in sync with the number of stored samples.
                  count.set(values.size());
              }
          } finally {
              unlockForRescale();
          }
      }