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);
}