@Override
  public void commit(TableMetadata base, TableMetadata metadata) {
    Pair<Integer, TableMetadata> current = versionAndMetadata();
    if (base != current.second()) {
      throw new CommitFailedException("Cannot commit changes based on stale table metadata");
    }

    if (base == metadata) {
      LOG.info("Nothing to commit.");
      return;
    }

    Preconditions.checkArgument(
          base == null || base.location().equals(metadata.location()),
          "Hadoop path-based tables cannot be relocated");
    Preconditions.checkArgument(
          !metadata.properties().containsKey(TableProperties.WRITE_METADATA_LOCATION),
          "Hadoop path-based tables cannot relocate metadata");

    String codecName =
          metadata.property(
                TableProperties.METADATA_COMPRESSION, TableProperties.METADATA_COMPRESSION_DEFAULT);
    TableMetadataParser.Codec codec = TableMetadataParser.Codec.fromName(codecName);
    String fileExtension = TableMetadataParser.getFileExtension(codec);
    Path tempMetadataFile = metadataPath(UUID.randomUUID() + fileExtension);
    TableMetadataParser.write(metadata, io().newOutputFile(tempMetadataFile.toString()));

    int nextVersion = (current.first() != null ? current.first() : 0) + 1;
    Path finalMetadataFile = metadataFilePath(nextVersion, codec);
    FileSystem fs = getFileSystem(tempMetadataFile, conf);
    boolean versionCommitSuccess = false;
    boolean useObjectStore =
          metadata.propertyAsBoolean(
                TableProperties.OBJECT_STORE_ENABLED, TableProperties.OBJECT_STORE_ENABLED_DEFAULT);
    int previousVersionsMax =
          metadata.propertyAsInt(
                TableProperties.METADATA_PREVIOUS_VERSIONS_MAX,
                TableProperties.METADATA_PREVIOUS_VERSIONS_MAX_DEFAULT);
    boolean supportGlobalLocking = useObjectStore;
    try {
      tryLock(tempMetadataFile, metadataRoot());
      versionCommitSuccess =
            commitNewVersion(
                  fs, tempMetadataFile, finalMetadataFile, nextVersion, supportGlobalLocking);
      if (!versionCommitSuccess) {
        throw new CommitFailedException(
              "Can not commit newMetaData because version [%s] has already been committed. " +
                    "tempMetaData=[%s],finalMetaData=[%s].Are there other clients running " +
                    "in parallel with the current task?",
              nextVersion, tempMetadataFile, finalMetadataFile);
      }
      validate(supportGlobalLocking, previousVersionsMax, nextVersion, fs, finalMetadataFile);
      this.shouldRefresh = true;
      LOG.info("Committed a new metadata file {}", finalMetadataFile);
      // update the best-effort version pointer
      writeVersionHint(fs, nextVersion);
      deleteRemovedMetadataFiles(base, metadata);
    } catch (CommitStateUnknownException e) {
      this.shouldRefresh = true;
      throw e;
    } catch (Exception e) {
      this.shouldRefresh = versionCommitSuccess;
      if (!versionCommitSuccess) {
        tryDelete(tempMetadataFile);
        throw new CommitFailedException(e);
      }
    } finally {
      unlock(tempMetadataFile, metadataRoot());
    }
  }
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