23
23
import java .util .Collections ;
24
24
import java .util .List ;
25
25
import java .util .Locale ;
26
- import java .util .Objects ;
27
26
28
27
/**
29
- * This abstract class defining basic {@link Decision} used during shard
30
- * allocation process.
28
+ * A {@link Decision} used during shard allocation process.
31
29
*
32
30
* @see AllocationDecider
33
31
*/
34
- public abstract class Decision implements ToXContent , Writeable {
32
+ public sealed interface Decision extends ToXContent , Writeable permits Decision . Single , Decision . Multi {
35
33
36
- public static final Decision ALWAYS = new Single (Type .YES );
37
- public static final Decision YES = new Single (Type .YES );
38
- public static final Decision NO = new Single (Type .NO );
39
- public static final Decision THROTTLE = new Single (Type .THROTTLE );
34
+ Single ALWAYS = new Single (Type .YES );
35
+ Single YES = new Single (Type .YES );
36
+ Single NO = new Single (Type .NO );
37
+ Single THROTTLE = new Single (Type .THROTTLE );
40
38
41
39
/**
42
40
* Creates a simple decision
@@ -46,40 +44,69 @@ public abstract class Decision implements ToXContent, Writeable {
46
44
* @param explanationParams additional parameters for the decision
47
45
* @return new {@link Decision} instance
48
46
*/
49
- public static Decision single (Type type , @ Nullable String label , @ Nullable String explanation , @ Nullable Object ... explanationParams ) {
47
+ static Decision single (Type type , @ Nullable String label , @ Nullable String explanation , @ Nullable Object ... explanationParams ) {
50
48
return new Single (type , label , explanation , explanationParams );
51
49
}
52
50
53
- public static Decision readFrom (StreamInput in ) throws IOException {
51
+ static Decision readFrom (StreamInput in ) throws IOException {
54
52
// Determine whether to read a Single or Multi Decision
55
53
if (in .readBoolean ()) {
56
54
Multi result = new Multi ();
57
55
int decisionCount = in .readVInt ();
58
56
for (int i = 0 ; i < decisionCount ; i ++) {
59
- Decision s = readFrom (in );
60
- result .decisions .add (s );
57
+ var flag = in .readBoolean ();
58
+ assert flag == false : "nested multi decision is not permitted" ;
59
+ var single = readSingleFrom (in );
60
+ result .decisions .add (single );
61
61
}
62
62
return result ;
63
63
} else {
64
- final Type type = Type .readFrom (in );
65
- final String label = in .readOptionalString ();
66
- final String explanation = in .readOptionalString ();
67
- if (label == null && explanation == null ) {
68
- return switch (type ) {
69
- case YES -> YES ;
70
- case THROTTLE -> THROTTLE ;
71
- case NO -> NO ;
72
- };
73
- }
74
- return new Single (type , label , explanation );
64
+ return readSingleFrom (in );
65
+ }
66
+ }
67
+
68
+ private static Single readSingleFrom (StreamInput in ) throws IOException {
69
+ final Type type = Type .readFrom (in );
70
+ final String label = in .readOptionalString ();
71
+ final String explanation = in .readOptionalString ();
72
+ if (label == null && explanation == null ) {
73
+ return switch (type ) {
74
+ case YES -> YES ;
75
+ case THROTTLE -> THROTTLE ;
76
+ case NO -> NO ;
77
+ };
75
78
}
79
+ return new Single (type , label , explanation );
76
80
}
77
81
82
+ /**
83
+ * Get the {@link Type} of this decision
84
+ * @return {@link Type} of this decision
85
+ */
86
+ Type type ();
87
+
88
+ /**
89
+ * Get the description label for this decision.
90
+ */
91
+ @ Nullable
92
+ String label ();
93
+
94
+ /**
95
+ * Get the explanation for this decision.
96
+ */
97
+ @ Nullable
98
+ String getExplanation ();
99
+
100
+ /**
101
+ * Return the list of all decisions that make up this decision
102
+ */
103
+ List <Decision > getDecisions ();
104
+
78
105
/**
79
106
* This enumeration defines the
80
107
* possible types of decisions
81
108
*/
82
- public enum Type implements Writeable {
109
+ enum Type implements Writeable {
83
110
YES (1 ),
84
111
THROTTLE (2 ),
85
112
NO (0 );
@@ -110,45 +137,22 @@ public boolean higherThan(Type other) {
110
137
return false ;
111
138
} else if (other == NO ) {
112
139
return true ;
113
- } else if (other == THROTTLE && this == YES ) {
114
- return true ;
115
- }
116
- return false ;
140
+ } else return other == THROTTLE && this == YES ;
117
141
}
118
142
119
- }
120
-
121
- /**
122
- * Get the {@link Type} of this decision
123
- * @return {@link Type} of this decision
124
- */
125
- public abstract Type type ();
126
-
127
- /**
128
- * Get the description label for this decision.
129
- */
130
- @ Nullable
131
- public abstract String label ();
132
-
133
- /**
134
- * Get the explanation for this decision.
135
- */
136
- @ Nullable
137
- public abstract String getExplanation ();
143
+ /**
144
+ * @return lowest decision by precedence NO->THROTTLE->YES
145
+ */
146
+ public static Type min (Type a , Type b ) {
147
+ return a .higherThan (b ) ? b : a ;
148
+ }
138
149
139
- /**
140
- * Return the list of all decisions that make up this decision
141
- */
142
- public abstract List <Decision > getDecisions ();
150
+ }
143
151
144
152
/**
145
153
* Simple class representing a single decision
146
154
*/
147
- public static class Single extends Decision implements ToXContentObject {
148
- private final Type type ;
149
- private final String label ;
150
- private final String explanationString ;
151
-
155
+ record Single (Type type , String label , String explanationString ) implements Decision , ToXContentObject {
152
156
/**
153
157
* Creates a new {@link Single} decision of a given type
154
158
* @param type {@link Type} of the decision
@@ -165,24 +169,13 @@ private Single(Type type) {
165
169
* @param explanationParams A set of additional parameters
166
170
*/
167
171
public Single (Type type , @ Nullable String label , @ Nullable String explanation , @ Nullable Object ... explanationParams ) {
168
- this .type = type ;
169
- this .label = label ;
170
- if (explanationParams != null && explanationParams .length > 0 ) {
171
- this .explanationString = String .format (Locale .ROOT , explanation , explanationParams );
172
- } else {
173
- this .explanationString = explanation ;
174
- }
175
- }
176
-
177
- @ Override
178
- public Type type () {
179
- return this .type ;
180
- }
181
-
182
- @ Override
183
- @ Nullable
184
- public String label () {
185
- return this .label ;
172
+ this (
173
+ type ,
174
+ label ,
175
+ explanationParams != null && explanationParams .length > 0
176
+ ? String .format (Locale .ROOT , explanation , explanationParams )
177
+ : explanation
178
+ );
186
179
}
187
180
188
181
@ Override
@@ -199,29 +192,6 @@ public String getExplanation() {
199
192
return this .explanationString ;
200
193
}
201
194
202
- @ Override
203
- public boolean equals (Object object ) {
204
- if (this == object ) {
205
- return true ;
206
- }
207
-
208
- if (object == null || getClass () != object .getClass ()) {
209
- return false ;
210
- }
211
-
212
- Decision .Single s = (Decision .Single ) object ;
213
- return this .type == s .type && Objects .equals (label , s .label ) && Objects .equals (explanationString , s .explanationString );
214
- }
215
-
216
- @ Override
217
- public int hashCode () {
218
- int result = type .hashCode ();
219
- result = 31 * result + (label == null ? 0 : label .hashCode ());
220
- String explanationStr = explanationString ;
221
- result = 31 * result + (explanationStr == null ? 0 : explanationStr .hashCode ());
222
- return result ;
223
- }
224
-
225
195
@ Override
226
196
public String toString () {
227
197
if (explanationString != null ) {
@@ -254,17 +224,20 @@ public void writeTo(StreamOutput out) throws IOException {
254
224
/**
255
225
* Simple class representing a list of decisions
256
226
*/
257
- public static class Multi extends Decision implements ToXContentFragment {
227
+ record Multi ( List < Single > decisions ) implements Decision , ToXContentFragment {
258
228
259
- private final List <Decision > decisions = new ArrayList <>();
229
+ public Multi () {
230
+ this (new ArrayList <>());
231
+ }
260
232
261
233
/**
262
234
* Add a decision to this {@link Multi}decision instance
263
235
* @param decision {@link Decision} to add
264
236
* @return {@link Multi}decision instance with the given decision added
265
237
*/
266
238
public Multi add (Decision decision ) {
267
- decisions .add (decision );
239
+ assert decision instanceof Single ;
240
+ decisions .add ((Single ) decision );
268
241
return this ;
269
242
}
270
243
@@ -300,26 +273,6 @@ public List<Decision> getDecisions() {
300
273
return Collections .unmodifiableList (this .decisions );
301
274
}
302
275
303
- @ Override
304
- public boolean equals (final Object object ) {
305
- if (this == object ) {
306
- return true ;
307
- }
308
-
309
- if (object == null || getClass () != object .getClass ()) {
310
- return false ;
311
- }
312
-
313
- final Decision .Multi m = (Decision .Multi ) object ;
314
-
315
- return this .decisions .equals (m .decisions );
316
- }
317
-
318
- @ Override
319
- public int hashCode () {
320
- return 31 * decisions .hashCode ();
321
- }
322
-
323
276
@ Override
324
277
public String toString () {
325
278
StringBuilder sb = new StringBuilder ();
0 commit comments