@@ -117,17 +117,23 @@ private static Single readSingleFrom(StreamInput in) throws IOException {
117117 * This enumeration defines the possible types of decisions
118118 */
119119 enum Type implements Writeable {
120- // ordered by positiveness; order matters for serialization and comparison
121- NO ,
122- NOT_PREFERRED ,
123- // Temporarily throttled is a better choice than choosing a not-preferred node,
124- // but NOT_PREFERRED and THROTTLED are generally not comparable.
125- THROTTLE ,
126- YES ;
120+ // order matters only for serialization, do NOT use for comparison
121+ NO (0 , 0 ),
122+ NOT_PREFERRED (1 , 2 ),
123+ THROTTLE (2 , 1 ),
124+ YES (3 , 3 );
127125
128126 // visible for testing
129127 static final TransportVersion ALLOCATION_DECISION_NOT_PREFERRED = TransportVersion .fromName ("allocation_decision_not_preferred" );
130128
129+ private final int nodeComparisonOrdinal ;
130+ private final int decisionComparisonOrdinal ;
131+
132+ Type (int nodeComparisonOrdinal , int decisionComparisonOrdinal ) {
133+ this .nodeComparisonOrdinal = nodeComparisonOrdinal ;
134+ this .decisionComparisonOrdinal = decisionComparisonOrdinal ;
135+ }
136+
131137 public static Type readFrom (StreamInput in ) throws IOException {
132138 if (in .getTransportVersion ().supports (AllocationDecision .ADD_NOT_PREFERRED_ALLOCATION_DECISION )) {
133139 return in .readEnum (Type .class );
@@ -173,38 +179,29 @@ public void writeTo(StreamOutput out) throws IOException {
173179 }
174180
175181 /**
176- * Compares this decision against a new decision. A temporarily THROTTLE'ed node is a better choice than a NOT_PREFERRED node.
182+ * Compares this decision against another decision (for choosing a node)
177183 * <p>
178- * This is used in simulation, which does not encounter THROTTLE; and allocation explain, which will choose a target node that is
179- * THROTTLED temporarily (which simulation ignores and will assign to) over one that is NOT_PREFERRED. Simulation
180- * and explain both use the same code paths in the Allocator code, so this helper is used in the Allocator code.
184+ * This comparison is used at the node level when deciding which node to allocate a shard to. We prefer to wait and allocate a shard
185+ * to a <code>THROTTLE</code>'d node than to move a shard to a <code>NOT_PREFERRED</code> node immediately.
186+ *
187+ * @return 0 when this == other, 1 when this > other, -1 when this < other
181188 */
182- public boolean isBetterAcrossNodes (Type newDecision ) {
183- return this . compareTo ( newDecision ) > 0 ;
189+ public int compareToBetweenNodes (Type other ) {
190+ return Integer . compare ( nodeComparisonOrdinal , other . nodeComparisonOrdinal ) ;
184191 }
185192
186193 /**
187- * Compares this decision against a new decision. THROTTLE is considered a worse decision than NOT_PREFERRED.
194+ * Compares this decision against another decision (for decision-aggregation)
188195 * <p>
189- * A node that has both NOT_PREFERRED and THROTTLE decider results must surface THROTTLE so that the shard does not get moved.
190- * THROTTLE will go away eventually and NOT_PREFERRED will surface, and then different action can be taken. This is important for
191- * the Reconciler executing real shard movement decisions. Allocation explain will also use it for individual node explanations.
196+ * This comparison is used when aggregating the results from many deciders. If one decider returns <code>THROTTLE</code> and
197+ * another returns <code>NOT_PREFERRED</code>, we want to return <code>THROTTLE</code> to ensure we respect any throttling deciders.
198+ * This can only occur in the reconciler or non-desired balancer, in both cases if we see a <code>THROTTLE</code> we want to
199+ * respect that until it resolves.
200+ *
201+ * @return 0 when this == other, 1 when this > other, -1 when this < other
192202 */
193- public boolean isWorseForTheSameNode (Type decision ) {
194- return switch (decision ) {
195- case NO -> {
196- yield false ;
197- }
198- case NOT_PREFERRED -> {
199- yield (this == YES ) ? false /* this=YES is not worse than NOT_PREFERRED */ : true /* this=THROTTLE is worse */ ;
200- }
201- case THROTTLE -> {
202- yield (this == NO ) ? true : false /* all Types other than NO are better than THROTTLE */ ;
203- }
204- case YES -> {
205- yield true ;
206- }
207- };
203+ public int compareToBetweenDecisions (Type other ) {
204+ return Integer .compare (decisionComparisonOrdinal , other .decisionComparisonOrdinal );
208205 }
209206
210207 /**
@@ -314,7 +311,7 @@ public Type type() {
314311 Decision .Type worst = Type .YES ;
315312 for (Single decision : decisions ) {
316313 final var next = decision .type ();
317- if (next .isWorseForTheSameNode (worst )) {
314+ if (next .compareToBetweenDecisions (worst ) < 0 ) {
318315 worst = next ;
319316 }
320317 }
0 commit comments