private static void copyFiles(final HiveConf conf, final FileSystem destFs,
            FileStatus[] srcs, final FileSystem srcFs, final Path destf,
            final boolean isSrcLocal, boolean isOverwrite,
            final List<Path> newFiles, boolean acidRename, boolean isManaged,
            boolean isCompactionTable) throws HiveException {

    try {
      FileStatus fullDestStatus = destFs.getFileStatus(destf);
      if (!fullDestStatus.isDirectory()) {
        throw new HiveException(destf + " is not a directory.");
      }
    } catch (IOException e1) {
      throw new HiveException(e1);
    }

    final List<Future<Pair<Path, Path>>> 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;
    // For ACID non-bucketed case, the filenames have to be in the format consistent with INSERT/UPDATE/DELETE Ops,
    // i.e, like 000000_0, 000001_0_copy_1, 000002_0.gz etc.
    // The extension is only maintained for files which are compressed.
    int taskId = 0;
    // Sort the files
    Arrays.sort(srcs);
    String configuredOwner = HiveConf.getVar(conf, ConfVars.HIVE_LOAD_DATA_OWNER);
    FileStatus[] files;
    for (FileStatus src : srcs) {
      if (src.isDirectory()) {
        try {
          files = srcFs.listStatus(src.getPath(), FileUtils.HIDDEN_FILES_PATH_FILTER);
        } catch (IOException e) {
          if (null != pool) {
            pool.shutdownNow();
          }
          throw new HiveException(e);
        }
      } else {
        files = new FileStatus[] {src};
      }

      if (isCompactionTable && HiveConf.getBoolVar(conf, HiveConf.ConfVars.HIVE_WRITE_ACID_VERSION_FILE)) {
        try {
          AcidUtils.OrcAcidVersion.writeVersionFile(destf, destFs);
        } catch (IOException e) {
          if (null != pool) {
            pool.shutdownNow();
          }
          throw new HiveException(e);
        }
      }

      final SessionState parentSession = SessionState.get();
      // Sort the files
      Arrays.sort(files);
      for (final FileStatus srcFile : files) {
        final Path srcP = srcFile.getPath();
        final boolean needToCopy = needToCopy(conf, srcP, destf, srcFs, destFs, configuredOwner, isManaged);

        final boolean isRenameAllowed = !needToCopy && !isSrcLocal;

        final String msg = "Unable to move source " + srcP + " to destination " + destf;

        // If we do a rename for a non-local file, we will be transfering the original
        // file permissions from source to the destination. Else, in case of mvFile() where we
        // copy from source to destination, we will inherit the destination's parent group ownership.
        if (null == pool) {
          try {
            Path destPath = mvFile(conf, srcFs, srcP, destFs, destf, isSrcLocal, isOverwrite, isRenameAllowed,
                    acidRename ? taskId++ : -1);

            if (null != newFiles) {
              newFiles.add(destPath);
            }
          } catch (Exception e) {
            throw getHiveException(e, msg, "Failed to move: {}");
          }
        } else {
          // future only takes final or seemingly final values. Make a final copy of taskId
          final int finalTaskId = acidRename ? taskId++ : -1;
          futures.add(pool.submit(new Callable<Pair<Path, Path>>() {
            @Override
            public Pair<Path, Path> call() throws HiveException {
              SessionState.setCurrentSessionState(parentSession);

              try {
                Path destPath =
                    mvFile(conf, srcFs, srcP, destFs, destf, isSrcLocal, isOverwrite, isRenameAllowed, finalTaskId);

                if (null != newFiles) {
                  newFiles.add(destPath);
                }
                return Pair.of(srcP, destPath);
              } catch (Exception e) {
                throw getHiveException(e, msg);
              }
            }
          }));
        }
      }
    }
    if (null != pool) {
      pool.shutdown();
      for (Future<Pair<Path, Path>> future : futures) {
        try {
          Pair<Path, Path> pair = future.get();
          LOG.debug("Moved src: {}, to dest: {}", pair.getLeft().toString(), pair.getRight().toString());
        } catch (Exception e) {
          throw handlePoolException(pool, e);
        }
      }
    }
  }
@param objectType
         hive object type
@param principalName
@param principalType
@param dbName
@param tableName
@param partValues
@param columnName
@return list of privileges
@throws HiveException
ql/src/java/org/apache/hadoop/hive/ql/metadata/Hive.java