private void runJob(
        long transactionId, OptionalInt bucketNumber, long tableId, Set<UUID> shardUuids)
        throws IOException {
      TableMetadata metadata = getTableMetadata(tableId);

      // This job could be in the queue for quite some time, so before doing any expensive
      // operations,
      // filter out shards that no longer exist, reducing the possibility of failure
      shardUuids = shardManager.getExistingShardUuids(tableId, shardUuids);
      if (shardUuids.size() <= 1) {
        return;
      }

      List<ShardInfo> newShards =
          performCompaction(transactionId, bucketNumber, shardUuids, metadata);
      log.info(
          "Compacted shards %s into %s",
          shardUuids, newShards.stream().map(ShardInfo::getShardUuid).collect(toList()));
      shardManager.replaceShardUuids(
          transactionId,
          tableId,
          metadata.getColumns(),
          shardUuids,
          newShards,
          OptionalLong.empty());
    }
 private List<ShardInfo> performCompaction(
     long transactionId,
     OptionalInt bucketNumber,
     Set<UUID> shardUuids,
     TableMetadata tableMetadata)
     throws IOException {
   if (tableMetadata.getSortColumnIds().isEmpty()) {
     return compactor.compact(
         transactionId, bucketNumber, shardUuids, tableMetadata.getColumns());
   }
   return compactor.compactSorted(
       transactionId,
       bucketNumber,
       shardUuids,
       tableMetadata.getColumns(),
       tableMetadata.getSortColumnIds(),
       nCopies(tableMetadata.getSortColumnIds().size(), ASC_NULLS_FIRST));
 }