private Collection planCompactions()

in server/base/src/main/java/org/apache/accumulo/server/compaction/CompactionJobGenerator.java [167:303]


  private Collection<CompactionJob> planCompactions(CompactionServiceId serviceId,
      CompactionKind kind, TabletMetadata tablet, Map<String,String> executionHints) {

    if (!servicesConfig.getPlanners().containsKey(serviceId.canonical())) {
      UNKNOWN_SERVICE_ERROR_LOG.trace(
          "Table {} returned non-existent compaction service {} for compaction type {}.  Check"
              + " the table compaction dispatcher configuration. No compactions will happen"
              + " until the configuration is fixed. This log message is temporarily suppressed.",
          tablet.getExtent().tableId(), serviceId, kind);
      return Set.of();
    }

    CompactionPlanner planner =
        planners.computeIfAbsent(serviceId, sid -> createPlanner(tablet.getTableId(), serviceId));

    // selecting indicator
    // selected files

    String ratioStr =
        env.getConfiguration(tablet.getTableId()).get(Property.TABLE_MAJC_RATIO.getKey());
    if (ratioStr == null) {
      ratioStr = Property.TABLE_MAJC_RATIO.getDefaultValue();
    }

    double ratio = Double.parseDouble(ratioStr);

    Set<CompactableFile> allFiles = tablet.getFilesMap().entrySet().stream()
        .map(entry -> new CompactableFileImpl(entry.getKey(), entry.getValue()))
        .collect(Collectors.toUnmodifiableSet());
    Set<CompactableFile> candidates;

    if (kind == CompactionKind.SYSTEM) {
      if (tablet.getExternalCompactions().isEmpty() && tablet.getSelectedFiles() == null) {
        candidates = allFiles;
      } else {
        var tmpFiles = new HashMap<>(tablet.getFilesMap());
        // remove any files that are in active compactions
        tablet.getExternalCompactions().values().stream().flatMap(ecm -> ecm.getJobFiles().stream())
            .forEach(tmpFiles::remove);
        // remove any files that are selected and the user compaction has completed
        // at least 1 job, otherwise we can keep the files
        var selectedFiles = tablet.getSelectedFiles();

        if (selectedFiles != null) {
          long selectedExpirationDuration =
              ConfigurationTypeHelper.getTimeInMillis(env.getConfiguration(tablet.getTableId())
                  .get(Property.TABLE_COMPACTION_SELECTION_EXPIRATION.getKey()));

          // If jobs are completed, or selected time has not expired, the remove
          // from the candidate list otherwise we can cancel the selection
          if (selectedFiles.getCompletedJobs() > 0
              || (steadyTime.minus(selectedFiles.getSelectedTime()).toMillis()
                  < selectedExpirationDuration)) {
            tmpFiles.keySet().removeAll(selectedFiles.getFiles());
          }
        }
        candidates = tmpFiles.entrySet().stream()
            .map(entry -> new CompactableFileImpl(entry.getKey(), entry.getValue()))
            .collect(Collectors.toUnmodifiableSet());
      }
    } else if (kind == CompactionKind.USER) {
      var selectedFiles = new HashSet<>(tablet.getSelectedFiles().getFiles());
      tablet.getExternalCompactions().values().stream().flatMap(ecm -> ecm.getJobFiles().stream())
          .forEach(selectedFiles::remove);
      candidates = selectedFiles.stream()
          .map(file -> new CompactableFileImpl(file, tablet.getFilesMap().get(file)))
          .collect(Collectors.toUnmodifiableSet());
    } else {
      throw new UnsupportedOperationException();
    }

    if (candidates.isEmpty()) {
      // there are not candidate files for compaction, so no reason to call the planner
      return Set.of();
    }

    CompactionPlanner.PlanningParameters params = new CompactionPlanner.PlanningParameters() {

      @Override
      public NamespaceId getNamespaceId() throws TableNotFoundException {
        return ((ServiceEnvironmentImpl) env).getContext().getNamespaceId(tablet.getTableId());
      }

      @Override
      public TableId getTableId() {
        return tablet.getTableId();
      }

      @Override
      public ServiceEnvironment getServiceEnvironment() {
        return (ServiceEnvironment) env;
      }

      @Override
      public CompactionKind getKind() {
        return kind;
      }

      @Override
      public double getRatio() {
        return ratio;
      }

      @Override
      public Collection<CompactableFile> getAll() {
        return allFiles;
      }

      @Override
      public Collection<CompactableFile> getCandidates() {
        return candidates;
      }

      @Override
      public Collection<CompactionJob> getRunningCompactions() {
        var allFiles2 = tablet.getFilesMap();
        return tablet.getExternalCompactions().values().stream().map(ecMeta -> {
          Collection<CompactableFile> files = ecMeta.getJobFiles().stream()
              .map(f -> new CompactableFileImpl(f, allFiles2.get(f))).collect(Collectors.toList());
          CompactionJob job = new CompactionJobImpl(ecMeta.getPriority(),
              ecMeta.getCompactionGroupId(), files, ecMeta.getKind());
          return job;
        }).collect(Collectors.toUnmodifiableList());
      }

      @Override
      public Map<String,String> getExecutionHints() {
        return executionHints;
      }

      @Override
      public CompactionPlan.Builder createPlanBuilder() {
        return new CompactionPlanImpl.BuilderImpl(kind, candidates);
      }
    };
    return planCompactions(planner, params, serviceId);
  }