Skip to content

Commit f748f00

Browse files
erikgrinakerkvoli
authored andcommitted
constraint: tighten inputs to CheckConjunction
Previously, `ConjunctionsCheck` took a store descriptor as an input. However, it only needed to know the store/node attributes and locality. Some upcoming callers (lease acquisition) can't easily construct a full store descriptor since the locking order would cause deadlocks. This patch changes it to only take the attributes and locality instead of the entire store descriptor, and renames it to `CheckConjunction()`. It also adds `CheckStoreConjunction()` as a convenience method that takes a store descriptor, and migrates all existing callers. Epic: none Release note: None
1 parent 9d976cb commit f748f00

File tree

7 files changed

+36
-25
lines changed

7 files changed

+36
-25
lines changed

pkg/kv/kvserver/allocator/allocatorimpl/allocator.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2827,7 +2827,7 @@ func (a Allocator) PreferredLeaseholders(
28272827
if !ok {
28282828
continue
28292829
}
2830-
if constraint.ConjunctionsCheck(storeDesc, preference.Constraints) {
2830+
if constraint.CheckStoreConjunction(storeDesc, preference.Constraints) {
28312831
preferred = append(preferred, repl)
28322832
}
28332833
}

pkg/kv/kvserver/allocator/allocatorimpl/allocator_scorer.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2010,7 +2010,7 @@ func allocateConstraintsCheck(
20102010
}
20112011

20122012
for i, constraints := range analyzed.Constraints {
2013-
if constraintsOK := constraint.ConjunctionsCheck(
2013+
if constraintsOK := constraint.CheckStoreConjunction(
20142014
store, constraints.Constraints,
20152015
); constraintsOK {
20162016
valid = true
@@ -2050,9 +2050,7 @@ func replaceConstraintsCheck(
20502050
for i, constraints := range analyzed.Constraints {
20512051
matchingStores := analyzed.SatisfiedBy[i]
20522052
satisfiedByExistingStore := containsStore(matchingStores, existingStore.StoreID)
2053-
satisfiedByCandidateStore := constraint.ConjunctionsCheck(
2054-
store, constraints.Constraints,
2055-
)
2053+
satisfiedByCandidateStore := constraint.CheckStoreConjunction(store, constraints.Constraints)
20562054
if satisfiedByCandidateStore {
20572055
valid = true
20582056
}
@@ -2147,7 +2145,7 @@ func rebalanceFromConstraintsCheck(
21472145
// satisfied by existing replicas or that is only fully satisfied because of
21482146
// fromStoreID, then it's necessary.
21492147
for i, constraints := range analyzed.Constraints {
2150-
if constraintsOK := constraint.ConjunctionsCheck(
2148+
if constraintsOK := constraint.CheckStoreConjunction(
21512149
store, constraints.Constraints,
21522150
); constraintsOK {
21532151
valid = true

pkg/kv/kvserver/allocator/base.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func IsStoreValid(
7676
return true
7777
}
7878
for _, subConstraints := range constraints {
79-
if constraintsOK := constraint.ConjunctionsCheck(
79+
if constraintsOK := constraint.CheckStoreConjunction(
8080
store, subConstraints.Constraints,
8181
); constraintsOK {
8282
return true

pkg/kv/kvserver/asim/queue/allocator_replica.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ func (sr *SimulatorReplica) LeaseViolatesPreferences(context.Context) bool {
9696
return false
9797
}
9898
for _, preference := range conf.LeasePreferences {
99-
if constraint.ConjunctionsCheck(storeDesc, preference.Constraints) {
99+
if constraint.CheckStoreConjunction(storeDesc, preference.Constraints) {
100100
return false
101101
}
102102
}

pkg/kv/kvserver/constraint/analyzer.go

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func AnalyzeConstraints(
6868
// is a much more stable failure state than frantically moving everything
6969
// off such a node.
7070
store, ok := storeResolver.GetStoreDescriptor(repl.StoreID)
71-
if !ok || ConjunctionsCheck(store, subConstraints.Constraints) {
71+
if !ok || CheckStoreConjunction(store, subConstraints.Constraints) {
7272
result.SatisfiedBy[i] = append(result.SatisfiedBy[i], store.StoreID)
7373
result.Satisfies[store.StoreID] = append(result.Satisfies[store.StoreID], i)
7474
}
@@ -80,18 +80,31 @@ func AnalyzeConstraints(
8080
return result
8181
}
8282

83-
// ConjunctionsCheck checks a store against a single set of constraints (out of
84-
// the possibly numerous sets that apply to a range), returning true iff the
85-
// store matches the constraints. The constraints are AND'ed together; a store
86-
// matches the conjunction if it matches all of them.
87-
func ConjunctionsCheck(store roachpb.StoreDescriptor, constraints []roachpb.Constraint) bool {
83+
// CheckConjunction checks the given attributes and locality tags against all
84+
// the given constraints. Every constraint must be satisfied by any
85+
// attribute/tier, i.e. they are ANDed together.
86+
func CheckConjunction(
87+
storeAttrs, nodeAttrs roachpb.Attributes,
88+
nodeLocality roachpb.Locality,
89+
constraints []roachpb.Constraint,
90+
) bool {
8891
for _, constraint := range constraints {
89-
// StoreMatchesConstraint returns whether a store matches the given constraint.
90-
hasConstraint := roachpb.StoreMatchesConstraint(store, constraint)
91-
if (constraint.Type == roachpb.Constraint_REQUIRED && !hasConstraint) ||
92-
(constraint.Type == roachpb.Constraint_PROHIBITED && hasConstraint) {
92+
matchesConstraint := roachpb.MatchesConstraint(storeAttrs, nodeAttrs, nodeLocality, constraint)
93+
if (constraint.Type == roachpb.Constraint_REQUIRED && !matchesConstraint) ||
94+
(constraint.Type == roachpb.Constraint_PROHIBITED && matchesConstraint) {
9395
return false
9496
}
9597
}
9698
return true
9799
}
100+
101+
// CheckStoreConjunction checks a store against a single set of constraints (out of
102+
// the possibly numerous sets that apply to a range), returning true iff the
103+
// store matches the constraints. The constraints are AND'ed together; a store
104+
// matches the conjunction if it matches all of them.
105+
func CheckStoreConjunction(
106+
storeDesc roachpb.StoreDescriptor, constraints []roachpb.Constraint,
107+
) bool {
108+
return CheckConjunction(
109+
storeDesc.Attrs, storeDesc.Node.Attrs, storeDesc.Node.Locality, constraints)
110+
}

pkg/kv/kvserver/replica_range_lease.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1551,7 +1551,7 @@ func (r *Replica) LeaseViolatesPreferences(ctx context.Context) bool {
15511551
return false
15521552
}
15531553
for _, preference := range conf.LeasePreferences {
1554-
if constraint.ConjunctionsCheck(*storeDesc, preference.Constraints) {
1554+
if constraint.CheckStoreConjunction(*storeDesc, preference.Constraints) {
15551555
return false
15561556
}
15571557
}

pkg/roachpb/span_config.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ import (
1818
"github.com/cockroachdb/errors"
1919
)
2020

21-
// StoreMatchesConstraint returns whether a store's attributes or node's
22-
// locality match the constraint's spec. It notably ignores whether the
23-
// constraint is required, prohibited, positive, or otherwise.
24-
func StoreMatchesConstraint(store StoreDescriptor, c Constraint) bool {
21+
// MatchesConstraint return whether the given attributes and locality tags match
22+
// the constraint's spec. It ignores whether the constraint is required,
23+
// prohibited, positive, or otherwise.
24+
func MatchesConstraint(storeAttrs, nodeAttrs Attributes, nodeLocality Locality, c Constraint) bool {
2525
if c.Key == "" {
26-
for _, attrs := range []Attributes{store.Attrs, store.Node.Attrs} {
26+
for _, attrs := range []Attributes{storeAttrs, nodeAttrs} {
2727
for _, attr := range attrs.Attrs {
2828
if attr == c.Value {
2929
return true
@@ -32,7 +32,7 @@ func StoreMatchesConstraint(store StoreDescriptor, c Constraint) bool {
3232
}
3333
return false
3434
}
35-
for _, tier := range store.Node.Locality.Tiers {
35+
for _, tier := range nodeLocality.Tiers {
3636
if c.Key == tier.Key && c.Value == tier.Value {
3737
return true
3838
}

0 commit comments

Comments
 (0)