void persistentBackupFile(String filename, Map<String, Map<String, Long>> usage) throws IOException {
      if (filename == null || filename.isEmpty() || !filenamePattern.matcher(filename).matches()) {
        throw new IllegalArgumentException("Invalid filename :" + filename);
      }
      if (usage == null) {
        throw new IllegalArgumentException("Invalid usage map");
      }

      if (backupFiles.contains(filename)) {
        return;
      }
      logger.trace("Persist container usage for {}", filename);
      String tempFileName = filename + TEMP_FILE_SUFFIX;
      Path tempFilePath = backupDirPath.resolve(tempFileName);
      Path filePath = backupDirPath.resolve(filename);

      // First save the usage in JSON format in the a temp file and then rename this temp file
      // to the target file since renaming file is atomic in POSIX.
      try (FileChannel channel = FileChannel.open(tempFilePath, StandardOpenOption.CREATE,
          StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE)) {
        String usageMapInJson = objectMapper.writeValueAsString(usage);
        channel.write(ByteBuffer.wrap(usageMapInJson.getBytes(StandardCharsets.UTF_8)));
        Files.move(tempFilePath, filePath);
      } catch (Exception e) {
        logger.error("Failed to serialize and persist usage map to file {}", filePath, e);
        throw e;
      }

      backupFiles.add(filename);
    }
Persist the {@code usage} in map under the backup directory with the given {@code filename}. Filename has to match
the date pattern.
@param filename The filename to save the given usage.
@param usage The usage to save.
@throws IOException
ambry-quota/src/main/java/com/github/ambry/quota/storage/MySqlStorageUsageRefresher.java