@VisibleForTesting
  int findVersionWithOutVersionHint(FileSystem fs) {
    try {
      if (!fs.exists(metadataRoot())) {
        // Either the table has just been created, or it has been corrupted, but either way, we have
        // to start at version 0.
        LOG.warn("Metadata for table not found in directory [{}]", metadataRoot());
        return 0;
      }
      // List the metadata directory to find the version files, and try to recover the max
      // available version
      FileStatus[] files =
            fs.listStatus(metadataRoot(), name -> VERSION_PATTERN.matcher(name.getName()).matches());
      int maxVersion = 0;
      for (FileStatus file : files) {
        int currentVersion = version(file.getPath().getName());
        if (currentVersion > maxVersion && getMetadataFile(currentVersion) != null) {
          maxVersion = currentVersion;
        }
      }
      return maxVersion;
    } catch (Exception e) {
      throw new RuntimeIOException(new IOException(e));
    }
  }
TableOperations implementation for file systems.

<p>For normal file-system(support atomic non-overwriting rename). Users can use it directly
without configuring additional lockManager.

<p>For object storage(not support atomic non-overwriting rename), user should choose a suitable
lockManager implementation.

<p>This maintains metadata in a "metadata" folder under the table location.
iceberg/patched-iceberg-core/src/main/java/org/apache/iceberg/hadoop/HadoopTableOperations.java