private void uploadPartCopy0(WriteOptions options, String sourcePath, String path, long start, long end,
        String uploadId, int partNumber, CompletableFuture<ObjectStorageCompletedPart> cf) {
        TimerUtil timerUtil = new TimerUtil();
        doUploadPartCopy(options, sourcePath, path, start, end, uploadId, partNumber).thenAccept(part -> {
            S3OperationStats.getInstance().uploadPartCopyStats(true).record(timerUtil.elapsedAs(TimeUnit.NANOSECONDS));
            cf.complete(part);
        }).exceptionally(ex -> {
            S3OperationStats.getInstance().uploadPartCopyStats(false).record(timerUtil.elapsedAs(TimeUnit.NANOSECONDS));
            Pair<RetryStrategy, Throwable> strategyAndCause = toRetryStrategyAndCause(ex, S3Operation.UPLOAD_PART_COPY);
            RetryStrategy retryStrategy = strategyAndCause.getLeft();
            Throwable cause = strategyAndCause.getRight();
            if (retryStrategy == RetryStrategy.ABORT || checkS3ApiMode) {
                logger.warn("UploadPartCopy for object {}-{} [{}, {}] fail", path, partNumber, start, end, cause);
                cf.completeExceptionally(cause);
            } else {
                long nextApiCallAttemptTimeout = Math.min(options.apiCallAttemptTimeout() * 2, TimeUnit.MINUTES.toMillis(10));
                options.apiCallAttemptTimeout(nextApiCallAttemptTimeout);
                int delay = retryDelay(S3Operation.UPLOAD_PART_COPY, options.retryCountGetAndAdd());
                logger.warn("UploadPartCopy for object {}-{} [{}, {}] fail, retry in {}ms with apiCallAttemptTimeout={}", path, partNumber, start, end, delay, nextApiCallAttemptTimeout, cause);
                scheduler.schedule(() -> uploadPartCopy0(options, sourcePath, path, start, end, uploadId, partNumber, cf), delay, TimeUnit.MILLISECONDS);
            }
            return null;
        });
    }
Upload a part of an object to the specified path.

@param options    options (or context) about the write operation
@param path       the path of the object where the part will be uploaded
@param uploadId   the upload ID of the multipart upload
@param partNumber the part number of the part to be uploaded
@param data       the data to be uploaded, it will be released once the finalCf is done
@param attemptCf  the CompletableFuture to complete when a single attempt is done
@param finalCf    the CompletableFuture to complete when the upload operation is done
s3stream/src/main/java/com/automq/stream/s3/operator/AbstractObjectStorage.java