Skip to content

Commit 34eb62b

Browse files
craig[bot]wenyihu6
andcommitted
Merge #158333
158333: mmaprototype: small clean up doStructuralNormalization r=wenyihu6 a=wenyihu6 Epic: CRDB-55052 Release note: none --- **mmaprototype: add assertion on emptyVoterConstraintIndex** This commit adds assertions on emptyVoterConstraintIndex and emptyConstraintIndex since there should only be one. --- **mmaprototype: clean up doStructuralNormalization** This commit refactors some code in doStructuralNormalization to use min utility and also adds assertions on programming errors. --- **mmaprototype: use >= 0 for emptyVoterConstraintIndex** This commit fixes >= 0 when checking for whether there were valid emptyVoterConstraintIndex and emptyConstraintIndex since 0 is a valid index. Co-authored-by: wenyihu6 <[email protected]>
2 parents 35973fd + f549149 commit 34eb62b

File tree

2 files changed

+52
-40
lines changed

2 files changed

+52
-40
lines changed

pkg/kv/kvserver/allocator/mmaprototype/constraint.go

Lines changed: 52 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -474,15 +474,37 @@ func doStructuralNormalization(conf *normalizedSpanConfig) error {
474474
allIndex int
475475
voterAndAllRel conjunctionRelationship
476476
}
477+
// emptyConstraintIndex corresponds to the index of the empty constraint in
478+
// conf.constraints. We expect only one empty constraint.
479+
// Example:
480+
// constraints: []: 2, [+region=a]: 2 => emptyConstraintIndex = 0
481+
//
482+
// TODO(wenyihu6): we should not allow user to specify empty constraints;
483+
// there should only be one created by us during normalizeConstraints.
484+
// Instead, we can also combine empty constraints into a single one in
485+
// normalizeConstraints.
477486
emptyConstraintIndex := -1
487+
// emptyVoterConstraintIndex corresponds to the index of the empty voter
488+
// constraint in conf.voterConstraints. We expect only one empty voter
489+
// constraint.
490+
// Example:
491+
// voterConstraints: [+region=a]: 2, []: 2 => emptyVoterConstraintIndex = 1
478492
emptyVoterConstraintIndex := -1
479493
var rels []relationshipVoterAndAll
480494
for i := range conf.voterConstraints {
481495
if len(conf.voterConstraints[i].constraints) == 0 {
496+
if emptyVoterConstraintIndex != -1 {
497+
return errors.Errorf("multiple empty voter constraints: %v and %v",
498+
conf.voterConstraints[emptyVoterConstraintIndex], conf.voterConstraints[i])
499+
}
482500
emptyVoterConstraintIndex = i
483501
}
484502
for j := range conf.constraints {
485503
if len(conf.constraints[j].constraints) == 0 {
504+
if emptyConstraintIndex != -1 && emptyConstraintIndex != j {
505+
return errors.Errorf("multiple empty constraints: %v and %v",
506+
conf.constraints[emptyConstraintIndex], conf.constraints[j])
507+
}
486508
emptyConstraintIndex = j
487509
}
488510
rels = append(rels, relationshipVoterAndAll{
@@ -577,10 +599,7 @@ func doStructuralNormalization(conf *normalizedSpanConfig) error {
577599
voterConstraints[rel.voterIndex].numReplicas
578600
if neededVoterReplicas > 0 && remainingAll > 0 {
579601
// We can satisfy some voter replicas.
580-
toAdd := remainingAll
581-
if toAdd > neededVoterReplicas {
582-
toAdd = neededVoterReplicas
583-
}
602+
toAdd := min(remainingAll, neededVoterReplicas)
584603
voterConstraints[rel.voterIndex].numReplicas += toAdd
585604
allReplicaConstraints[rel.allIndex].remainingReplicas -= toAdd
586605
}
@@ -602,20 +621,20 @@ func doStructuralNormalization(conf *normalizedSpanConfig) error {
602621
// has some remainingReplicas, we take them here to satisfy the empty voter
603622
// constraint as much as possible. Only what is remaining in the empty voter
604623
// constraint will then be available for subsequent narrowing.
605-
if emptyVoterConstraintIndex > 0 && emptyConstraintIndex > 0 {
624+
if emptyVoterConstraintIndex >= 0 && emptyConstraintIndex >= 0 {
606625
neededReplicas := conf.voterConstraints[emptyVoterConstraintIndex].numReplicas
607-
actualReplicas := voterConstraints[emptyVoterConstraintIndex].numReplicas
608-
remaining := neededReplicas - actualReplicas
609-
if remaining > 0 {
610-
remainingSatisfiable := allReplicaConstraints[emptyConstraintIndex].remainingReplicas
611-
if remainingSatisfiable > 0 {
612-
count := remainingSatisfiable
613-
if count > remaining {
614-
count = remaining
615-
}
616-
voterConstraints[emptyVoterConstraintIndex].numReplicas += count
617-
allReplicaConstraints[emptyConstraintIndex].remainingReplicas -= count
618-
}
626+
// While iterating over the previous relationships, we skipped over
627+
// emptyVoterConstraintIndex, so its corresponding
628+
// voterConstraints.numReplicas must be 0.
629+
if voterConstraints[emptyVoterConstraintIndex].numReplicas != 0 {
630+
panic(errors.AssertionFailedf("programming error: voterConstraints[%d].numReplicas should be 0, but is %d",
631+
emptyVoterConstraintIndex, voterConstraints[emptyVoterConstraintIndex]))
632+
}
633+
remainingSatisfiable := allReplicaConstraints[emptyConstraintIndex].remainingReplicas
634+
if neededReplicas > 0 && remainingSatisfiable > 0 {
635+
count := min(remainingSatisfiable, neededReplicas)
636+
voterConstraints[emptyVoterConstraintIndex].numReplicas += count
637+
allReplicaConstraints[emptyConstraintIndex].remainingReplicas -= count
619638
}
620639
}
621640

@@ -761,19 +780,17 @@ func doStructuralNormalization(conf *normalizedSpanConfig) error {
761780
// rel.voterIndex must be emptyVoterConstraintIndex.
762781
continue
763782
}
764-
if conf.constraints[rel.allIndex].numReplicas < conf.voterConstraints[rel.voterIndex].numReplicas {
765-
toAddCount := conf.voterConstraints[rel.voterIndex].numReplicas -
766-
conf.constraints[rel.allIndex].numReplicas
767-
availableCount := conf.constraints[emptyConstraintIndex].numReplicas
768-
if availableCount < toAddCount {
769-
// TODO(wenyihu6): this should also create an error, since we will
770-
// end up with two identical constraint conjunctions in replica
771-
// constraints and voter constraints, with the former having a lower
772-
// count than the latter.
773-
toAddCount = availableCount
774-
}
775-
conf.constraints[emptyConstraintIndex].numReplicas -= toAddCount
776-
conf.constraints[rel.allIndex].numReplicas += toAddCount
783+
toAddCount := conf.voterConstraints[rel.voterIndex].numReplicas -
784+
conf.constraints[rel.allIndex].numReplicas
785+
availableCount := conf.constraints[emptyConstraintIndex].numReplicas
786+
if toAddCount > 0 && availableCount > 0 {
787+
// TODO(wenyihu6): this should also create an error, since we will
788+
// end up with two identical constraint conjunctions in replica
789+
// constraints and voter constraints, with the former having a lower
790+
// count than the latter.
791+
add := min(toAddCount, availableCount)
792+
conf.constraints[emptyConstraintIndex].numReplicas -= add
793+
conf.constraints[rel.allIndex].numReplicas += add
777794
}
778795
}
779796
// For conjStrictSubset, if the subset relationship is with
@@ -790,14 +807,12 @@ func doStructuralNormalization(conf *normalizedSpanConfig) error {
790807
continue
791808
}
792809
availableCount := conf.constraints[emptyConstraintIndex].numReplicas
793-
if availableCount > 0 {
794-
toAddCount := conf.voterConstraints[rel.voterIndex].numReplicas
795-
if toAddCount > availableCount {
796-
toAddCount = availableCount
797-
}
798-
conf.constraints[emptyConstraintIndex].numReplicas -= toAddCount
810+
toAddCount := conf.voterConstraints[rel.voterIndex].numReplicas
811+
if availableCount > 0 && toAddCount > 0 {
812+
add := min(availableCount, toAddCount)
813+
conf.constraints[emptyConstraintIndex].numReplicas -= add
799814
conf.constraints = append(conf.constraints, internedConstraintsConjunction{
800-
numReplicas: toAddCount,
815+
numReplicas: add,
801816
constraints: conf.voterConstraints[rel.voterIndex].constraints,
802817
})
803818
}

pkg/kv/kvserver/allocator/mmaprototype/testdata/normalize_config

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -609,8 +609,6 @@ output:
609609

610610
# Replicas are not constrained. The voter constraints are promoted to replica
611611
# constraints.
612-
#
613-
# TODO(sumeer): investigate why the normalization also threw an error.
614612
normalize num-replicas=5 num-voters=3
615613
constraint num-replicas=5
616614
voter-constraint num-replicas=1 +region=a +zone=a1
@@ -623,7 +621,6 @@ input:
623621
voter-constraints:
624622
+region=a,+zone=a1:1
625623
+region=a,+zone=a2:1
626-
err=could not satisfy all voter constraints due to non-intersecting conjunctions in voter and all replica constraints
627624
output:
628625
num-replicas=5 num-voters=3
629626
constraints:

0 commit comments

Comments
 (0)