func NewWeightedBalancer() Loadbalancer {
	lb := &weightedBalancer{}
	return lb
}
NewWeightedBalancer creates a loadbalancer using weighted-round-robin algorithm.
package loadbalance
import (
	"context"
	"sync"
	"github.com/bytedance/gopkg/lang/fastrand"
	"golang.org/x/sync/singleflight"
	"github.com/cloudwego/kitex/pkg/discovery"
	"github.com/cloudwego/kitex/pkg/klog"
)
var weightedPickerPool, randomPickerPool sync.Pool
func init() {
	weightedPickerPool.New = newWeightedPicker
	randomPickerPool.New = newRandomPicker
}
type entry = int
type weightedPicker struct {
	immutableInstances []discovery.Instance
	immutableEntries   []entry
	weightSum          int
	copiedInstances []discovery.Instance
	copiedEntries   []entry
	firstIndex      int
}
func newWeightedPicker() interface{} {
	return &weightedPicker{
		firstIndex: -1,
	}
}
func (wp *weightedPicker) Next(ctx context.Context, request interface{}) (ins discovery.Instance) {
	if wp.firstIndex < 0 {
		weight := fastrand.Intn(wp.weightSum)
		for i := 0; i < len(wp.immutableEntries); i++ {
			weight -= wp.immutableEntries[i]
			if weight < 0 {
				wp.firstIndex = i
				break
			}
		}
		return wp.immutableInstances[wp.firstIndex]
	}
	if wp.copiedInstances == nil {
		wp.copiedInstances = make([]discovery.Instance, len(wp.immutableInstances)-1)
		copy(wp.copiedInstances, wp.immutableInstances[:wp.firstIndex])
		copy(wp.copiedInstances[wp.firstIndex:], wp.immutableInstances[wp.firstIndex+1:])
		wp.copiedEntries = make([]entry, len(wp.immutableEntries)-1)
		copy(wp.copiedEntries, wp.immutableEntries[:wp.firstIndex])
		copy(wp.copiedEntries[wp.firstIndex:], wp.immutableEntries[wp.firstIndex+1:])
		wp.weightSum -= wp.immutableEntries[wp.firstIndex]
	}
	n := len(wp.copiedInstances)
	if n > 0 {
		weight := fastrand.Intn(wp.weightSum)
		for i := 0; i < len(wp.copiedEntries); i++ {
			weight -= wp.copiedEntries[i]
			if weight < 0 {
				wp.weightSum -= wp.copiedEntries[i]
				ins := wp.copiedInstances[i]
				wp.copiedInstances[i] = wp.copiedInstances[n-1]
				wp.copiedInstances = wp.copiedInstances[:n-1]
				wp.copiedEntries[i] = wp.copiedEntries[n-1]
				wp.copiedEntries = wp.copiedEntries[:n-1]
				return ins
			}
		}
	}
	return nil
}
func (wp *weightedPicker) zero() {
	wp.immutableInstances = nil
	wp.immutableEntries = nil
	wp.weightSum = 0
	wp.copiedInstances = nil
	wp.copiedEntries = nil
	wp.firstIndex = -1
}
func (wp *weightedPicker) Recycle() {
	wp.zero()
	weightedPickerPool.Put(wp)
}
type randomPicker struct {
	immutableInstances []discovery.Instance
	firstIndex         int
	copiedInstances    []discovery.Instance
}
func newRandomPicker() interface{} {
	return &randomPicker{
		firstIndex: -1,
	}
}
func (rp *randomPicker) Next(ctx context.Context, request interface{}) (ins discovery.Instance) {
	if rp.firstIndex < 0 {
		rp.firstIndex = fastrand.Intn(len(rp.immutableInstances))
		return rp.immutableInstances[rp.firstIndex]
	}
	if rp.copiedInstances == nil {
		rp.copiedInstances = make([]discovery.Instance, len(rp.immutableInstances)-1)
		copy(rp.copiedInstances, rp.immutableInstances[:rp.firstIndex])
		copy(rp.copiedInstances[rp.firstIndex:], rp.immutableInstances[rp.firstIndex+1:])
	}
	n := len(rp.copiedInstances)
	if n > 0 {
		index := fastrand.Intn(n)
		ins := rp.copiedInstances[index]
		rp.copiedInstances[index] = rp.copiedInstances[n-1]
		rp.copiedInstances = rp.copiedInstances[:n-1]
		return ins
	}
	return nil
}
func (rp *randomPicker) zero() {
	rp.copiedInstances = nil
	rp.immutableInstances = nil
	rp.firstIndex = -1
}
func (rp *randomPicker) Recycle() {
	rp.zero()
	randomPickerPool.Put(rp)
}
type weightInfo struct {
	balance   bool
	instances []discovery.Instance
	entries   []entry
	weightSum int
}
type weightedBalancer struct {
	cachedWeightInfo sync.Map
	sfg              singleflight.Group
}