@@ -89,15 +89,21 @@ type topologyPair struct {
89
89
}
90
90
type topologyToMatchedTermCount map [topologyPair ]int64
91
91
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
95
101
}
96
102
}
97
103
98
104
func (m topologyToMatchedTermCount ) clone () topologyToMatchedTermCount {
99
105
copy := make (topologyToMatchedTermCount , len (m ))
100
- copy .append (m )
106
+ copy .merge (m )
101
107
return copy
102
108
}
103
109
@@ -134,6 +140,48 @@ func (m topologyToMatchedTermCount) updateWithAntiAffinityTerms(terms []framewor
134
140
}
135
141
}
136
142
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
+
137
185
// returns true IFF the given pod matches all the given terms.
138
186
func podMatchesAllAffinityTerms (terms []framework.AffinityTerm , pod * v1.Pod ) bool {
139
187
if len (terms ) == 0 {
@@ -153,25 +201,26 @@ func podMatchesAllAffinityTerms(terms []framework.AffinityTerm, pod *v1.Pod) boo
153
201
// 1. Whether it has PodAntiAffinity
154
202
// 2. Whether any AntiAffinityTerm matches the incoming pod
155
203
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 ))
157
205
index := int32 (- 1 )
158
206
processNode := func (i int ) {
159
207
nodeInfo := nodes [i ]
160
208
node := nodeInfo .Node ()
161
209
162
- topoMap := make (topologyToMatchedTermCount )
210
+ antiAffinityCounts := make (topologyToMatchedTermCountList , 0 )
163
211
for _ , existingPod := range nodeInfo .PodsWithRequiredAntiAffinity {
164
- topoMap . updateWithAntiAffinityTerms (existingPod .RequiredAntiAffinityTerms , pod , nsLabels , node , 1 )
212
+ antiAffinityCounts . appendWithAntiAffinityTerms (existingPod .RequiredAntiAffinityTerms , pod , nsLabels , node , 1 )
165
213
}
166
- if len (topoMap ) != 0 {
167
- topoMaps [atomic .AddInt32 (& index , 1 )] = topoMap
214
+ if len (antiAffinityCounts ) != 0 {
215
+ antiAffinityCountsList [atomic .AddInt32 (& index , 1 )] = antiAffinityCounts
168
216
}
169
217
}
170
218
pl .parallelizer .Until (ctx , len (nodes ), processNode , pl .Name ())
171
219
172
220
result := make (topologyToMatchedTermCount )
221
+ // Traditional for loop is slightly faster in this case than its "for range" equivalent.
173
222
for i := 0 ; i <= int (index ); i ++ {
174
- result .append ( topoMaps [i ])
223
+ result .mergeWithList ( antiAffinityCountsList [i ])
175
224
}
176
225
177
226
return result
@@ -188,20 +237,20 @@ func (pl *InterPodAffinity) getIncomingAffinityAntiAffinityCounts(ctx context.Co
188
237
return affinityCounts , antiAffinityCounts
189
238
}
190
239
191
- affinityCountsList := make ([]topologyToMatchedTermCount , len (allNodes ))
192
- antiAffinityCountsList := make ([]topologyToMatchedTermCount , len (allNodes ))
240
+ affinityCountsList := make ([]topologyToMatchedTermCountList , len (allNodes ))
241
+ antiAffinityCountsList := make ([]topologyToMatchedTermCountList , len (allNodes ))
193
242
index := int32 (- 1 )
194
243
processNode := func (i int ) {
195
244
nodeInfo := allNodes [i ]
196
245
node := nodeInfo .Node ()
197
246
198
- affinity := make (topologyToMatchedTermCount )
199
- antiAffinity := make (topologyToMatchedTermCount )
247
+ affinity := make (topologyToMatchedTermCountList , 0 )
248
+ antiAffinity := make (topologyToMatchedTermCountList , 0 )
200
249
for _ , existingPod := range nodeInfo .Pods {
201
- affinity .updateWithAffinityTerms (podInfo .RequiredAffinityTerms , existingPod .Pod , node , 1 )
250
+ affinity .appendWithAffinityTerms (podInfo .RequiredAffinityTerms , existingPod .Pod , node , 1 )
202
251
// The incoming pod's terms have the namespaceSelector merged into the namespaces, and so
203
252
// 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 )
205
254
}
206
255
207
256
if len (affinity ) > 0 || len (antiAffinity ) > 0 {
@@ -213,8 +262,8 @@ func (pl *InterPodAffinity) getIncomingAffinityAntiAffinityCounts(ctx context.Co
213
262
pl .parallelizer .Until (ctx , len (allNodes ), processNode , pl .Name ())
214
263
215
264
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 ])
218
267
}
219
268
220
269
return affinityCounts , antiAffinityCounts
0 commit comments