private static Path mvFile(HiveConf conf, FileSystem sourceFs, Path sourcePath, FileSystem destFs, Path destDirPath,
                             boolean isSrcLocal, boolean isOverwrite, boolean isRenameAllowed,
                             int taskId) throws IOException {

    // Strip off the file type, if any so we don't make:
    // 000000_0.gz -> 000000_0.gz_copy_1
    final String fullname = sourcePath.getName();
    final String name;
    if (taskId == -1) { // non-acid
      name = FilenameUtils.getBaseName(sourcePath.getName());
    } else { // acid
      name = getPathName(taskId);
    }
    final String type = FilenameUtils.getExtension(sourcePath.getName());

    // Incase of ACID, the file is ORC so the extension is not relevant and should not be inherited.
    Path destFilePath = new Path(destDirPath, taskId == -1 ? fullname : name);

    /*
    * The below loop may perform bad when the destination file already exists and it has too many _copy_
    * files as well. A desired approach was to call listFiles() and get a complete list of files from
    * the destination, and check whether the file exists or not on that list. However, millions of files
    * could live on the destination directory, and on concurrent situations, this can cause OOM problems.
    *
    * I'll leave the below loop for now until a better approach is found.
    */
    for (int counter = 1; destFs.exists(destFilePath); counter++) {
      if (isOverwrite) {
        destFs.delete(destFilePath, false);
        break;
      }
      destFilePath =  new Path(destDirPath, name + (Utilities.COPY_KEYWORD + counter) +
              ((taskId == -1 && !type.isEmpty()) ? "." + type : ""));
    }

    if (isRenameAllowed) {
      destFs.rename(sourcePath, destFilePath);
    } else if (isSrcLocal) {
      destFs.copyFromLocalFile(sourcePath, destFilePath);
    } else {
      if (!FileUtils.copy(sourceFs, sourcePath, destFs, destFilePath,
          false,   // delete source
          false,  // overwrite destination
          conf,
          new DataCopyStatistics())) {
        LOG.error("Copy failed for source: " + sourcePath + " to destination: " + destFilePath);
        throw new IOException("File copy failed.");
      }

      // Source file delete may fail because of permission issue as executing user might not
      // have permission to delete the files in the source path. Ignore this failure.
      try {
        if (!sourceFs.delete(sourcePath, true)) {
          LOG.warn("Delete source failed for source: " + sourcePath + " during copy to destination: " + destFilePath);
        }
      } catch (Exception e) {
        LOG.warn("Delete source failed for source: " + sourcePath + " during copy to destination: " + destFilePath, e);
      }
    }
    return destFilePath;
  }
<p>
  Moves a file from one {@link Path} to another. If {@code isRenameAllowed} is true then the
  {@link FileSystem#rename(Path, Path)} method is used to move the file. If its false then the data is copied, if
  {@code isSrcLocal} is true then the {@link FileSystem#copyFromLocalFile(Path, Path)} method is used, else
  {@link FileUtils#copy(FileSystem, Path, FileSystem, Path, boolean, boolean, HiveConf)} is used.
</p>

<p>
  If the destination file already exists, then {@code _copy_[counter]} is appended to the file name, where counter
  is an integer starting from 1.
</p>

@param conf the {@link HiveConf} to use if copying data
@param sourceFs the {@link FileSystem} where the source file exists
@param sourcePath the {@link Path} to move
@param destFs the {@link FileSystem} to move the file to
@param destDirPath the {@link Path} to move the file to
@param isSrcLocal if the source file is on the local filesystem
@param isOverwrite if true, then overwrite destination file if exist else make a duplicate copy
@param isRenameAllowed true if the data should be renamed and not copied, false otherwise

@return the {@link Path} the source file was moved to

@throws IOException if there was an issue moving the file
ql/src/java/org/apache/hadoop/hive/ql/metadata/Hive.java