public String dumpRecordsAsHex(int firstRecordId,
                                 int lastRecordId) throws IOException {
    if (firstRecordId > lastRecordId) {
      return "<no records in range " + firstRecordId + " .. " + lastRecordId + ">";
    }
    long actualFileSize = storage.actualFileSize();
    StringBuilder sb = new StringBuilder();
    for (int recordId = firstRecordId; recordId <= lastRecordId; recordId++) {
      String recordAsHex;
      if (recordId == NULL_ID) {
        recordAsHex = "<header>";
      }
      else {
        long recordOffsetInFile = recordOffsetInFileUnchecked(recordId);

        if (recordOffsetInFile >= actualFileSize) {
          recordAsHex = "<EOF: outside of allocated file region>";
        }
        else {
          int recordOffsetInPage = storage.toOffsetInPage(recordOffsetInFile);

          Page page = storage.pageByOffset(recordOffsetInFile);
          ByteBuffer pageBuffer = page.rawPageBuffer();
          ByteBuffer recordSlice = pageBuffer.slice(recordOffsetInPage, RecordLayout.RECORD_SIZE_IN_BYTES);

          recordAsHex = IOUtil.toHexString(recordSlice);
        }
      }
      sb.append("[#%06d/max=%06d]: ".formatted(recordId, maxAllocatedID()))
        .append(recordAsHex)
        .append('\n');
    }
    return sb.toString();
  }
public String dumpRecordsAsHex(int firstRecordId,
                                 int lastRecordId)