private SortedMap<Long, Long> getAndValidateMissingChunks(
        int maxAlloc, long from, long to) {
      Map.Entry<Long, Long> firstMissing = chunkIndex.floorEntry(from);
      if (firstMissing == null) {
        throw new AssertionError("No lower bound for start offset " + from);
      }
      if (firstMissing.getValue() <= from
          || ((from - firstMissing.getKey()) % maxAlloc) != 0) {
        // The data does not belong to a recognized chunk, or is split wrong.
        throw new AssertionError("Lower bound for start offset " + from + " is ["
            + firstMissing.getKey() + ", " + firstMissing.getValue() + ")");
      }
      SortedMap<Long, Long> missingChunks = chunkIndex.subMap(firstMissing.getKey(), to);
      if (missingChunks.isEmpty()) {
        throw new AssertionError("No chunks for [" + from + ", " + to + ")");
      }
      long lastMissingOffset = missingChunks.lastKey(),
          lastMissingEnd = missingChunks.get(lastMissingOffset);
      if (lastMissingEnd < to
          || (to != lastMissingEnd && ((to - lastMissingOffset) % maxAlloc) != 0)) {
        // The data does not belong to a recognized chunk, or is split wrong.
        throw new AssertionError("Lower bound for end offset " + to + " is ["
            + lastMissingOffset + ", " + lastMissingEnd + ")");
      }
      return missingChunks;
    }
This is currently only used by Parquet; however, a generally applicable approach is used -
you pass in a set of offset pairs for a file, and the file is cached with these boundaries.
Don't add anything format specific here.
ql/src/java/org/apache/hadoop/hive/llap/LlapCacheAwareFs.java