Skip to content

Commit 0b789d7

Browse files
authored
Merge pull request kubernetes#129427 from macsko/improve_map_in_interpodaffinity_prefilter
Improve topologyToMatchedTermCount map in InterPodAffinity PreFilter
2 parents cace64a + 2d82687 commit 0b789d7

File tree

1 file changed

+67
-18
lines changed
  • pkg/scheduler/framework/plugins/interpodaffinity

1 file changed

+67
-18
lines changed

pkg/scheduler/framework/plugins/interpodaffinity/filtering.go

Lines changed: 67 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,21 @@ type topologyPair struct {
8989
}
9090
type topologyToMatchedTermCount map[topologyPair]int64
9191

92-
func (m topologyToMatchedTermCount) append(toAppend topologyToMatchedTermCount) {
93-
for pair := range toAppend {
94-
m[pair] += toAppend[pair]
92+
func (m topologyToMatchedTermCount) merge(toMerge topologyToMatchedTermCount) {
93+
for pair, count := range toMerge {
94+
m[pair] += count
95+
}
96+
}
97+
98+
func (m topologyToMatchedTermCount) mergeWithList(toMerge topologyToMatchedTermCountList) {
99+
for _, tmtc := range toMerge {
100+
m[tmtc.topologyPair] += tmtc.count
95101
}
96102
}
97103

98104
func (m topologyToMatchedTermCount) clone() topologyToMatchedTermCount {
99105
copy := make(topologyToMatchedTermCount, len(m))
100-
copy.append(m)
106+
copy.merge(m)
101107
return copy
102108
}
103109

@@ -134,6 +140,48 @@ func (m topologyToMatchedTermCount) updateWithAntiAffinityTerms(terms []framewor
134140
}
135141
}
136142

143+
// topologyToMatchedTermCountList is a slice equivalent of topologyToMatchedTermCount map.
144+
// The use of slice improves the performance of PreFilter,
145+
// especially due to faster iteration when merging than with topologyToMatchedTermCount.
146+
type topologyToMatchedTermCountList []topologyPairCount
147+
148+
type topologyPairCount struct {
149+
topologyPair topologyPair
150+
count int64
151+
}
152+
153+
func (m *topologyToMatchedTermCountList) append(node *v1.Node, tk string, value int64) {
154+
if tv, ok := node.Labels[tk]; ok {
155+
pair := topologyPair{key: tk, value: tv}
156+
*m = append(*m, topologyPairCount{
157+
topologyPair: pair,
158+
count: value,
159+
})
160+
}
161+
}
162+
163+
// appends the specified value to the topologyToMatchedTermCountList
164+
// for each affinity term if "targetPod" matches ALL terms.
165+
func (m *topologyToMatchedTermCountList) appendWithAffinityTerms(
166+
terms []framework.AffinityTerm, pod *v1.Pod, node *v1.Node, value int64) {
167+
if podMatchesAllAffinityTerms(terms, pod) {
168+
for _, t := range terms {
169+
m.append(node, t.TopologyKey, value)
170+
}
171+
}
172+
}
173+
174+
// appends the specified value to the topologyToMatchedTermCountList
175+
// for each anti-affinity term matched the target pod.
176+
func (m *topologyToMatchedTermCountList) appendWithAntiAffinityTerms(terms []framework.AffinityTerm, pod *v1.Pod, nsLabels labels.Set, node *v1.Node, value int64) {
177+
// Check anti-affinity terms.
178+
for _, t := range terms {
179+
if t.Matches(pod, nsLabels) {
180+
m.append(node, t.TopologyKey, value)
181+
}
182+
}
183+
}
184+
137185
// returns true IFF the given pod matches all the given terms.
138186
func podMatchesAllAffinityTerms(terms []framework.AffinityTerm, pod *v1.Pod) bool {
139187
if len(terms) == 0 {
@@ -153,25 +201,26 @@ func podMatchesAllAffinityTerms(terms []framework.AffinityTerm, pod *v1.Pod) boo
153201
// 1. Whether it has PodAntiAffinity
154202
// 2. Whether any AntiAffinityTerm matches the incoming pod
155203
func (pl *InterPodAffinity) getExistingAntiAffinityCounts(ctx context.Context, pod *v1.Pod, nsLabels labels.Set, nodes []*framework.NodeInfo) topologyToMatchedTermCount {
156-
topoMaps := make([]topologyToMatchedTermCount, len(nodes))
204+
antiAffinityCountsList := make([]topologyToMatchedTermCountList, len(nodes))
157205
index := int32(-1)
158206
processNode := func(i int) {
159207
nodeInfo := nodes[i]
160208
node := nodeInfo.Node()
161209

162-
topoMap := make(topologyToMatchedTermCount)
210+
antiAffinityCounts := make(topologyToMatchedTermCountList, 0)
163211
for _, existingPod := range nodeInfo.PodsWithRequiredAntiAffinity {
164-
topoMap.updateWithAntiAffinityTerms(existingPod.RequiredAntiAffinityTerms, pod, nsLabels, node, 1)
212+
antiAffinityCounts.appendWithAntiAffinityTerms(existingPod.RequiredAntiAffinityTerms, pod, nsLabels, node, 1)
165213
}
166-
if len(topoMap) != 0 {
167-
topoMaps[atomic.AddInt32(&index, 1)] = topoMap
214+
if len(antiAffinityCounts) != 0 {
215+
antiAffinityCountsList[atomic.AddInt32(&index, 1)] = antiAffinityCounts
168216
}
169217
}
170218
pl.parallelizer.Until(ctx, len(nodes), processNode, pl.Name())
171219

172220
result := make(topologyToMatchedTermCount)
221+
// Traditional for loop is slightly faster in this case than its "for range" equivalent.
173222
for i := 0; i <= int(index); i++ {
174-
result.append(topoMaps[i])
223+
result.mergeWithList(antiAffinityCountsList[i])
175224
}
176225

177226
return result
@@ -188,20 +237,20 @@ func (pl *InterPodAffinity) getIncomingAffinityAntiAffinityCounts(ctx context.Co
188237
return affinityCounts, antiAffinityCounts
189238
}
190239

191-
affinityCountsList := make([]topologyToMatchedTermCount, len(allNodes))
192-
antiAffinityCountsList := make([]topologyToMatchedTermCount, len(allNodes))
240+
affinityCountsList := make([]topologyToMatchedTermCountList, len(allNodes))
241+
antiAffinityCountsList := make([]topologyToMatchedTermCountList, len(allNodes))
193242
index := int32(-1)
194243
processNode := func(i int) {
195244
nodeInfo := allNodes[i]
196245
node := nodeInfo.Node()
197246

198-
affinity := make(topologyToMatchedTermCount)
199-
antiAffinity := make(topologyToMatchedTermCount)
247+
affinity := make(topologyToMatchedTermCountList, 0)
248+
antiAffinity := make(topologyToMatchedTermCountList, 0)
200249
for _, existingPod := range nodeInfo.Pods {
201-
affinity.updateWithAffinityTerms(podInfo.RequiredAffinityTerms, existingPod.Pod, node, 1)
250+
affinity.appendWithAffinityTerms(podInfo.RequiredAffinityTerms, existingPod.Pod, node, 1)
202251
// The incoming pod's terms have the namespaceSelector merged into the namespaces, and so
203252
// here we don't lookup the existing pod's namespace labels, hence passing nil for nsLabels.
204-
antiAffinity.updateWithAntiAffinityTerms(podInfo.RequiredAntiAffinityTerms, existingPod.Pod, nil, node, 1)
253+
antiAffinity.appendWithAntiAffinityTerms(podInfo.RequiredAntiAffinityTerms, existingPod.Pod, nil, node, 1)
205254
}
206255

207256
if len(affinity) > 0 || len(antiAffinity) > 0 {
@@ -213,8 +262,8 @@ func (pl *InterPodAffinity) getIncomingAffinityAntiAffinityCounts(ctx context.Co
213262
pl.parallelizer.Until(ctx, len(allNodes), processNode, pl.Name())
214263

215264
for i := 0; i <= int(index); i++ {
216-
affinityCounts.append(affinityCountsList[i])
217-
antiAffinityCounts.append(antiAffinityCountsList[i])
265+
affinityCounts.mergeWithList(affinityCountsList[i])
266+
antiAffinityCounts.mergeWithList(antiAffinityCountsList[i])
218267
}
219268

220269
return affinityCounts, antiAffinityCounts

0 commit comments

Comments
 (0)