This is an automated email from the ASF dual-hosted git repository.
mani pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/yunikorn-core.git
The following commit(s) were added to refs/heads/master by this push:
new 8c38ff77 [YUNIKORN-3232] Prune queue snapshots in
findEligiblePreemptionVictims (#1071)
8c38ff77 is described below
commit 8c38ff77a299c3e377c0e4a5433f1e85f9cf25d4
Author: Victor Zhou <[email protected]>
AuthorDate: Wed Mar 18 14:35:08 2026 +0530
[YUNIKORN-3232] Prune queue snapshots in findEligiblePreemptionVictims
(#1071)
Closes: #1071
Signed-off-by: mani <[email protected]>
---
pkg/scheduler/objects/queue.go | 37 +++++++++++++++++++++++++++++++++++++
pkg/scheduler/objects/queue_test.go | 5 ++++-
2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/pkg/scheduler/objects/queue.go b/pkg/scheduler/objects/queue.go
index 43f15e6d..db7a1f18 100644
--- a/pkg/scheduler/objects/queue.go
+++ b/pkg/scheduler/objects/queue.go
@@ -2029,6 +2029,10 @@ func (sq *Queue) FindEligiblePreemptionVictims(queuePath
string, ask *Allocation
// walk the subtree contained within the preemption fence and collect
potential victims organized by nodeID
fence.findEligiblePreemptionVictims(results, queuePath, ask,
priorityMap, queuePriority, false)
+ // prune snapshots that cannot contribute victims:
+ // - leaf snapshots with no victims
+ // - non-leaf snapshots not on ask path or any victim path
+ prunePreemptionSnapshots(results, queuePath)
return results
}
@@ -2080,6 +2084,8 @@ func (sq *Queue) findEligiblePreemptionVictims(results
map[string]*QueuePreempti
// skip this queue if we are within guaranteed limits
remaining :=
results[sq.QueuePath].GetRemainingGuaranteedResource()
if remaining != nil &&
resources.StrictlyGreaterThanOrEquals(remaining, resources.Zero) {
+ // this queue cannot contribute victims; remove the
just-created leaf snapshot
+ delete(results, sq.QueuePath)
return
}
@@ -2147,6 +2153,37 @@ func (sq *Queue) findEligiblePreemptionVictims(results
map[string]*QueuePreempti
}
}
+func prunePreemptionSnapshots(results map[string]*QueuePreemptionSnapshot,
askQueuePath string) {
+ if len(results) == 0 {
+ return
+ }
+
+ keep := make(map[string]struct{}, len(results))
+ // Always keep ask queue path and its ancestor chain.
+ if askSnapshot, ok := results[askQueuePath]; ok {
+ for current := askSnapshot; current != nil; current =
current.Parent {
+ keep[current.QueuePath] = struct{}{}
+ }
+ }
+
+ // Keep all leaf snapshots with victims and their ancestor chain.
+ for _, snapshot := range results {
+ if !snapshot.Leaf || len(snapshot.PotentialVictims) == 0 {
+ continue
+ }
+ for current := snapshot; current != nil; current =
current.Parent {
+ keep[current.QueuePath] = struct{}{}
+ }
+ }
+
+ // Remove all snapshots that are not on keep paths.
+ for queuePath := range results {
+ if _, ok := keep[queuePath]; !ok {
+ delete(results, queuePath)
+ }
+ }
+}
+
func (sq *Queue) findPreemptionFenceRoot(priorityMap map[string]int64,
currentPriority int64) *Queue {
if sq == nil {
return nil
diff --git a/pkg/scheduler/objects/queue_test.go
b/pkg/scheduler/objects/queue_test.go
index 7e48c500..d78d6334 100644
--- a/pkg/scheduler/objects/queue_test.go
+++ b/pkg/scheduler/objects/queue_test.go
@@ -1991,7 +1991,7 @@ func TestFindEligiblePreemptionVictims(t *testing.T) {
// verify no victims when no allocations exist
snapshot := leaf1.FindEligiblePreemptionVictims(leaf1.QueuePath, ask)
- assert.Equal(t, 5, len(snapshot), "wrong snapshot count") // root,
root.parent1, root.parent1.leaf1, root.parent2, root.parent2.leaf2
+ assert.Equal(t, 3, len(snapshot), "wrong snapshot count") // root,
root.parent1, root.parent1.leaf1
assert.Equal(t, 0, len(victims(snapshot)), "found victims")
// add two lower-priority allocs in leaf2
@@ -2028,6 +2028,7 @@ func TestFindEligiblePreemptionVictims(t *testing.T) {
parent1.preemptionPolicy = policies.FencePreemptionPolicy
assert.Equal(t, leaf1.findPreemptionFenceRoot(make(map[string]int64),
int64(ask.priority)).QueuePath, "root.parent1")
snapshot = leaf1.FindEligiblePreemptionVictims(leaf1.QueuePath, ask)
+ assert.Equal(t, 3, len(snapshot), "wrong snapshot count")
assert.Equal(t, 0, len(victims(snapshot)), "found victims")
parent1.preemptionPolicy = policies.DefaultPreemptionPolicy
@@ -2035,6 +2036,7 @@ func TestFindEligiblePreemptionVictims(t *testing.T) {
leaf1.preemptionPolicy = policies.FencePreemptionPolicy
assert.Equal(t, leaf1.findPreemptionFenceRoot(make(map[string]int64),
int64(ask.priority)).QueuePath, "root.parent1.leaf1")
snapshot = leaf1.FindEligiblePreemptionVictims(leaf1.QueuePath, ask)
+ assert.Equal(t, 3, len(snapshot), "wrong snapshot count")
assert.Equal(t, 0, len(victims(snapshot)), "found victims")
leaf1.preemptionPolicy = policies.DefaultPreemptionPolicy
@@ -2062,6 +2064,7 @@ func TestFindEligiblePreemptionVictims(t *testing.T) {
assert.Equal(t, leaf1.preemptionPolicy,
policies.DefaultPreemptionPolicy)
assert.Equal(t, leaf1.findPreemptionFenceRoot(make(map[string]int64),
int64(ask.priority)).QueuePath, parent1.QueuePath)
snapshot = leaf1.FindEligiblePreemptionVictims(leaf1.QueuePath, ask)
+ assert.Equal(t, 3, len(snapshot), "wrong snapshot count")
assert.Equal(t, 0, len(victims(snapshot)), "wrong victim count")
parent1.allocatedResource = used
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]