public static boolean moveFile(final HiveConf conf, Path srcf, final Path destf, boolean replace,
                                 boolean isSrcLocal, boolean isManaged) throws HiveException {
    final FileSystem srcFs, destFs;
    try {
      destFs = destf.getFileSystem(conf);
    } catch (IOException e) {
      LOG.error("Failed to get dest fs", e);
      throw new HiveException(e.getMessage(), e);
    }
    try {
      srcFs = srcf.getFileSystem(conf);
    } catch (IOException e) {
      LOG.error("Failed to get src fs", e);
      throw new HiveException(e.getMessage(), e);
    }

    String configuredOwner = HiveConf.getVar(conf, ConfVars.HIVE_LOAD_DATA_OWNER);

    // If source path is a subdirectory of the destination path (or the other way around):
    //   ex: INSERT OVERWRITE DIRECTORY 'target/warehouse/dest4.out' SELECT src.value WHERE src.key >= 300;
    //   where the staging directory is a subdirectory of the destination directory
    // (1) Do not delete the dest dir before doing the move operation.
    // (2) It is assumed that subdir and dir are in same encryption zone.
    // (3) Move individual files from scr dir to dest dir.
    boolean srcIsSubDirOfDest = isSubDir(srcf, destf, srcFs, destFs, isSrcLocal),
        destIsSubDirOfSrc = isSubDir(destf, srcf, destFs, srcFs, false);
    final String msg = "Unable to move source " + srcf + " to destination " + destf;
    try {
      if (replace) {
        try{
          //if destf is an existing directory:
          //if replace is true, delete followed by rename(mv) is equivalent to replace
          //if replace is false, rename (mv) actually move the src under dest dir
          //if destf is an existing file, rename is actually a replace, and do not need
          // to delete the file first
          if (replace && !srcIsSubDirOfDest) {
            destFs.delete(destf, true);
            LOG.debug("The path " + destf.toString() + " is deleted");
          }
        } catch (FileNotFoundException ignore) {
        }
      }
      final SessionState parentSession = SessionState.get();
      if (isSrcLocal) {
        // For local src file, copy to hdfs
        destFs.copyFromLocalFile(srcf, destf);
        return true;
      } else {
        if (needToCopy(conf, srcf, destf, srcFs, destFs, configuredOwner, isManaged)) {
          //copy if across file system or encryption zones.
          LOG.debug("Copying source " + srcf + " to " + destf + " because HDFS encryption zones are different.");
          return FileUtils.copy(srcf.getFileSystem(conf), srcf, destf.getFileSystem(conf), destf,
              true,    // delete source
              replace, // overwrite destination
              conf,
              new DataCopyStatistics());
        } else {
          if (srcIsSubDirOfDest || destIsSubDirOfSrc) {
            FileStatus[] srcs = destFs.listStatus(srcf, FileUtils.HIDDEN_FILES_PATH_FILTER);

            List<Future<Void>> futures = new LinkedList<>();
            final ExecutorService pool = conf.getInt(ConfVars.HIVE_MOVE_FILES_THREAD_COUNT.varname, 25) > 0 ?
                Executors.newFixedThreadPool(conf.getInt(ConfVars.HIVE_MOVE_FILES_THREAD_COUNT.varname, 25),
                new ThreadFactoryBuilder().setDaemon(true).setNameFormat("Move-Thread-%d").build()) : null;
            if (destIsSubDirOfSrc && !destFs.exists(destf)) {
              if (Utilities.FILE_OP_LOGGER.isTraceEnabled()) {
                Utilities.FILE_OP_LOGGER.trace("Creating " + destf);
              }
              destFs.mkdirs(destf);
            }
            /* Move files one by one because source is a subdirectory of destination */
            for (final FileStatus srcStatus : srcs) {

              final Path destFile = new Path(destf, srcStatus.getPath().getName());

              final String poolMsg =
                  "Unable to move source " + srcStatus.getPath() + " to destination " + destFile;

              if (null == pool) {
                deleteAndRename(destFs, destFile, srcStatus, destf);
              } else {
                futures.add(pool.submit(new Callable<Void>() {
                  @Override
                  public Void call() throws HiveException {
                    SessionState.setCurrentSessionState(parentSession);
                    try {
                      deleteAndRename(destFs, destFile, srcStatus, destf);
                    } catch (Exception e) {
                      throw getHiveException(e, poolMsg);
                    }
                    return null;
                  }
                }));
              }
            }
            if (null != pool) {
              pool.shutdown();
              for (Future<Void> future : futures) {
                try {
                  future.get();
                } catch (Exception e) {
                  throw handlePoolException(pool, e);
                }
              }
            }
            return true;
          } else {
            if (destFs.rename(srcf, destf)) {
              return true;
            }
            return false;
          }
        }
      }
    } catch (Exception e) {
      throw getHiveException(e, msg);
    }
  }
Recycles the files recursively from the input path to the cmroot directory either by copying or moving it.

@param dataPath Path of the data files to be recycled to cmroot
@param isPurge
         When set to true files which needs to be recycled are not moved to Trash
ql/src/java/org/apache/hadoop/hive/ql/metadata/Hive.java