github.com/projecteru2/core@v0.0.0-20240321043226-06bcc1c23f58/strategy/drained.go (about)

     1  package strategy
     2  
     3  import (
     4  	"context"
     5  	"sort"
     6  
     7  	"github.com/projecteru2/core/types"
     8  
     9  	"github.com/cockroachdb/errors"
    10  )
    11  
    12  // DrainedPlan 优先往Capacity最小的节点部署,尽可能把节点的资源榨干在部署下一台.
    13  func DrainedPlan(_ context.Context, infos []Info, need, total, _ int) (map[string]int, error) {
    14  	if total < need {
    15  		return nil, errors.Wrapf(types.ErrInsufficientResource, "need: %d, available: %d", need, total)
    16  	}
    17  
    18  	deploy := map[string]int{}
    19  
    20  	infosCopy := make([]Info, len(infos))
    21  	copy(infosCopy, infos)
    22  	sort.Slice(infosCopy, func(i, j int) bool {
    23  		if infosCopy[i].Capacity < infosCopy[j].Capacity {
    24  			return true
    25  		}
    26  		return infosCopy[i].Usage > infosCopy[j].Usage
    27  	})
    28  
    29  	for idx := 0; idx < len(infosCopy); idx++ {
    30  		info := &infosCopy[idx]
    31  		if need < info.Capacity {
    32  			deploy[info.Nodename] = need
    33  			need = 0
    34  		} else {
    35  			deploy[info.Nodename] = info.Capacity
    36  			need -= info.Capacity
    37  		}
    38  		if need == 0 {
    39  			return deploy, nil
    40  		}
    41  	}
    42  	return nil, errors.Wrapf(types.ErrInsufficientResource, "BUG: never reach here")
    43  }