docs: public double update(final double units) {
      final double speed;
      lock.lock();
      try {
        final long currentTime = System.nanoTime();
        final long timeDifference = (currentTime - lastUpdateTime) / C1; // nanoseconds to micros
        if (timeDifference >= averagingPeriod) {
          speed = units / averagingPeriod;
          cachedSpeed = speed;
          lastUpdateTime = currentTime;
          elapsedTime = ZERO_TIME;
          quantity = ZERO_UNITS;
        } else {
          if (timeDifference > ZERO_TIME) {
            lastUpdateTime = currentTime;
            elapsedTime += timeDifference;
          }
          if (units != ZERO_UNITS) {
            quantity += units;
          }
          if (elapsedTime >= averagingPeriod) {
            speed = quantity / elapsedTime;
            cachedSpeed = speed;
            elapsedTime = ZERO_TIME;
            quantity = ZERO_UNITS;
          } else {
            speed = (cachedSpeed * (averagingPeriod - elapsedTime) + quantity) / averagingPeriod;
          }
        }
      } finally {
        lock.unlock();
      }
      return speed * C0; // units per micro to units per second
    }