func (a *Affinity) String() string {
	kind := ""
	if a.Weight < 0 {
		kind = "anti-"
	}
	return fmt.Sprintf("<%saffinity: scope %s %s => %d>",
		kind, a.Scope.String(), a.Match.String(), a.Weight)
}
String returns the affinity as a string.
package cache
import (
	"fmt"
	"sigs.k8s.io/yaml"
	"github.com/intel/cri-resource-manager/pkg/apis/resmgr"
	"github.com/intel/cri-resource-manager/pkg/cri/resource-manager/kubernetes"
)
const (
	keyAffinity = "affinity"
	keyAntiAffinity = "anti-affinity"
)
type Expression struct {
	resmgr.Expression
}
type simpleAffinity map[string][]string
type podContainerAffinity map[string][]*Affinity
type Affinity struct {
	Scope  *resmgr.Expression `json:"scope,omitempty"`   
	Match  *resmgr.Expression `json:"match"`             
	Weight int32              `json:"weight,omitempty"`  
}
const (
	UserWeightCutoff = 1000
	DefaultWeight int32 = 1
)
type ImplicitAffinity struct {
	Eligible func(Container) bool  
	Affinity *Affinity             
}
func (a *Affinity) Validate() error {
	if err := a.Scope.Validate(); err != nil {
		return cacheError("invalid affinity scope: %v", err)
	}
	if err := a.Match.Validate(); err != nil {
		return cacheError("invalid affinity match: %v", err)
	}
	switch {
	case a.Weight > UserWeightCutoff:
		a.Weight = UserWeightCutoff
	case a.Weight < -UserWeightCutoff:
		a.Weight = -UserWeightCutoff
	}
	return nil
}
func (cch *cache) EvaluateAffinity(a *Affinity) map[string]int32 {
	results := make(map[string]int32)
	for _, c := range cch.FilterScope(a.Scope) {
		if a.Match.Evaluate(c) {
			id := c.GetCacheID()
			results[id] += a.Weight
		}
	}
	return results
}
func (cch *cache) FilterScope(scope *resmgr.Expression) []Container {
	cch.Debug("calculating scope %s", scope.String())
	result := []Container{}
	for _, c := range cch.GetContainers() {
		if scope.Evaluate(c) {
			cch.Debug("  + container %s: IN scope", c.PrettyName())
			result = append(result, c)
		} else {
			cch.Debug("  - container %s: NOT IN scope", c.PrettyName())
		}
	}
	return result
}