code: public List<Future<?>> submitBackground(final ColumnFamilyStore cfs)
      {
          if (cfs.isAutoCompactionDisabled())
          {
              logger.debug("Autocompaction is disabled");
              return Collections.emptyList();
          }
  
          int count = compactingCF.count(cfs);
          if (count > 0 && executor.getActiveCount() >= executor.getMaximumPoolSize())
          {
              logger.debug("Background compaction is still running for {}.{} ({} remaining). Skipping",
                           cfs.keyspace.getName(), cfs.name, count);
              return Collections.emptyList();
          }
  
          logger.debug("Scheduling a background task check for {}.{} with {}",
                       cfs.keyspace.getName(),
                       cfs.name,
                       cfs.getCompactionStrategy().getName());
          List<Future<?>> futures = new ArrayList<Future<?>>();
          // we must schedule it at least once, otherwise compaction will stop for a CF until next flush
          do {
              if (executor.isShutdown())
              {
                  logger.info("Executor has shut down, not submitting background task");
                  return Collections.emptyList();
              }
              compactingCF.add(cfs);
              futures.add(executor.submit(new BackgroundCompactionTask(cfs)));
              // if we have room for more compactions, then fill up executor
          } while (executor.getActiveCount() + futures.size() < executor.getMaximumPoolSize());
  
          return futures;
      }
docs: Call this whenever a compaction might be needed on the given columnfamily.
  It's okay to over-call (within reason) if a call is unnecessary, it will
  turn into a no-op in the bucketing/candidate-scan phase.