This is an automated email from the ASF dual-hosted git repository.

manirajv06 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 42edf052 [YUNIKORN-3323] Replacing google btree with tidwall btree 
(#1117)
42edf052 is described below

commit 42edf052aa81bf71137179991721d1372f3704c0
Author: Aditya Maheshwari <[email protected]>
AuthorDate: Mon Aug 10 13:56:12 2026 +0530

    [YUNIKORN-3323] Replacing google btree with tidwall btree (#1117)
    
    Initiated tidwall btree with below options
    1. With degree as 7
    2. No locks
    
    Used Walk() method as it is performant than Scan()
    
    Closes: #1117
    
    Signed-off-by: mani <[email protected]>
---
 go.mod                                      |  2 +-
 go.sum                                      |  4 ++--
 pkg/scheduler/objects/application.go        |  7 +++++-
 pkg/scheduler/objects/node_collection.go    | 34 +++++++++++++----------------
 pkg/scheduler/objects/node_iterator.go      | 15 +++++++------
 pkg/scheduler/objects/node_iterator_test.go | 12 +++++-----
 pkg/scheduler/objects/utilities_test.go     |  8 +++----
 7 files changed, 42 insertions(+), 40 deletions(-)

diff --git a/go.mod b/go.mod
index 76556ee2..2d3ee6f5 100644
--- a/go.mod
+++ b/go.mod
@@ -24,7 +24,6 @@ go 1.25.0
 require (
        github.com/apache/yunikorn-scheduler-interface 
v0.0.0-20260727092410-674338955bdf
        github.com/go-ldap/ldap/v3 v3.4.13
-       github.com/google/btree v1.1.3
        github.com/google/go-cmp v0.7.0
        github.com/google/uuid v1.6.0
        github.com/julienschmidt/httprouter v1.3.0
@@ -33,6 +32,7 @@ require (
        github.com/prometheus/client_model v0.6.2
        github.com/prometheus/common v0.67.5
        github.com/sasha-s/go-deadlock v0.3.9
+       github.com/tidwall/btree v1.8.1
        go.uber.org/zap v1.27.1
        go.yaml.in/yaml/v3 v3.0.4
        golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90
diff --git a/go.sum b/go.sum
index 10e3c159..82d63445 100644
--- a/go.sum
+++ b/go.sum
@@ -20,8 +20,6 @@ github.com/go-logr/stdr v1.2.2 
h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
 github.com/go-logr/stdr v1.2.2/go.mod 
h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
 github.com/golang/protobuf v1.5.4 
h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
 github.com/golang/protobuf v1.5.4/go.mod 
h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
-github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
-github.com/google/btree v1.1.3/go.mod 
h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
 github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
 github.com/google/go-cmp v0.7.0/go.mod 
h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
@@ -72,6 +70,8 @@ github.com/sasha-s/go-deadlock v0.3.9 
h1:fiaT9rB7g5sr5ddNZvlwheclN9IP86eFW9WgqlE
 github.com/sasha-s/go-deadlock v0.3.9/go.mod 
h1:KuZj51ZFmx42q/mPaYbRk0P1xcwe697zsJKE03vD4/Y=
 github.com/stretchr/testify v1.11.1 
h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
 github.com/stretchr/testify v1.11.1/go.mod 
h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
+github.com/tidwall/btree v1.8.1 h1:27ehoXvm5AG/g+1VxLS1SD3vRhp/H7LuEfwNvddEdmA=
+github.com/tidwall/btree v1.8.1/go.mod 
h1:jBbTdUWhSZClZWoDg54VnvV7/54modSOzDN7VXftj1A=
 go.opentelemetry.io/auto/sdk v1.2.1 
h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
 go.opentelemetry.io/auto/sdk v1.2.1/go.mod 
h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
 go.opentelemetry.io/otel v1.43.0 
h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I=
diff --git a/pkg/scheduler/objects/application.go 
b/pkg/scheduler/objects/application.go
index a125e0ac..3d4d8130 100644
--- a/pkg/scheduler/objects/application.go
+++ b/pkg/scheduler/objects/application.go
@@ -2114,9 +2114,14 @@ func (sa *Application) RemoveAllAllocations() 
[]*Allocation {
        sa.allocatedResource = resources.NewResource()
        sa.allocatedPlaceholder = resources.NewResource()
        sa.allocations = make(map[string]*Allocation)
+
        // When the resource trackers are zero we should not expect anything to 
come in later.
        if resources.IsZero(sa.pending) {
-               if err := sa.HandleApplicationEvent(CompleteApplication); err 
!= nil {
+               event := CompleteApplication
+               if sa.IsFailing() {
+                       event = FailApplication
+               }
+               if err := sa.HandleApplicationEvent(event); err != nil {
                        log.Log(log.SchedApplication).Warn("Application state 
not changed to Completing while removing all allocations",
                                zap.String("currentState", sa.CurrentState()),
                                zap.Error(err))
diff --git a/pkg/scheduler/objects/node_collection.go 
b/pkg/scheduler/objects/node_collection.go
index cea1b2a6..90dfa464 100644
--- a/pkg/scheduler/objects/node_collection.go
+++ b/pkg/scheduler/objects/node_collection.go
@@ -21,7 +21,7 @@ package objects
 import (
        "fmt"
 
-       "github.com/google/btree"
+       "github.com/tidwall/btree"
        "go.uber.org/zap"
 
        "github.com/apache/yunikorn-core/pkg/locking"
@@ -56,27 +56,23 @@ type nodeRef struct {
        nodeScore float64 // node score
 }
 
-func (nr nodeRef) Less(than btree.Item) bool {
-       other, ok := than.(nodeRef)
-       if !ok {
-               return false
-       }
-       if nr.nodeScore < other.nodeScore {
+func nodeRefLess(a, b nodeRef) bool {
+       if a.nodeScore < b.nodeScore {
                return true
        }
-       if other.nodeScore < nr.nodeScore {
+       if b.nodeScore < a.nodeScore {
                return false
        }
-       return nr.node.NodeID < other.node.NodeID
+       return a.node.NodeID < b.node.NodeID
 }
 
 type baseNodeCollection struct {
        Partition string // partition used with this collection
 
        // Private fields need protection
-       nsp         NodeSortingPolicy   // node sorting policy
-       nodes       map[string]*nodeRef // nodes assigned to this collection
-       sortedNodes *btree.BTree        // nodes sorted by score
+       nsp         NodeSortingPolicy      // node sorting policy
+       nodes       map[string]*nodeRef    // nodes assigned to this collection
+       sortedNodes *btree.BTreeG[nodeRef] // nodes sorted by score
 
        unreservedIterator *treeIterator
        fullIterator       *treeIterator
@@ -109,7 +105,7 @@ func (nc *baseNodeCollection) AddNode(node *Node) error {
                nodeScore: nc.scoreNode(node),
        }
        nc.nodes[node.NodeID] = &nref
-       nc.sortedNodes.ReplaceOrInsert(nref)
+       nc.sortedNodes.Set(nref)
        return nil
 }
 
@@ -174,11 +170,11 @@ func (nc *baseNodeCollection) GetFullNodeIterator() 
NodeIterator {
        return nc.fullIterator
 }
 
-func (nc *baseNodeCollection) cloneSortedNodes() *btree.BTree {
+func (nc *baseNodeCollection) cloneSortedNodes() *btree.BTreeG[nodeRef] {
        nc.Lock()
        defer nc.Unlock()
 
-       return nc.sortedNodes.Clone()
+       return nc.sortedNodes.Copy()
 }
 
 // Sets the node sorting policy.
@@ -188,11 +184,11 @@ func (nc *baseNodeCollection) SetNodeSortingPolicy(policy 
NodeSortingPolicy) {
        nc.nsp = policy
 
        // sortedNodes must be rebuilt since sort ordering is different
-       nc.sortedNodes.Clear(false)
+       nc.sortedNodes.Clear()
        for _, nref := range nc.nodes {
                node := nref.node
                nref.nodeScore = nc.scoreNode(node)
-               nc.sortedNodes.ReplaceOrInsert(*nref)
+               nc.sortedNodes.Set(*nref)
        }
 }
 
@@ -217,7 +213,7 @@ func (nc *baseNodeCollection) NodeUpdated(node *Node) {
        if nref.nodeScore != updatedScore {
                nc.sortedNodes.Delete(*nref)
                nref.nodeScore = nc.scoreNode(node)
-               nc.sortedNodes.ReplaceOrInsert(*nref)
+               nc.sortedNodes.Set(*nref)
        }
 }
 
@@ -227,7 +223,7 @@ func NewNodeCollection(partition string) NodeCollection {
                Partition:   partition,
                nsp:         
NewNodeSortingPolicy(policies.FairSortPolicy.String(), nil),
                nodes:       make(map[string]*nodeRef),
-               sortedNodes: btree.New(7), // Degree=7 here is experimentally 
the most efficient for up to around 5k nodes
+               sortedNodes: btree.NewBTreeGOptions(nodeRefLess, 
btree.Options{Degree: 7, NoLocks: true}), // Degree=7 here is experimentally 
the most efficient for up to around 5k nodes
        }
 
        unreservedIterator := NewTreeIterator(acceptUnreserved, 
bsc.cloneSortedNodes)
diff --git a/pkg/scheduler/objects/node_iterator.go 
b/pkg/scheduler/objects/node_iterator.go
index 1bb7b361..9e7f321c 100644
--- a/pkg/scheduler/objects/node_iterator.go
+++ b/pkg/scheduler/objects/node_iterator.go
@@ -19,7 +19,7 @@
 package objects
 
 import (
-       "github.com/google/btree"
+       "github.com/tidwall/btree"
 )
 
 // NodeIterator iterates over a list of nodes based on the defined policy
@@ -30,25 +30,26 @@ type NodeIterator interface {
 
 type treeIterator struct {
        accept  func(*Node) bool
-       getTree func() *btree.BTree
+       getTree func() *btree.BTreeG[nodeRef]
 }
 
 // ForEachNode Calls the provided "f" function on the sorted Node object until 
it returns false.
 // The accept() function checks if the node should be a candidate or not.
 func (ti *treeIterator) ForEachNode(f func(*Node) bool) {
-       ti.getTree().Ascend(func(item btree.Item) bool {
-               if ref, ok := item.(nodeRef); ok {
+       ti.getTree().Walk(func(refs []nodeRef) bool {
+               for _, ref := range refs {
                        node := ref.node
                        if ti.accept(node) {
-                               return f(node)
+                               if !f(node) {
+                                       return false
+                               }
                        }
                }
-
                return true
        })
 }
 
-func NewTreeIterator(accept func(*Node) bool, getTree func() *btree.BTree) 
*treeIterator {
+func NewTreeIterator(accept func(*Node) bool, getTree func() 
*btree.BTreeG[nodeRef]) *treeIterator {
        ti := &treeIterator{
                getTree: getTree,
                accept:  accept,
diff --git a/pkg/scheduler/objects/node_iterator_test.go 
b/pkg/scheduler/objects/node_iterator_test.go
index 56594c6d..b983b52b 100644
--- a/pkg/scheduler/objects/node_iterator_test.go
+++ b/pkg/scheduler/objects/node_iterator_test.go
@@ -22,7 +22,7 @@ import (
        "strconv"
        "testing"
 
-       "github.com/google/btree"
+       "github.com/tidwall/btree"
        "gotest.tools/v3/assert"
 
        "github.com/apache/yunikorn-core/pkg/common/resources"
@@ -30,7 +30,7 @@ import (
 
 func TestTreeIterator_AcceptAll(t *testing.T) {
        tree := getTree()
-       treeItr := NewTreeIterator(acceptAll, func() *btree.BTree {
+       treeItr := NewTreeIterator(acceptAll, func() *btree.BTreeG[nodeRef] {
                return tree
        })
 
@@ -45,7 +45,7 @@ func TestTreeIterator_AcceptAll(t *testing.T) {
 
 func TestTreeIterator_AcceptUnreserved(t *testing.T) {
        tree := getTree()
-       treeItr := NewTreeIterator(acceptUnreserved, func() *btree.BTree {
+       treeItr := NewTreeIterator(acceptUnreserved, func() 
*btree.BTreeG[nodeRef] {
                return tree
        })
 
@@ -65,14 +65,14 @@ func TestTreeIterator_AcceptUnreserved(t *testing.T) {
        }
 }
 
-func getTree() *btree.BTree {
+func getTree() *btree.BTreeG[nodeRef] {
        nodesReserved := newSchedNodeList(0, 5, true)
        nodes := newSchedNodeList(5, 10, false)
        nodes = append(nodes, nodesReserved...)
 
-       tree := btree.New(7)
+       tree := btree.NewBTreeG(nodeRefLess)
        for _, n := range nodes {
-               tree.ReplaceOrInsert(nodeRef{
+               tree.Set(nodeRef{
                        node:      n,
                        nodeScore: 1,
                })
diff --git a/pkg/scheduler/objects/utilities_test.go 
b/pkg/scheduler/objects/utilities_test.go
index 255f6bc5..7c2cee80 100644
--- a/pkg/scheduler/objects/utilities_test.go
+++ b/pkg/scheduler/objects/utilities_test.go
@@ -23,7 +23,7 @@ import (
        "testing"
        "time"
 
-       "github.com/google/btree"
+       "github.com/tidwall/btree"
        "gotest.tools/v3/assert"
 
        "github.com/apache/yunikorn-core/pkg/common/configs"
@@ -331,15 +331,15 @@ func assertAllocationLog(t *testing.T, ask *Allocation, 
message []string) {
 }
 
 func getNodeIteratorFn(nodes ...*Node) func() NodeIterator {
-       tree := btree.New(7)
+       tree := btree.NewBTreeG(nodeRefLess)
        for _, node := range nodes {
-               tree.ReplaceOrInsert(nodeRef{
+               tree.Set(nodeRef{
                        node, 1,
                })
        }
 
        return func() NodeIterator {
-               return NewTreeIterator(acceptAll, func() *btree.BTree {
+               return NewTreeIterator(acceptAll, func() *btree.BTreeG[nodeRef] 
{
                        return tree
                })
        }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to