Codebase list golang-github-vbauerster-mpb / bc85b17
EwmaDecorator, AverageDecorator interface Vladimir Bauer 6 years ago
4 changed file(s) with 39 addition(s) and 25 deletion(s). Raw diff Collapse all Expand all
8484 }
8585
8686 // EwmaDecorator interface.
87 // EWMA based decorators must to implement this one.
87 // EWMA based decorators should implement this one.
8888 type EwmaDecorator interface {
89 IterationUpdate(int64, time.Duration)
89 EwmaUpdate(int64, time.Duration)
9090 }
9191
9292 // AverageDecorator interface.
9393 // Average decorators should implement this interface to provide start
9494 // time adjustment facility, for resume-able tasks.
9595 type AverageDecorator interface {
96 Adjust(time.Time)
96 AverageAdjust(time.Time)
9797 }
9898
9999 // ShutdownListener interface.
2626 // work duration as second argument, in order for this decorator to
2727 // work correctly. This decorator is a wrapper of MovingAverageETA.
2828 func EwmaETA(style TimeStyle, age float64, wcc ...WC) Decorator {
29 var average MovingAverage
29 var average ewma.MovingAverage
3030 if age == 0 {
3131 average = ewma.NewMovingAverage()
3232 } else {
3333 average = ewma.NewMovingAverage(age)
3434 }
35 average = &ThreadSafeMovingAverage{MovingAverage: average}
3536 return MovingAverageETA(style, average, nil, wcc...)
3637 }
3738
4546 //
4647 // `wcc` optional WC config
4748 //
48 func MovingAverageETA(style TimeStyle, average MovingAverage, normalizer TimeNormalizer, wcc ...WC) Decorator {
49 func MovingAverageETA(style TimeStyle, average ewma.MovingAverage, normalizer TimeNormalizer, wcc ...WC) Decorator {
4950 d := &movingAverageETA{
5051 WC: initWC(wcc...),
5152 average: average,
7172 return d.FormatMsg(d.producer(remaining))
7273 }
7374
74 func (d *movingAverageETA) NextAmount(n int64, wdd ...time.Duration) {
75 var workDuration time.Duration
76 for _, wd := range wdd {
77 workDuration = wd
78 }
79 durPerItem := float64(workDuration) / float64(n)
75 func (d *movingAverageETA) EwmaUpdate(n int64, dur time.Duration) {
76 durPerItem := float64(dur) / float64(n)
8077 if math.IsInf(durPerItem, 0) || math.IsNaN(durPerItem) {
8178 return
8279 }
11
22 import (
33 "sort"
4 "sync"
45
56 "github.com/VividCortex/ewma"
67 )
78
8 // MovingAverage is the interface that computes a moving average over
9 // a time-series stream of numbers. The average may be over a window
10 // or exponentially decaying.
11 type MovingAverage = ewma.MovingAverage
9 // ThreadSafeMovingAverage is a thread safe wrapper for ewma.MovingAverage.
10 type ThreadSafeMovingAverage struct {
11 ewma.MovingAverage
12 mu sync.Mutex
13 }
14
15 func (s *ThreadSafeMovingAverage) Add(value float64) {
16 s.mu.Lock()
17 s.MovingAverage.Add(value)
18 s.mu.Unlock()
19 }
20
21 func (s *ThreadSafeMovingAverage) Value() float64 {
22 s.mu.Lock()
23 defer s.mu.Unlock()
24 return s.MovingAverage.Value()
25 }
26
27 func (s *ThreadSafeMovingAverage) Set(value float64) {
28 s.mu.Lock()
29 s.MovingAverage.Set(value)
30 s.mu.Unlock()
31 }
1232
1333 type medianWindow [3]float64
1434
3454 }
3555
3656 // NewMedian is fixed last 3 samples median MovingAverage.
37 func NewMedian() MovingAverage {
38 return new(medianWindow)
57 func NewMedian() ewma.MovingAverage {
58 return &ThreadSafeMovingAverage{MovingAverage: new(medianWindow)}
3959 }
3131 // work duration as second argument, in order for this decorator to
3232 // work correctly. This decorator is a wrapper of MovingAverageSpeed.
3333 func EwmaSpeed(unit int, format string, age float64, wcc ...WC) Decorator {
34 var average MovingAverage
34 var average ewma.MovingAverage
3535 if age == 0 {
3636 average = ewma.NewMovingAverage()
3737 } else {
3838 average = ewma.NewMovingAverage(age)
3939 }
40 average = &ThreadSafeMovingAverage{MovingAverage: average}
4041 return MovingAverageSpeed(unit, format, average, wcc...)
4142 }
4243
5859 // unit=UnitKB, format="%.1f" output: "1.0MB/s"
5960 // unit=UnitKB, format="% .1f" output: "1.0 MB/s"
6061 //
61 func MovingAverageSpeed(unit int, format string, average MovingAverage, wcc ...WC) Decorator {
62 func MovingAverageSpeed(unit int, format string, average ewma.MovingAverage, wcc ...WC) Decorator {
6263 if format == "" {
6364 format = "%.0f"
6465 }
8889 return d.FormatMsg(d.msg)
8990 }
9091
91 func (d *movingAverageSpeed) NextAmount(n int64, wdd ...time.Duration) {
92 var workDuration time.Duration
93 for _, wd := range wdd {
94 workDuration = wd
95 }
96 durPerByte := float64(workDuration) / float64(n)
92 func (d *movingAverageSpeed) EwmaUpdate(n int64, dur time.Duration) {
93 durPerByte := float64(dur) / float64(n)
9794 if math.IsInf(durPerByte, 0) || math.IsNaN(durPerByte) {
9895 return
9996 }