func (p *policy) Introspect(state *introspect.State) {
	pools := make(map[string]*introspect.Pool, len(p.pools))
	for _, node := range p.nodes {
		cpus := node.GetSupply()
		pool := &introspect.Pool{
			Name:   node.Name(),
			CPUs:   cpus.SharableCPUs().Union(cpus.IsolatedCPUs()).String(),
			Memory: node.GetMemset(memoryAll).String(),
		}
		if parent := node.Parent(); !parent.IsNil() {
			pool.Parent = parent.Name()
		}
		if children := node.Children(); len(children) > 0 {
			pool.Children = make([]string, 0, len(children))
			for _, c := range children {
				pool.Children = append(pool.Children, c.Name())
			}
		}
		pools[pool.Name] = pool
	}
	state.Pools = pools
	assignments := make(map[string]*introspect.Assignment, len(p.allocations.grants))
	for _, g := range p.allocations.grants {
		a := &introspect.Assignment{
			ContainerID:   g.GetContainer().GetID(),
			CPUShare:      g.SharedPortion(),
			ExclusiveCPUs: g.ExclusiveCPUs().Union(g.IsolatedCPUs()).String(),
			Pool:          g.GetCPUNode().Name(),
		}
		if g.SharedPortion() > 0 || a.ExclusiveCPUs == "" {
			a.SharedCPUs = g.SharedCPUs().String()
		}
		assignments[a.ContainerID] = a
	}
	state.Assignments = assignments
}
Introspect provides data for external introspection.
package topologyaware
import (
	v1 "k8s.io/api/core/v1"
	resapi "k8s.io/apimachinery/pkg/api/resource"
	"k8s.io/kubernetes/pkg/kubelet/cm/cpuset"
	"github.com/hashicorp/go-multierror"
	"github.com/intel/cri-resource-manager/pkg/config"
	"github.com/intel/cri-resource-manager/pkg/cpuallocator"
	"github.com/intel/cri-resource-manager/pkg/cri/resource-manager/cache"
	"github.com/intel/cri-resource-manager/pkg/cri/resource-manager/events"
	"github.com/intel/cri-resource-manager/pkg/cri/resource-manager/introspect"
	policyapi "github.com/intel/cri-resource-manager/pkg/cri/resource-manager/policy"
	system "github.com/intel/cri-resource-manager/pkg/sysfs"
	idset "github.com/intel/goresctrl/pkg/utils"
)
const (
	PolicyName = "topology-aware"
	PolicyDescription = "A policy for prototyping memory tiering."
	PolicyPath = "policy." + PolicyName
	AliasName = "memtier"
	AliasPath = "policy." + AliasName
	ColdStartDone = "cold-start-done"
)
type allocations struct {
	policy *policy
	grants map[string]Grant
}
type policy struct {
	options      *policyapi.BackendOptions  
	cache        cache.Cache                
	sys          system.System              
	allowed      cpuset.CPUSet              
	reserved     cpuset.CPUSet              
	reserveCnt   int                        
	isolated     cpuset.CPUSet              
	nodes        map[string]Node            
	pools        []Node                     
	root         Node                       
	nodeCnt      int                        
	depth        int                        
	allocations  allocations                
	cpuAllocator cpuallocator.CPUAllocator  
	coldstartOff bool                       
	isAlias      bool                       
}
var _ policyapi.Backend = &policy{}
var coldStartOff bool
func CreateTopologyAwarePolicy(opts *policyapi.BackendOptions) policyapi.Backend {
	return createPolicy(opts, false)
}
func CreateMemtierPolicy(opts *policyapi.BackendOptions) policyapi.Backend {
	return createPolicy(opts, true)
}
func createPolicy(opts *policyapi.BackendOptions, isAlias bool) policyapi.Backend {
	p := &policy{
		cache:        opts.Cache,
		sys:          opts.System,
		options:      opts,
		cpuAllocator: cpuallocator.NewCPUAllocator(opts.System),
		isAlias:      isAlias,
	}
	if isAlias {
		*opt = *aliasOpt
	}
	if err := p.initialize(); err != nil {
		log.Fatal("failed to initialize %s policy: %v", PolicyName, err)
	}
	p.addImplicitAffinities()
	config.GetModule(policyapi.ConfigPath).AddNotify(p.configNotify)
	return p
}
func (p *policy) Name() string {
	return PolicyName
}
func (p *policy) Description() string {
	return PolicyDescription
}
func (p *policy) Start(add []cache.Container, del []cache.Container) error {
	if err := p.restoreCache(); err != nil {
		return policyError("failed to start: %v", err)
	}
	p.checkColdstartOff()
	p.root.Dump("<post-start>")
	return p.Sync(add, del)
}
func (p *policy) Sync(add []cache.Container, del []cache.Container) error {
	log.Debug("synchronizing state...")
	for _, c := range del {
		p.ReleaseResources(c)
	}
	for _, c := range add {
		p.AllocateResources(c)
	}
	return nil
}
func (p *policy) AllocateResources(container cache.Container) error {
	log.Debug("allocating resources for %s...", container.PrettyName())
	grant, err := p.allocatePool(container, "")
	if err != nil {
		return policyError("failed to allocate resources for %s: %v",
			container.PrettyName(), err)
	}
	p.applyGrant(grant)
	p.updateSharedAllocations(&grant)
	p.root.Dump("<post-alloc>")
	return nil
}
func (p *policy) ReleaseResources(container cache.Container) error {
	log.Debug("releasing resources of %s...", container.PrettyName())
	if grant, found := p.releasePool(container); found {
		p.updateSharedAllocations(&grant)
	}
	p.root.Dump("<post-release>")
	return nil
}
func (p *policy) UpdateResources(c cache.Container) error {
	log.Debug("(not) updating container %s...", c.PrettyName())
	return nil
}
func (p *policy) Rebalance() (bool, error) {
	var errors error
	containers := p.cache.GetContainers()
	movable := []cache.Container{}
	for _, c := range containers {
		if c.GetQOSClass() != v1.PodQOSGuaranteed {
			p.ReleaseResources(c)
			movable = append(movable, c)
		}
	}
	for _, c := range movable {
		if err := p.AllocateResources(c); err != nil {
			if errors == nil {
				errors = err
			} else {
				errors = policyError("%v, %v", errors, err)
			}
		}
	}
	return true, errors
}
func (p *policy) HandleEvent(e *events.Policy) (bool, error) {
	log.Debug("received policy event %s.%s with data %v...", e.Source, e.Type, e.Data)
	switch e.Type {
	case events.ContainerStarted:
		c, ok := e.Data.(cache.Container)
		if !ok {
			return false, policyError("%s event: expecting cache.Container Data, got %T",
				e.Type, e.Data)
		}
		log.Info("triggering coldstart period (if necessary) for %s", c.PrettyName())
		return false, p.triggerColdStart(c)
	case ColdStartDone:
		id, ok := e.Data.(string)
		if !ok {
			return false, policyError("%s event: expecting container ID Data, got %T",
				e.Type, e.Data)
		}
		c, ok := p.cache.LookupContainer(id)
		if !ok {
			return false, policyError("%s event: failed to lookup container %s", id)
		}
		log.Info("finishing coldstart period for %s", c.PrettyName())
		return p.finishColdStart(c)
	}
	return false, nil
}