go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/common/sync/dispatcher/buffer/moving_average.go (about) 1 // Copyright 2019 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package buffer 16 17 import ( 18 "errors" 19 ) 20 21 // movingAverage tracks a moving average of integers. 22 // 23 // It is not goroutine-safe. 24 type movingAverage struct { 25 values []int // used as a circular buffer 26 curIdx int 27 curSum int64 28 } 29 30 // newMovingAverage makes a new movingAverage 31 // 32 // Args: 33 // 34 // window - The number of values to track.; if this is <= 0, panics. 35 // seed - A seed value. 36 func newMovingAverage(window, seed int) *movingAverage { 37 if window <= 0 { 38 panic(errors.New("window must be positive")) 39 } 40 41 values := make([]int, window) 42 curSum := int64(0) 43 for i := range values { 44 values[i] = seed 45 curSum += int64(seed) 46 } 47 48 return &movingAverage{values, 0, curSum} 49 } 50 51 // get retrieves the current average value. 52 func (m *movingAverage) get() float64 { 53 return float64(m.curSum) / float64(len(m.values)) 54 } 55 56 // adds a new value to track. 57 func (m *movingAverage) record(value int) { 58 m.curSum += int64(value) - int64(m.values[m.curIdx]) 59 m.values[m.curIdx] = value 60 m.curIdx = (m.curIdx + 1) % len(m.values) 61 }