
fi.evolver.basics.spring.clean.MaxRowsCleaner Maven / Gradle / Ivy
package fi.evolver.basics.spring.clean;
import static fi.evolver.utils.timing.TimingUtils.begin;
import java.time.Instant;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import fi.evolver.basics.spring.job.ResultState;
import fi.evolver.basics.spring.job.TaskStatusService;
import fi.evolver.basics.spring.job.entity.TaskStatus.TaskState;
import fi.evolver.basics.spring.triggerable.TriggerableException;
import fi.evolver.utils.arg.Arg;
import fi.evolver.utils.arg.LongArg;
import fi.evolver.utils.timing.TimingUtils.AutoCloser;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.TypedQuery;
@Component
public class MaxRowsCleaner extends GenericCleaner {
private static final LongArg ARG_MAX_ROWS = new LongArg("MaxRows", 0L, null);
@PersistenceContext
private EntityManager em;
@Autowired
public MaxRowsCleaner(DataCleaner dataCleaner, TaskStatusService taskStatusService) {
super(dataCleaner, taskStatusService);
}
@Override
protected ResultState clean(Class> table, Map args) throws TriggerableException {
Instant maxStartTime = Instant.now().plusMillis(ARG_MAX_RUN_TIME_MS.get(args));
long maxBatchSize = ARG_MAX_BATCH_SIZE.get(args);
long maxRows = ARG_MAX_ROWS.get(args);
int deleted = 0;
int batch = 0;
long originalCount = countRows(table);
long count = originalCount;
if (count <= maxRows)
return new ResultState(TaskState.NOTHING_TO_DO, "%s count %s within limits", table.getSimpleName(), count);
while (count > maxRows) {
try (AutoCloser t = begin("Batch")) {
taskStatusService.updateMessage("Deleted %d / %d %s rows", deleted, originalCount - maxRows, table.getSimpleName());
long minId = queryMinId(table);
long delete = Math.min(count - maxRows, maxBatchSize);
deleted += dataCleaner.deleteByIdLessThan(table, minId + delete);
++batch;
count = countRows(table);
}
if (Instant.now().isAfter(maxStartTime)) {
LOG.info("Out of time after {} batches: stopping", batch);
break;
}
}
return ResultState.ok(deleted > 0, "Deleted %s of %s %s rows", deleted, originalCount, table.getSimpleName());
}
private long queryMinId(Class> table) {
try (AutoCloser t = begin("MinId")) {
TypedQuery query = em.createQuery("SELECT min(id) FROM " + table.getSimpleName(), Long.class);
return query.getSingleResult();
}
}
private long countRows(Class> table) {
try (AutoCloser t = begin("Count")) {
taskStatusService.updateMessage("Counting %s entities", table.getSimpleName());
TypedQuery query = em.createQuery("SELECT count(t) FROM " + table.getSimpleName() + " t", Long.class);
return query.getSingleResult();
}
}
@Override
protected List> getAdditionalArgs() {
return Arrays.asList(ARG_MAX_ROWS);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy