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]

Reply via email to