Class CleanupCriterionEvaluator
- a node under an excluded path prefix is never a candidate
- DELETE: created AND last modified older than the campaign period, and content size above the floor
- PURGE_VERSIONS: the file owns at least one PURGEABLE version — see
selectVersionsToRemove(java.util.Map<java.lang.String, java.lang.Long>, java.lang.String, java.lang.String, org.exoplatform.addons.documents.cleanup.model.CleanupParams, long)for the union of the age rule and the count rule that defines the removal set — and the size of that removal set is above the floor
CleanupCandidate, so it stays
visible as 'Kept' in every campaign.
The criterion is split in two: a CHEAP decision (path exclusion, the two
dates, the size of the removal set) and the EXPENSIVE size measurements,
supplied lazily. evaluateLazily(long, long, int, java.lang.String, org.exoplatform.addons.documents.cleanup.model.CleanupParams, long, java.util.function.LongSupplier, java.util.function.LongSupplier) pulls a size only once the cheap
decision needs it to answer, so a scan pays a size read only for the nodes
that reach the size floor test at all — see the ordering rationale there. It
is the ONE entry point, for the scan and the revalidation paths alike (both
reach it through CleanupJcrStorage#toCandidate) and for the tests: a
caller already holding a size passes () -> size, which keeps the
policy defined exactly once instead of behind an eager facade no production
caller could have.
-
Method Summary
Modifier and TypeMethodDescriptionstatic CleanupActionevaluateLazily(long createdTime, long lastModifiedTime, int purgeableVersionCount, String path, CleanupParams params, long nowMillis, LongSupplier fileSizeSupplier, LongSupplier purgeableVersionsSizeSupplier) The candidate criterion, with the two sizes supplied lazily: a supplier is invoked ONLY when the decision cannot be reached without it.selectVersionsToRemove(Map<String, Long> versionCreationDates, String rootVersionName, String baseVersionName, CleanupParams params, long nowMillis) Selects the versions of a versionable file to remove, as the UNION of the TWO purge rules — an age rule and a count rule — the architect ruled on: neither replaces the other.
-
Method Details
-
selectVersionsToRemove
public static List<String> selectVersionsToRemove(Map<String, Long> versionCreationDates, String rootVersionName, String baseVersionName, CleanupParams params, long nowMillis) Selects the versions of a versionable file to remove, as the UNION of the TWO purge rules — an age rule and a count rule — the architect ruled on: neither replaces the other. This removal set is the ONE definition of the purge policy:evaluateLazily(long, long, int, java.lang.String, org.exoplatform.addons.documents.cleanup.model.CleanupParams, long, java.util.function.LongSupplier, java.util.function.LongSupplier)counts it to decide candidacy at scan and at revalidation time, and the execution removes exactly it, so the three can never disagree.- the ROOT version and the BASE (current) version are NEVER removed — skipped by name, and JCR forbids removing them anyway
- every remaining version whose OWN creation date is older than the
campaign period (
nowMillis - periodMonths) is removed; the version's own date, never the file's — a file touched yesterday can still carry versions from three years ago, and those are the PO's actual target - of the versions still standing after that — all of them inside the
period — the OLDEST are removed while their count STILL exceeds
maxVersionsPerFile
maxVersionsPerFileversions, all inside the period, plus the base and root versions.THE CASE A READER WILL WONDER ABOUT: the base version may itself be older than the period, and it survives regardless — it is the file's CURRENT content, not an old revision. Reclaiming it would destroy the file, which is the DELETE action's job (and its own dates decide that), never this one's.
A version whose creation date is unknown (non-positive) is never removed BY AGE — the same doubt-favours-the-file rule as
isAged(long, long, org.exoplatform.addons.documents.cleanup.model.CleanupParams, long)— but it does count against the cap, and being the oldest by sort order it is the first the count rule trims.- Parameters:
versionCreationDates- creation date (epoch millis) of EVERY version of the file, keyed by version name, root and base versions included: they are skipped here so the exclusion stays defined oncerootVersionName- name of the version history's root versionbaseVersionName- name of the file's base (current) versionparams- campaign parameters snapshotnowMillis- evaluation time (epoch millis)- Returns:
- the names of the versions to remove, OLDEST FIRST, empty when the file has nothing to purge
-
evaluateLazily
public static CleanupAction evaluateLazily(long createdTime, long lastModifiedTime, int purgeableVersionCount, String path, CleanupParams params, long nowMillis, LongSupplier fileSizeSupplier, LongSupplier purgeableVersionsSizeSupplier) The candidate criterion, with the two sizes supplied lazily: a supplier is invoked ONLY when the decision cannot be reached without it. A caller already holding a size hands over() -> sizerather than reaching for a second, eager entry point — there is none, on purpose.WHY the ordering matters (do not 'simplify' it away): a sequential dry-run measuring both sizes up-front for every nt:file was measured saturating BOTH Infinispan JCR caches at their 1,000,000-entry cap — 'collaboration' (the files) and 'system' (the version histories) — with the JVM heap climbing from ~5 GB to ~20 GB. Measuring the versions size alone costs about THREE nodes per version (jcr:frozenNode -> jcr:content -> jcr:data), so an eager measurement charges that to every scanned file instead of only to the ones whose candidacy actually turns on it.
Cost that REMAINS: the version HISTORY still has to be read for every versionable file, because the count rule of
selectVersionsToRemove(java.util.Map<java.lang.String, java.lang.Long>, java.lang.String, java.lang.String, org.exoplatform.addons.documents.cleanup.model.CleanupParams, long)is age-INDEPENDENT and a file created last week can exceed the cap — that is what keeps pressuring the 'system' workspace cache, and this split does NOT remove it. What that walk reads is now only each version's NAME and OWN creation date, never a frozen node, so the ~3 nodes per version are charged solely to the versions actually being removed, on a file already known to be a candidate.- Parameters:
createdTime- node creation time (epoch millis, 0 = unknown)lastModifiedTime- node last modification time (epoch millis, 0 = unknown, falls back to createdTime)purgeableVersionCount- number of versions the purge would remove, as selected byselectVersionsToRemove(java.util.Map<java.lang.String, java.lang.Long>, java.lang.String, java.lang.String, org.exoplatform.addons.documents.cleanup.model.CleanupParams, long)(0 for a non-versionable file, which has no version history at all)path- node pathparams- campaign parameters snapshotnowMillis- evaluation time (epoch millis)fileSizeSupplier- content size in bytes, measured on demandpurgeableVersionsSizeSupplier- cumulated size of the versions the purge would remove, in bytes, measured on demand- Returns:
- the qualifying
CleanupAction, or null when the node is not a candidate
-