func New(cc balancer.ClientConn, bOpts balancer.BuildOptions, stateAggregator BalancerStateAggregator, loadStore load.PerClusterReporter, logger *grpclog.PrefixLogger) *BalancerGroup {
	return &BalancerGroup{
		cc:        cc,
		buildOpts: bOpts,
		logger:    logger,
		loadStore: loadStore,
		stateAggregator: stateAggregator,
		idToBalancerConfig: make(map[string]*subBalancerWrapper),
		balancerCache:      cache.NewTimeoutCache(DefaultSubBalancerCloseTimeout),
		scToSubBalancer:    make(map[balancer.SubConn]*subBalancerWrapper),
	}
}
New creates a new BalancerGroup. Note that the BalancerGroup
needs to be started to work.

TODO(easwars): Pass an options struct instead of N args.
package balancergroup
import (
	"fmt"
	"sync"
	"time"
	orcapb "github.com/cncf/xds/go/xds/data/orca/v3"
	"google.golang.org/grpc/xds/internal/xdsclient/load"
	"google.golang.org/grpc/balancer"
	"google.golang.org/grpc/connectivity"
	"google.golang.org/grpc/internal/cache"
	"google.golang.org/grpc/internal/grpclog"
	"google.golang.org/grpc/resolver"
)
type subBalancerWrapper struct {
	balancer.ClientConn
	id    string
	group *BalancerGroup
	mu    sync.Mutex
	state balancer.State
	builder balancer.Builder
	buildOpts balancer.BuildOptions
	ccState *balancer.ClientConnState
	balancer balancer.Balancer
}
func (sbc *subBalancerWrapper) UpdateState(state balancer.State) {
	sbc.mu.Lock()
	sbc.state = state
	sbc.group.updateBalancerState(sbc.id, state)
	sbc.mu.Unlock()
}
func (sbc *subBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
	return sbc.group.newSubConn(sbc, addrs, opts)
}
func (sbc *subBalancerWrapper) updateBalancerStateWithCachedPicker() {
	sbc.mu.Lock()
	if sbc.state.Picker != nil {
		sbc.group.updateBalancerState(sbc.id, sbc.state)
	}
	sbc.mu.Unlock()
}
func (sbc *subBalancerWrapper) startBalancer() {
	b := sbc.builder.Build(sbc, sbc.buildOpts)
	sbc.group.logger.Infof("Created child policy %p of type %v", b, sbc.builder.Name())
	sbc.balancer = b
	if sbc.ccState != nil {
		b.UpdateClientConnState(*sbc.ccState)
	}
}
func (sbc *subBalancerWrapper) exitIdle() {
	b := sbc.balancer
	if b == nil {
		return
	}
	if ei, ok := b.(balancer.ExitIdler); ok {
		ei.ExitIdle()
		return
	}
	for sc, b := range sbc.group.scToSubBalancer {
		if b == sbc {
			sc.Connect()
		}
	}
}
func (sbc *subBalancerWrapper) updateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
	b := sbc.balancer
	if b == nil {
		return
	}
	b.UpdateSubConnState(sc, state)
}
func (sbc *subBalancerWrapper) updateClientConnState(s balancer.ClientConnState) error {
	sbc.ccState = &s
	b := sbc.balancer
	if b == nil {
		return nil
	}
	return b.UpdateClientConnState(s)
}
func (sbc *subBalancerWrapper) resolverError(err error) {
	b := sbc.balancer
	if b == nil {
		return
	}
	b.ResolverError(err)
}
func (sbc *subBalancerWrapper) stopBalancer() {
	sbc.balancer.Close()
	sbc.balancer = nil
}
type BalancerGroup struct {
	cc        balancer.ClientConn
	buildOpts balancer.BuildOptions
	logger    *grpclog.PrefixLogger
	loadStore load.PerClusterReporter  
	stateAggregator BalancerStateAggregator
	outgoingMu         sync.Mutex
	outgoingStarted    bool
	idToBalancerConfig map[string]*subBalancerWrapper
	balancerCache *cache.TimeoutCache
	incomingMu      sync.Mutex
	incomingStarted bool  
	scToSubBalancer map[balancer.SubConn]*subBalancerWrapper
}
var DefaultSubBalancerCloseTimeout = 15 * time.Minute