in pkg/scheduler/preemption/preemption.go [160:201]
func minimalPreemptions(wl *workload.Info, assignment flavorassigner.Assignment, snapshot *cache.Snapshot, resPerFlv resourcesPerFlavor, candidates []*workload.Info, allowBorrowing bool) []*workload.Info {
wlReq := totalRequestsForAssignment(wl, assignment)
cq := snapshot.ClusterQueues[wl.ClusterQueue]
// Simulate removing all candidates from the ClusterQueue and cohort.
var targets []*workload.Info
fits := false
for _, candWl := range candidates {
candCQ := snapshot.ClusterQueues[candWl.ClusterQueue]
if cq != candCQ && !cqIsBorrowing(candCQ, resPerFlv) {
continue
}
snapshot.RemoveWorkload(candWl)
targets = append(targets, candWl)
if workloadFits(wlReq, cq, allowBorrowing) {
fits = true
break
}
}
if !fits {
// Reset changes to the snapshot.
for _, t := range targets {
snapshot.AddWorkload(t)
}
return nil
}
// In the reverse order, check if any of the workloads can be added back.
for i := len(targets) - 2; i >= 0; i-- {
snapshot.AddWorkload(targets[i])
if workloadFits(wlReq, cq, allowBorrowing) {
// O(1) deletion: copy the last element into index i and reduce size.
targets[i] = targets[len(targets)-1]
targets = targets[:len(targets)-1]
} else {
snapshot.RemoveWorkload(targets[i])
}
}
// Reset changes to the snapshot.
for _, t := range targets {
snapshot.AddWorkload(t)
}
return targets
}