@Override
  public boolean run(CompactorContext context)
       throws IOException, HiveException, InterruptedException {
    if (context.getCompactionInfo().runAs.equals(System.getProperty("user.name"))) {
      run(context.getConf(), context.getTable(), context.getSd(),
              context.getValidWriteIdList(), context.getCompactionInfo(), context.getAcidDirectory());
    } else {
      UserGroupInformation ugi = UserGroupInformation.createProxyUser(context.getCompactionInfo().runAs,
              UserGroupInformation.getLoginUser());
      ugi.doAs((PrivilegedExceptionAction<Object>) () -> {
        run(context.getConf(), context.getTable(), context.getSd(),
                context.getValidWriteIdList(), context.getCompactionInfo(), context.getAcidDirectory());
        return null;
      });
      try {
        FileSystem.closeAllForUGI(ugi);
      } catch (IOException exception) {
        LOG.error("Could not clean up file-system handles for UGI: " + ugi + " for " + context.getCompactionInfo().getFullPartitionName(),
            exception);
      }
    }
    return true;
  }
Class to do compactions via an MR job.  This has to be in the ql package rather than metastore
.compactions package with all of it's relatives because it needs access to the actual input
and output formats, which are in ql.  ql depends on metastore and we can't have a circular
dependency.
ql/src/java/org/apache/hadoop/hive/ql/txn/compactor/MRCompactor.java