@@ -474,20 +474,36 @@ 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 {
482496 if emptyVoterConstraintIndex != - 1 {
483- return errors .Errorf ("invalid configurations with empty voter constraint" )
497+ return errors .Errorf ("multiple empty voter constraints: %v and %v" ,
498+ conf .voterConstraints [emptyVoterConstraintIndex ], conf .voterConstraints [i ])
484499 }
485500 emptyVoterConstraintIndex = i
486501 }
487502 for j := range conf .constraints {
488503 if len (conf .constraints [j ].constraints ) == 0 {
489504 if emptyConstraintIndex != - 1 && emptyConstraintIndex != j {
490- return errors .Errorf ("invalid configurations with empty constraint" )
505+ return errors .Errorf ("multiple empty constraints: %v and %v" ,
506+ conf .constraints [emptyConstraintIndex ], conf .constraints [j ])
491507 }
492508 emptyConstraintIndex = j
493509 }
@@ -607,8 +623,12 @@ func doStructuralNormalization(conf *normalizedSpanConfig) error {
607623 // constraint will then be available for subsequent narrowing.
608624 if emptyVoterConstraintIndex >= 0 && emptyConstraintIndex >= 0 {
609625 neededReplicas := conf .voterConstraints [emptyVoterConstraintIndex ].numReplicas
626+ // While iterating over the previous relationships, we skipped over
627+ // emptyVoterConstraintIndex, so its corresponding
628+ // voterConstraints.numReplicas must be 0.
610629 if voterConstraints [emptyVoterConstraintIndex ].numReplicas != 0 {
611- panic ("programming error" )
630+ panic (errors .AssertionFailedf ("programming error: voterConstraints[%d].numReplicas should be 0, but is %d" ,
631+ emptyVoterConstraintIndex , voterConstraints [emptyVoterConstraintIndex ]))
612632 }
613633 remainingSatisfiable := allReplicaConstraints [emptyConstraintIndex ].remainingReplicas
614634 if neededReplicas > 0 && remainingSatisfiable > 0 {
0 commit comments