github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/manager/scheduler/decision_tree.go (about) 1 package scheduler 2 3 import ( 4 "container/heap" 5 ) 6 7 type decisionTree struct { 8 // Count of tasks for the service scheduled to this subtree 9 tasks int 10 11 // Non-leaf point to the next level of the tree. The key is the 12 // value that the subtree covers. 13 next map[string]*decisionTree 14 15 // Leaf nodes contain a list of nodes 16 nodeHeap nodeMaxHeap 17 } 18 19 // orderedNodes returns the nodes in this decision tree entry, sorted best 20 // (lowest) first according to the sorting function. Must be called on a leaf 21 // of the decision tree. 22 // 23 // The caller may modify the nodes in the returned slice. 24 func (dt *decisionTree) orderedNodes(meetsConstraints func(*NodeInfo) bool, nodeLess func(*NodeInfo, *NodeInfo) bool) []NodeInfo { 25 if dt.nodeHeap.length != len(dt.nodeHeap.nodes) { 26 // We already collapsed the heap into a sorted slice, so 27 // re-heapify. There may have been modifications to the nodes 28 // so we can't return dt.nodeHeap.nodes as-is. We also need to 29 // reevaluate constraints because of the possible modifications. 30 for i := 0; i < len(dt.nodeHeap.nodes); { 31 if meetsConstraints(&dt.nodeHeap.nodes[i]) { 32 i++ 33 } else { 34 last := len(dt.nodeHeap.nodes) - 1 35 dt.nodeHeap.nodes[i] = dt.nodeHeap.nodes[last] 36 dt.nodeHeap.nodes = dt.nodeHeap.nodes[:last] 37 } 38 } 39 dt.nodeHeap.length = len(dt.nodeHeap.nodes) 40 heap.Init(&dt.nodeHeap) 41 } 42 43 // Popping every element orders the nodes from best to worst. The 44 // first pop gets the worst node (since this a max-heap), and puts it 45 // at position n-1. Then the next pop puts the next-worst at n-2, and 46 // so on. 47 for dt.nodeHeap.Len() > 0 { 48 heap.Pop(&dt.nodeHeap) 49 } 50 51 return dt.nodeHeap.nodes 52 }