class ActiveTimeSeriesCounter implements IActiveTimeSeriesCounter {

  @Override
  public void updateActiveRatio(String storageGroup) {
    lock.writeLock().lock();
    try {
      HyperLogLog log = storageGroupHllMap.get(storageGroup);
      if (log == null) {
        LOGGER.warn(
            "Unknown SG {} is calling updateActiveRatio. It can be ignored the sg is deleted recently",
            storageGroup);
        return;
      }
      long activeTimeSeriesNum = storageGroupHllMap.get(storageGroup).cardinality();
      if (activeTimeSeriesNum != activeTimeSeriesNumMap.get(storageGroup)) {
        // update the active time series number in the newest memtable to be flushed
        activeTimeSeriesNumMap.put(storageGroup, activeTimeSeriesNum);

        double totalActiveTsNum = 0;
        LOGGER.debug("{}: updating active ratio", Thread.currentThread().getName());
        for (double number : activeTimeSeriesNumMap.values()) {
          totalActiveTsNum += number;
        }
        for (Map.Entry<String, Long> entry : activeTimeSeriesNumMap.entrySet()) {
          double activeRatio = 0;
          if (totalActiveTsNum > 0) {
            activeRatio = entry.getValue() / totalActiveTsNum;
          }
          activeRatioMap.put(entry.getKey(), activeRatio);
          LOGGER.debug("{}: storage group {} has an active ratio: {}",
              Thread.currentThread().getName(),
              entry.getKey(), activeRatio);
        }
      }
      // initialize the HLL counter
      storageGroupHllMap.put(storageGroup, new HyperLogLog(LOG2M));
    } catch (Exception e) {
      LOGGER.error("Update {} active ratio failed", storageGroup, e);
    } finally {
      lock.writeLock().unlock();
    }
  }

}