github.com/MetalBlockchain/metalgo@v1.11.9/utils/math/meter/continuous_meter.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package meter 5 6 import ( 7 "math" 8 "time" 9 ) 10 11 var ( 12 convertEToBase2 = math.Log(2) 13 14 _ Factory = (*ContinuousFactory)(nil) 15 _ Meter = (*continuousMeter)(nil) 16 ) 17 18 // ContinuousFactory implements the Factory interface by returning a continuous 19 // time meter. 20 type ContinuousFactory struct{} 21 22 func (ContinuousFactory) New(halflife time.Duration) Meter { 23 return NewMeter(halflife) 24 } 25 26 type continuousMeter struct { 27 halflife float64 28 value float64 29 30 numCoresRunning float64 31 lastUpdated time.Time 32 } 33 34 // NewMeter returns a new Meter with the provided halflife 35 func NewMeter(halflife time.Duration) Meter { 36 return &continuousMeter{ 37 halflife: float64(halflife) / convertEToBase2, 38 } 39 } 40 41 func (a *continuousMeter) Inc(now time.Time, numCores float64) { 42 a.Read(now) 43 a.numCoresRunning += numCores 44 } 45 46 func (a *continuousMeter) Dec(now time.Time, numCores float64) { 47 a.Read(now) 48 a.numCoresRunning -= numCores 49 } 50 51 func (a *continuousMeter) Read(now time.Time) float64 { 52 timeSincePreviousUpdate := a.lastUpdated.Sub(now) 53 if timeSincePreviousUpdate >= 0 { 54 return a.value 55 } 56 a.lastUpdated = now 57 58 factor := math.Exp(float64(timeSincePreviousUpdate) / a.halflife) 59 a.value *= factor 60 a.value += a.numCoresRunning * (1 - factor) 61 return a.value 62 } 63 64 func (a *continuousMeter) TimeUntil(now time.Time, value float64) time.Duration { 65 currentValue := a.Read(now) 66 if currentValue <= value { 67 return time.Duration(0) 68 } 69 // Note that [factor] >= 1 70 factor := currentValue / value 71 // Note that [numHalfLives] >= 0 72 numHalflives := math.Log(factor) 73 duration := numHalflives * a.halflife 74 // Overflow protection 75 if duration > math.MaxInt64 { 76 return time.Duration(math.MaxInt64) 77 } 78 return time.Duration(duration) 79 }