Skip to content

Commit 81bac07

Browse files
committed
remove nesting from multi allocation decision
1 parent 5e2f154 commit 81bac07

File tree

3 files changed

+77
-123
lines changed

3 files changed

+77
-123
lines changed

server/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/BalancedShardsAllocator.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,22 +1134,22 @@ private boolean tryRelocateShard(ModelNode minNode, ModelNode maxNode, ProjectIn
11341134
continue;
11351135
}
11361136

1137-
final Decision decision = new Decision.Multi().add(allocationDecision).add(rebalanceDecision);
1137+
final Decision.Type canAllocateOrRebalance = Decision.Type.min(allocationDecision.type(), rebalanceDecision.type());
11381138

11391139
maxNode.removeShard(projectIndex(shard), shard);
11401140
long shardSize = allocation.clusterInfo().getShardSize(shard, ShardRouting.UNAVAILABLE_EXPECTED_SHARD_SIZE);
11411141

1142-
assert decision.type() == Type.YES || decision.type() == Type.THROTTLE : decision.type();
1142+
assert canAllocateOrRebalance == Type.YES || canAllocateOrRebalance == Type.THROTTLE : canAllocateOrRebalance;
11431143
logger.debug(
11441144
"decision [{}]: relocate [{}] from [{}] to [{}]",
1145-
decision.type(),
1145+
canAllocateOrRebalance,
11461146
shard,
11471147
maxNode.getNodeId(),
11481148
minNode.getNodeId()
11491149
);
11501150
minNode.addShard(
11511151
projectIndex(shard),
1152-
decision.type() == Type.YES
1152+
canAllocateOrRebalance == Type.YES
11531153
/* only allocate on the cluster if we are not throttled */
11541154
? routingNodes.relocateShard(shard, minNode.getNodeId(), shardSize, "rebalance", allocation.changes()).v1()
11551155
: shard.relocate(minNode.getNodeId(), shardSize)

server/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/AllocationDeciders.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ private Decision withDeciders(
205205
BiFunction<String, Decision, String> logMessageCreator
206206
) {
207207
if (debugMode == RoutingAllocation.DebugMode.OFF) {
208-
var result = Decision.YES;
208+
Decision result = Decision.YES;
209209
for (AllocationDecider decider : deciders) {
210210
var decision = deciderAction.apply(decider);
211211
if (decision.type() == Decision.Type.NO) {

server/src/main/java/org/elasticsearch/cluster/routing/allocation/decider/Decision.java

Lines changed: 72 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,19 @@
2323
import java.util.Collections;
2424
import java.util.List;
2525
import java.util.Locale;
26-
import java.util.Objects;
2726

2827
/**
2928
* This abstract class defining basic {@link Decision} used during shard
3029
* allocation process.
3130
*
3231
* @see AllocationDecider
3332
*/
34-
public abstract class Decision implements ToXContent, Writeable {
33+
public sealed interface Decision extends ToXContent, Writeable permits Decision.Single, Decision.Multi {
3534

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);
35+
Single ALWAYS = new Single(Type.YES);
36+
Single YES = new Single(Type.YES);
37+
Single NO = new Single(Type.NO);
38+
Single THROTTLE = new Single(Type.THROTTLE);
4039

4140
/**
4241
* Creates a simple decision
@@ -46,40 +45,69 @@ public abstract class Decision implements ToXContent, Writeable {
4645
* @param explanationParams additional parameters for the decision
4746
* @return new {@link Decision} instance
4847
*/
49-
public static Decision single(Type type, @Nullable String label, @Nullable String explanation, @Nullable Object... explanationParams) {
48+
static Decision single(Type type, @Nullable String label, @Nullable String explanation, @Nullable Object... explanationParams) {
5049
return new Single(type, label, explanation, explanationParams);
5150
}
5251

53-
public static Decision readFrom(StreamInput in) throws IOException {
52+
static Decision readFrom(StreamInput in) throws IOException {
5453
// Determine whether to read a Single or Multi Decision
5554
if (in.readBoolean()) {
5655
Multi result = new Multi();
5756
int decisionCount = in.readVInt();
5857
for (int i = 0; i < decisionCount; i++) {
59-
Decision s = readFrom(in);
60-
result.decisions.add(s);
58+
var flag = in.readBoolean();
59+
assert flag == false : "nested multi decision is not permitted";
60+
var single = readSingleFrom(in);
61+
result.decisions.add(single);
6162
}
6263
return result;
6364
} 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);
65+
return readSingleFrom(in);
66+
}
67+
}
68+
69+
private static Single readSingleFrom(StreamInput in) throws IOException {
70+
final Type type = Type.readFrom(in);
71+
final String label = in.readOptionalString();
72+
final String explanation = in.readOptionalString();
73+
if (label == null && explanation == null) {
74+
return switch (type) {
75+
case YES -> YES;
76+
case THROTTLE -> THROTTLE;
77+
case NO -> NO;
78+
};
7579
}
80+
return new Single(type, label, explanation);
7681
}
7782

83+
/**
84+
* Get the {@link Type} of this decision
85+
* @return {@link Type} of this decision
86+
*/
87+
Type type();
88+
89+
/**
90+
* Get the description label for this decision.
91+
*/
92+
@Nullable
93+
String label();
94+
95+
/**
96+
* Get the explanation for this decision.
97+
*/
98+
@Nullable
99+
String getExplanation();
100+
101+
/**
102+
* Return the list of all decisions that make up this decision
103+
*/
104+
List<Decision> getDecisions();
105+
78106
/**
79107
* This enumeration defines the
80108
* possible types of decisions
81109
*/
82-
public enum Type implements Writeable {
110+
enum Type implements Writeable {
83111
YES(1),
84112
THROTTLE(2),
85113
NO(0);
@@ -110,45 +138,22 @@ public boolean higherThan(Type other) {
110138
return false;
111139
} else if (other == NO) {
112140
return true;
113-
} else if (other == THROTTLE && this == YES) {
114-
return true;
115-
}
116-
return false;
141+
} else return other == THROTTLE && this == YES;
117142
}
118143

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();
144+
/**
145+
* @return lowest decision by precedence NO->THROTTLE->YES
146+
*/
147+
public static Type min(Type a, Type b) {
148+
return a.higherThan(b) ? b : a;
149+
}
138150

139-
/**
140-
* Return the list of all decisions that make up this decision
141-
*/
142-
public abstract List<Decision> getDecisions();
151+
}
143152

144153
/**
145154
* Simple class representing a single decision
146155
*/
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-
156+
record Single(Type type, String label, String explanationString) implements Decision, ToXContentObject {
152157
/**
153158
* Creates a new {@link Single} decision of a given type
154159
* @param type {@link Type} of the decision
@@ -165,24 +170,13 @@ private Single(Type type) {
165170
* @param explanationParams A set of additional parameters
166171
*/
167172
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;
173+
this(
174+
type,
175+
label,
176+
explanationParams != null && explanationParams.length > 0
177+
? String.format(Locale.ROOT, explanation, explanationParams)
178+
: explanation
179+
);
186180
}
187181

188182
@Override
@@ -199,29 +193,6 @@ public String getExplanation() {
199193
return this.explanationString;
200194
}
201195

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-
225196
@Override
226197
public String toString() {
227198
if (explanationString != null) {
@@ -254,17 +225,20 @@ public void writeTo(StreamOutput out) throws IOException {
254225
/**
255226
* Simple class representing a list of decisions
256227
*/
257-
public static class Multi extends Decision implements ToXContentFragment {
228+
record Multi(List<Single> decisions) implements Decision, ToXContentFragment {
258229

259-
private final List<Decision> decisions = new ArrayList<>();
230+
public Multi() {
231+
this(new ArrayList<>());
232+
}
260233

261234
/**
262235
* Add a decision to this {@link Multi}decision instance
263236
* @param decision {@link Decision} to add
264237
* @return {@link Multi}decision instance with the given decision added
265238
*/
266239
public Multi add(Decision decision) {
267-
decisions.add(decision);
240+
assert decision instanceof Single;
241+
decisions.add((Single) decision);
268242
return this;
269243
}
270244

@@ -300,26 +274,6 @@ public List<Decision> getDecisions() {
300274
return Collections.unmodifiableList(this.decisions);
301275
}
302276

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-
323277
@Override
324278
public String toString() {
325279
StringBuilder sb = new StringBuilder();

0 commit comments

Comments
 (0)