@Override
  public Iterable<FileStatus> getDeletableFiles(Iterable<FileStatus> files) {
    // The Iterable is lazy evaluated, so if we just pass this Iterable in, we will access the HFile
    // storage inside the snapshot lock, which could take a lot of time (for example, several
    // seconds), and block all other operations, especially other cleaners.
    // So here we convert it to List first, to force it evaluated before calling
    // getUnreferencedFiles, so we will not hold snapshot lock for a long time.
    List<FileStatus> filesList =
      StreamSupport.stream(files.spliterator(), false).collect(Collectors.toList());
    try {
      return cache.getUnreferencedFiles(filesList, master.getSnapshotManager());
    } catch (CorruptedSnapshotException cse) {
      LOG.debug("Corrupted in-progress snapshot file exception, ignored ", cse);
    } catch (IOException e) {
      LOG.error("Exception while checking if files were valid, keeping them just in case.", e);
    }
    return Collections.emptyList();
  }
File cache for HFiles in the completed and currently running snapshots
hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/SnapshotHFileCleaner.java