2121
2222import com .fasterxml .jackson .annotation .JsonSubTypes ;
2323import com .fasterxml .jackson .annotation .JsonTypeInfo ;
24+ import org .apache .druid .java .util .common .StringUtils ;
2425import org .apache .druid .server .coordinator .duty .CompactSegments ;
2526
27+ import java .util .Objects ;
28+
2629/**
2730 * Policy used by {@link CompactSegments} duty to pick segments for compaction.
2831 */
2932@ JsonTypeInfo (use = JsonTypeInfo .Id .NAME , property = "type" )
3033@ JsonSubTypes (value = {
3134 @ JsonSubTypes .Type (name = "newestSegmentFirst" , value = NewestSegmentFirstPolicy .class ),
32- @ JsonSubTypes .Type (name = "fixedIntervalOrder" , value = FixedIntervalOrderPolicy .class )
35+ @ JsonSubTypes .Type (name = "fixedIntervalOrder" , value = FixedIntervalOrderPolicy .class ),
36+ @ JsonSubTypes .Type (name = "mostFragmentedFirst" , value = MostFragmentedIntervalFirstPolicy .class )
3337})
3438public interface CompactionCandidateSearchPolicy
3539{
3640 /**
3741 * Compares between two compaction candidates. Used to determine the
3842 * order in which segments and intervals should be picked for compaction.
3943 *
40- * @return A positive value if {@code candidateA} should be picked first, a
41- * negative value if {@code candidateB} should be picked first or zero if the
44+ * @return A negative value if {@code candidateA} should be picked first, a
45+ * positive value if {@code candidateB} should be picked first or zero if the
4246 * order does not matter.
4347 */
4448 int compareCandidates (CompactionCandidate candidateA , CompactionCandidate candidateB );
@@ -47,10 +51,71 @@ public interface CompactionCandidateSearchPolicy
4751 * Checks if the given {@link CompactionCandidate} is eligible for compaction
4852 * in the current iteration. A policy may implement this method to skip
4953 * compacting intervals or segments that do not fulfil some required criteria.
54+ *
55+ * @return {@link Eligibility#OK} only if eligible.
5056 */
51- boolean isEligibleForCompaction (
57+ Eligibility checkEligibilityForCompaction (
5258 CompactionCandidate candidate ,
53- CompactionStatus currentCompactionStatus ,
5459 CompactionTaskStatus latestTaskStatus
5560 );
61+
62+ /**
63+ * Describes the eligibility of an interval for compaction.
64+ */
65+ class Eligibility
66+ {
67+ public static final Eligibility OK = new Eligibility (true , null );
68+
69+ private final boolean eligible ;
70+ private final String reason ;
71+
72+ private Eligibility (boolean eligible , String reason )
73+ {
74+ this .eligible = eligible ;
75+ this .reason = reason ;
76+ }
77+
78+ public boolean isEligible ()
79+ {
80+ return eligible ;
81+ }
82+
83+ public String getReason ()
84+ {
85+ return reason ;
86+ }
87+
88+ public static Eligibility fail (String messageFormat , Object ... args )
89+ {
90+ return new Eligibility (false , StringUtils .format (messageFormat , args ));
91+ }
92+
93+ @ Override
94+ public boolean equals (Object object )
95+ {
96+ if (this == object ) {
97+ return true ;
98+ }
99+ if (object == null || getClass () != object .getClass ()) {
100+ return false ;
101+ }
102+ Eligibility that = (Eligibility ) object ;
103+ return eligible == that .eligible && Objects .equals (reason , that .reason );
104+ }
105+
106+ @ Override
107+ public int hashCode ()
108+ {
109+ return Objects .hash (eligible , reason );
110+ }
111+
112+ @ Override
113+ public String toString ()
114+ {
115+ return "Eligibility{" +
116+ "eligible=" + eligible +
117+ ", reason='" + reason + '\'' +
118+ '}' ;
119+ }
120+ }
56121}
0 commit comments