snapshot of https://github.com/grpc/grpc-go.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
codecov / upload (push) Failing after 13m59s
CodeQL / Analyze (push) Failing after 1s
govulncheck / govulncheck (.) (push) Failing after 1s
govulncheck / govulncheck (./cmd/protoc-gen-go-grpc) (push) Failing after 1s
govulncheck / govulncheck (./gcp/observability) (push) Failing after 1s
govulncheck / govulncheck (./security/advancedtls) (push) Failing after 1s
govulncheck / govulncheck (./stats/opencensus) (push) Failing after 1s
Testing / tests (arm, latest) (push) Waiting to run
Testing / vet-proto (push) Failing after 1s
Testing / extras (latest) (push) Failing after 1s
Testing / static checks (latest-1) (push) Failing after 1s
Testing / tests (-race, latest) (push) Failing after 1s
Testing / tests (i386, latest) (push) Failing after 1s
Testing / tests (latest) (push) Failing after 1s
Testing / tests (latest-1) (push) Failing after 1s
Stale bot / stale (push) Failing after 1s
Lock Threads / lock (push) Failing after 1s
Some checks failed
codecov / upload (push) Failing after 13m59s
CodeQL / Analyze (push) Failing after 1s
govulncheck / govulncheck (.) (push) Failing after 1s
govulncheck / govulncheck (./cmd/protoc-gen-go-grpc) (push) Failing after 1s
govulncheck / govulncheck (./gcp/observability) (push) Failing after 1s
govulncheck / govulncheck (./security/advancedtls) (push) Failing after 1s
govulncheck / govulncheck (./stats/opencensus) (push) Failing after 1s
Testing / tests (arm, latest) (push) Waiting to run
Testing / vet-proto (push) Failing after 1s
Testing / extras (latest) (push) Failing after 1s
Testing / static checks (latest-1) (push) Failing after 1s
Testing / tests (-race, latest) (push) Failing after 1s
Testing / tests (i386, latest) (push) Failing after 1s
Testing / tests (latest) (push) Failing after 1s
Testing / tests (latest-1) (push) Failing after 1s
Stale bot / stale (push) Failing after 1s
Lock Threads / lock (push) Failing after 1s
This commit is contained in:
84
internal/wrr/random.go
Normal file
84
internal/wrr/random.go
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2019 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package wrr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
rand "math/rand/v2"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// weightedItem is a wrapped weighted item that is used to implement weighted random algorithm.
|
||||
type weightedItem struct {
|
||||
item any
|
||||
weight int64
|
||||
accumulatedWeight int64
|
||||
}
|
||||
|
||||
func (w *weightedItem) String() string {
|
||||
return fmt.Sprint(*w)
|
||||
}
|
||||
|
||||
// randomWRR is a struct that contains weighted items implement weighted random algorithm.
|
||||
type randomWRR struct {
|
||||
items []*weightedItem
|
||||
// Are all item's weights equal
|
||||
equalWeights bool
|
||||
}
|
||||
|
||||
// NewRandom creates a new WRR with random.
|
||||
func NewRandom() WRR {
|
||||
return &randomWRR{}
|
||||
}
|
||||
|
||||
var randInt64n = rand.Int64N
|
||||
|
||||
func (rw *randomWRR) Next() (item any) {
|
||||
if len(rw.items) == 0 {
|
||||
return nil
|
||||
}
|
||||
if rw.equalWeights {
|
||||
return rw.items[randInt64n(int64(len(rw.items)))].item
|
||||
}
|
||||
|
||||
sumOfWeights := rw.items[len(rw.items)-1].accumulatedWeight
|
||||
// Random number in [0, sumOfWeights).
|
||||
randomWeight := randInt64n(sumOfWeights)
|
||||
// Item's accumulated weights are in ascending order, because item's weight >= 0.
|
||||
// Binary search rw.items to find first item whose accumulatedWeight > randomWeight
|
||||
// The return i is guaranteed to be in range [0, len(rw.items)) because randomWeight < last item's accumulatedWeight
|
||||
i := sort.Search(len(rw.items), func(i int) bool { return rw.items[i].accumulatedWeight > randomWeight })
|
||||
return rw.items[i].item
|
||||
}
|
||||
|
||||
func (rw *randomWRR) Add(item any, weight int64) {
|
||||
accumulatedWeight := weight
|
||||
equalWeights := true
|
||||
if len(rw.items) > 0 {
|
||||
lastItem := rw.items[len(rw.items)-1]
|
||||
accumulatedWeight = lastItem.accumulatedWeight + weight
|
||||
equalWeights = rw.equalWeights && weight == lastItem.weight
|
||||
}
|
||||
rw.equalWeights = equalWeights
|
||||
rItem := &weightedItem{item: item, weight: weight, accumulatedWeight: accumulatedWeight}
|
||||
rw.items = append(rw.items, rItem)
|
||||
}
|
||||
|
||||
func (rw *randomWRR) String() string {
|
||||
return fmt.Sprint(rw.items)
|
||||
}
|
||||
Reference in New Issue
Block a user