speed decor with producer func
Vladimir Bauer
6 years ago
| 21 | 21 | // Note that it's necessary to supply bar.Incr* methods with incremental |
| 22 | 22 | // work duration as second argument, in order for this decorator to |
| 23 | 23 | // work correctly. This decorator is a wrapper of MovingAverageSpeed. |
| 24 | func EwmaSpeed(unit int, fmt string, age float64, wcc ...WC) Decorator { | |
| 25 | return MovingAverageSpeed(unit, fmt, ewma.NewMovingAverage(age), wcc...) | |
| 24 | func EwmaSpeed(unit int, format string, age float64, wcc ...WC) Decorator { | |
| 25 | return MovingAverageSpeed(unit, format, ewma.NewMovingAverage(age), wcc...) | |
| 26 | 26 | } |
| 27 | 27 | |
| 28 | 28 | // MovingAverageSpeed decorator relies on MovingAverage implementation |
| 30 | 30 | // |
| 31 | 31 | // `unit` one of [0|UnitKiB|UnitKB] zero for no unit |
| 32 | 32 | // |
| 33 | // `fmt` printf compatible verb for value, like "%f" or "%d" | |
| 33 | // `format` printf compatible verb for value, like "%f" or "%d" | |
| 34 | 34 | // |
| 35 | 35 | // `average` MovingAverage implementation |
| 36 | 36 | // |
| 37 | 37 | // `wcc` optional WC config |
| 38 | 38 | // |
| 39 | // fmt examples: | |
| 39 | // format examples: | |
| 40 | 40 | // |
| 41 | // unit=UnitKiB, fmt="%.1f" output: "1.0MiB/s" | |
| 42 | // unit=UnitKiB, fmt="% .1f" output: "1.0 MiB/s" | |
| 43 | // unit=UnitKB, fmt="%.1f" output: "1.0MB/s" | |
| 44 | // unit=UnitKB, fmt="% .1f" output: "1.0 MB/s" | |
| 41 | // unit=UnitKiB, format="%.1f" output: "1.0MiB/s" | |
| 42 | // unit=UnitKiB, format="% .1f" output: "1.0 MiB/s" | |
| 43 | // unit=UnitKB, format="%.1f" output: "1.0MB/s" | |
| 44 | // unit=UnitKB, format="% .1f" output: "1.0 MB/s" | |
| 45 | 45 | // |
| 46 | func MovingAverageSpeed(unit int, fmt string, average MovingAverage, wcc ...WC) Decorator { | |
| 46 | func MovingAverageSpeed(unit int, format string, average MovingAverage, wcc ...WC) Decorator { | |
| 47 | 47 | var wc WC |
| 48 | 48 | for _, widthConf := range wcc { |
| 49 | 49 | wc = widthConf |
| 50 | 50 | } |
| 51 | if format == "" { | |
| 52 | format = "%.0f" | |
| 53 | } | |
| 51 | 54 | wc.Init() |
| 52 | if fmt == "" { | |
| 53 | fmt = "%.0f" | |
| 54 | } | |
| 55 | 55 | d := &movingAverageSpeed{ |
| 56 | 56 | WC: wc, |
| 57 | unit: unit, | |
| 58 | fmt: fmt, | |
| 59 | 57 | average: average, |
| 58 | } | |
| 59 | switch unit { | |
| 60 | case UnitKiB: | |
| 61 | d.producer = func(speed float64) string { | |
| 62 | return fmt.Sprintf(format, &speedType{SizeB1024(math.Round(speed))}) | |
| 63 | } | |
| 64 | case UnitKB: | |
| 65 | d.producer = func(speed float64) string { | |
| 66 | return fmt.Sprintf(format, &speedType{SizeB1000(math.Round(speed))}) | |
| 67 | } | |
| 68 | default: | |
| 69 | d.producer = func(speed float64) string { | |
| 70 | return fmt.Sprintf(format, speed) | |
| 71 | } | |
| 60 | 72 | } |
| 61 | 73 | return d |
| 62 | 74 | } |
| 63 | 75 | |
| 64 | 76 | type movingAverageSpeed struct { |
| 65 | 77 | WC |
| 66 | unit int | |
| 67 | fmt string | |
| 78 | producer func(float64) string | |
| 68 | 79 | average ewma.MovingAverage |
| 69 | 80 | msg string |
| 70 | 81 | completeMsg *string |
| 78 | 89 | return d.FormatMsg(d.msg) |
| 79 | 90 | } |
| 80 | 91 | |
| 81 | speed := d.average.Value() | |
| 82 | ||
| 83 | var val interface{} | |
| 84 | switch d.unit { | |
| 85 | case UnitKiB: | |
| 86 | val = &speedType{SizeB1024(math.Round(speed))} | |
| 87 | case UnitKB: | |
| 88 | val = &speedType{SizeB1000(math.Round(speed))} | |
| 89 | default: | |
| 90 | val = speed | |
| 91 | } | |
| 92 | d.msg = fmt.Sprintf(d.fmt, val) | |
| 92 | d.msg = d.producer(d.average.Value()) | |
| 93 | 93 | |
| 94 | 94 | return d.FormatMsg(d.msg) |
| 95 | 95 | } |
| 112 | 112 | |
| 113 | 113 | // AverageSpeed decorator with dynamic unit measure adjustment. It's |
| 114 | 114 | // a wrapper of NewAverageSpeed. |
| 115 | func AverageSpeed(unit int, fmt string, wcc ...WC) Decorator { | |
| 116 | return NewAverageSpeed(unit, fmt, time.Now(), wcc...) | |
| 115 | func AverageSpeed(unit int, format string, wcc ...WC) Decorator { | |
| 116 | return NewAverageSpeed(unit, format, time.Now(), wcc...) | |
| 117 | 117 | } |
| 118 | 118 | |
| 119 | 119 | // NewAverageSpeed decorator with dynamic unit measure adjustment and |
| 121 | 121 | // |
| 122 | 122 | // `unit` one of [0|UnitKiB|UnitKB] zero for no unit |
| 123 | 123 | // |
| 124 | // `fmt` printf compatible verb for value, like "%f" or "%d" | |
| 124 | // `format` printf compatible verb for value, like "%f" or "%d" | |
| 125 | 125 | // |
| 126 | 126 | // `startTime` start time |
| 127 | 127 | // |
| 128 | 128 | // `wcc` optional WC config |
| 129 | 129 | // |
| 130 | // fmt examples: | |
| 130 | // format examples: | |
| 131 | 131 | // |
| 132 | // unit=UnitKiB, fmt="%.1f" output: "1.0MiB/s" | |
| 133 | // unit=UnitKiB, fmt="% .1f" output: "1.0 MiB/s" | |
| 134 | // unit=UnitKB, fmt="%.1f" output: "1.0MB/s" | |
| 135 | // unit=UnitKB, fmt="% .1f" output: "1.0 MB/s" | |
| 132 | // unit=UnitKiB, format="%.1f" output: "1.0MiB/s" | |
| 133 | // unit=UnitKiB, format="% .1f" output: "1.0 MiB/s" | |
| 134 | // unit=UnitKB, format="%.1f" output: "1.0MB/s" | |
| 135 | // unit=UnitKB, format="% .1f" output: "1.0 MB/s" | |
| 136 | 136 | // |
| 137 | func NewAverageSpeed(unit int, fmt string, startTime time.Time, wcc ...WC) Decorator { | |
| 137 | func NewAverageSpeed(unit int, format string, startTime time.Time, wcc ...WC) Decorator { | |
| 138 | 138 | var wc WC |
| 139 | 139 | for _, widthConf := range wcc { |
| 140 | 140 | wc = widthConf |
| 141 | 141 | } |
| 142 | if format == "" { | |
| 143 | format = "%.0f" | |
| 144 | } | |
| 142 | 145 | wc.Init() |
| 143 | if fmt == "" { | |
| 144 | fmt = "%.0f" | |
| 145 | } | |
| 146 | 146 | d := &averageSpeed{ |
| 147 | 147 | WC: wc, |
| 148 | unit: unit, | |
| 149 | 148 | startTime: startTime, |
| 150 | fmt: fmt, | |
| 149 | } | |
| 150 | switch unit { | |
| 151 | case UnitKiB: | |
| 152 | d.producer = func(speed float64) string { | |
| 153 | return fmt.Sprintf(format, &speedType{SizeB1024(math.Round(speed))}) | |
| 154 | } | |
| 155 | case UnitKB: | |
| 156 | d.producer = func(speed float64) string { | |
| 157 | return fmt.Sprintf(format, &speedType{SizeB1000(math.Round(speed))}) | |
| 158 | } | |
| 159 | default: | |
| 160 | d.producer = func(speed float64) string { | |
| 161 | return fmt.Sprintf(format, speed) | |
| 162 | } | |
| 151 | 163 | } |
| 152 | 164 | return d |
| 153 | 165 | } |
| 154 | 166 | |
| 155 | 167 | type averageSpeed struct { |
| 156 | 168 | WC |
| 157 | unit int | |
| 158 | 169 | startTime time.Time |
| 159 | fmt string | |
| 170 | producer func(float64) string | |
| 160 | 171 | msg string |
| 161 | 172 | completeMsg *string |
| 162 | 173 | } |
| 169 | 180 | return d.FormatMsg(d.msg) |
| 170 | 181 | } |
| 171 | 182 | |
| 172 | timeElapsed := time.Since(d.startTime) | |
| 173 | speed := float64(st.Current) / timeElapsed.Seconds() | |
| 174 | ||
| 175 | var val interface{} | |
| 176 | switch d.unit { | |
| 177 | case UnitKiB: | |
| 178 | val = &speedType{SizeB1024(math.Round(speed))} | |
| 179 | case UnitKB: | |
| 180 | val = &speedType{SizeB1000(math.Round(speed))} | |
| 181 | default: | |
| 182 | val = speed | |
| 183 | } | |
| 184 | d.msg = fmt.Sprintf(d.fmt, val) | |
| 183 | speed := float64(st.Current) / time.Since(d.startTime).Seconds() | |
| 184 | d.msg = d.producer(speed) | |
| 185 | 185 | |
| 186 | 186 | return d.FormatMsg(d.msg) |
| 187 | 187 | } |