github.com/gocrane/crane@v0.11.0/pkg/recommendation/recommender/resource/resource_spec.go (about)

     1  package resource
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"sort"
     7  	"strconv"
     8  	"strings"
     9  
    10  	"k8s.io/apimachinery/pkg/api/resource"
    11  )
    12  
    13  const DefaultSpecs = "0.25c0.25g,0.25c0.5g,0.25c1g,0.5c0.5g,0.5c1g,1c1g,1c2g,1c4g,1c8g,2c2g,2c4g,2c8g,2c16g,4c4g,4c8g,4c16g,4c32g,8c8g,8c16g,8c32g,8c64g,16c32g,16c64g,16c128g,32c64g,32c128g,32c256g,64c128g,64c256g"
    14  
    15  type Specification struct {
    16  	CPU    float64
    17  	Memory float64
    18  }
    19  
    20  func GetResourceSpecifications(s string) ([]Specification, error) {
    21  	var resourceSpecs []Specification
    22  	arr := strings.Split(s, ",")
    23  	for i := 0; i < len(arr); i++ {
    24  		var arrResource []string
    25  		reg := regexp.MustCompile(`[0-9.]+`)
    26  		if reg != nil {
    27  			arrResource = reg.FindAllString(arr[i], -1)
    28  		}
    29  
    30  		if len(arrResource) != 2 {
    31  			return nil, fmt.Errorf("specification %s format error", arr[i])
    32  		}
    33  
    34  		cpu, err := strconv.ParseFloat(arrResource[0], 64)
    35  		if err != nil {
    36  			return nil, fmt.Errorf("specification %s cpu format error", arr[i])
    37  		}
    38  
    39  		memory, err := strconv.ParseFloat(arrResource[1], 64)
    40  		if err != nil {
    41  			return nil, fmt.Errorf("specification %s memory format error", arr[i])
    42  		}
    43  
    44  		resourceSpec := Specification{
    45  			CPU:    cpu,
    46  			Memory: memory,
    47  		}
    48  		resourceSpecs = append(resourceSpecs, resourceSpec)
    49  	}
    50  
    51  	sort.Slice(resourceSpecs, func(i, j int) bool {
    52  		if resourceSpecs[i].CPU > resourceSpecs[j].CPU {
    53  			return false
    54  		} else if resourceSpecs[i].CPU < resourceSpecs[j].CPU {
    55  			return true
    56  		} else {
    57  			return resourceSpecs[i].Memory < resourceSpecs[j].Memory
    58  		}
    59  	})
    60  
    61  	return resourceSpecs, nil
    62  }
    63  
    64  func GetNormalizedResource(cpu, mem *resource.Quantity, specs []Specification) (resource.Quantity, resource.Quantity) {
    65  	var cpuCores float64
    66  	var memInGBi float64
    67  
    68  	for i := 0; i < len(specs); i++ {
    69  		if cpuCores > 0 {
    70  			break
    71  		}
    72  
    73  		if specs[i].CPU >= float64(cpu.MilliValue())/1000 {
    74  			for j := i; j < len(specs); j++ {
    75  				if specs[i].CPU != specs[j].CPU {
    76  					break
    77  				}
    78  				if specs[j].Memory >= float64(mem.Value())/(1024.*1024.*1024.) {
    79  					cpuCores = specs[j].CPU
    80  					memInGBi = specs[j].Memory
    81  					break
    82  				}
    83  			}
    84  		}
    85  	}
    86  
    87  	return resource.MustParse(fmt.Sprintf("%.2f", cpuCores)), resource.MustParse(fmt.Sprintf("%.2fGi", memInGBi))
    88  }