refactoring speed: unit is either [0|SizeB1024(0)|SizeB1000(0)]
Vladimir Bauer
3 years ago
| 3 | 3 | "fmt" |
| 4 | 4 | "io" |
| 5 | 5 | "math" |
| 6 | "strings" | |
| 6 | 7 | "time" |
| 7 | 8 | |
| 8 | 9 | "github.com/VividCortex/ewma" |
| 38 | 39 | // EwmaSpeed exponential-weighted-moving-average based speed decorator. |
| 39 | 40 | // For this decorator to work correctly you have to measure each iteration's |
| 40 | 41 | // duration and pass it to one of the (*Bar).EwmaIncr... family methods. |
| 41 | func EwmaSpeed(unit int, format string, age float64, wcc ...WC) Decorator { | |
| 42 | func EwmaSpeed(unit interface{}, format string, age float64, wcc ...WC) Decorator { | |
| 42 | 43 | var average ewma.MovingAverage |
| 43 | 44 | if age == 0 { |
| 44 | 45 | average = ewma.NewMovingAverage() |
| 51 | 52 | // MovingAverageSpeed decorator relies on MovingAverage implementation |
| 52 | 53 | // to calculate its average. |
| 53 | 54 | // |
| 54 | // `unit` one of [0|UnitKiB|UnitKB] zero for no unit | |
| 55 | // `unit` one of [0|SizeB1024(0)|SizeB1000(0)] | |
| 55 | 56 | // |
| 56 | 57 | // `format` printf compatible verb for value, like "%f" or "%d" |
| 57 | 58 | // |
| 61 | 62 | // |
| 62 | 63 | // format examples: |
| 63 | 64 | // |
| 64 | // unit=UnitKiB, format="%.1f" output: "1.0MiB/s" | |
| 65 | // unit=UnitKiB, format="% .1f" output: "1.0 MiB/s" | |
| 66 | // unit=UnitKB, format="%.1f" output: "1.0MB/s" | |
| 67 | // unit=UnitKB, format="% .1f" output: "1.0 MB/s" | |
| 68 | func MovingAverageSpeed(unit int, format string, average ewma.MovingAverage, wcc ...WC) Decorator { | |
| 65 | // unit=SizeB1024(0), format="%.1f" output: "1.0MiB/s" | |
| 66 | // unit=SizeB1024(0), format="% .1f" output: "1.0 MiB/s" | |
| 67 | // unit=SizeB1000(0), format="%.1f" output: "1.0MB/s" | |
| 68 | // unit=SizeB1000(0), format="% .1f" output: "1.0 MB/s" | |
| 69 | func MovingAverageSpeed(unit interface{}, format string, average ewma.MovingAverage, wcc ...WC) Decorator { | |
| 69 | 70 | if format == "" { |
| 70 | 71 | format = "%.0f" |
| 72 | } else if strings.Count(format, "%") != 1 { | |
| 73 | panic("expected format with exactly 1 verb") | |
| 71 | 74 | } |
| 72 | 75 | d := &movingAverageSpeed{ |
| 73 | 76 | WC: initWC(wcc...), |
| 112 | 115 | // NewAverageSpeed decorator with dynamic unit measure adjustment and |
| 113 | 116 | // user provided start time. |
| 114 | 117 | // |
| 115 | // `unit` one of [0|UnitKiB|UnitKB] zero for no unit | |
| 118 | // `unit` one of [0|SizeB1024(0)|SizeB1000(0)] | |
| 116 | 119 | // |
| 117 | 120 | // `format` printf compatible verb for value, like "%f" or "%d" |
| 118 | 121 | // |
| 122 | 125 | // |
| 123 | 126 | // format examples: |
| 124 | 127 | // |
| 125 | // unit=UnitKiB, format="%.1f" output: "1.0MiB/s" | |
| 126 | // unit=UnitKiB, format="% .1f" output: "1.0 MiB/s" | |
| 127 | // unit=UnitKB, format="%.1f" output: "1.0MB/s" | |
| 128 | // unit=UnitKB, format="% .1f" output: "1.0 MB/s" | |
| 129 | func NewAverageSpeed(unit int, format string, startTime time.Time, wcc ...WC) Decorator { | |
| 128 | // unit=SizeB1024(0), format="%.1f" output: "1.0MiB/s" | |
| 129 | // unit=SizeB1024(0), format="% .1f" output: "1.0 MiB/s" | |
| 130 | // unit=SizeB1000(0), format="%.1f" output: "1.0MB/s" | |
| 131 | // unit=SizeB1000(0), format="% .1f" output: "1.0 MB/s" | |
| 132 | func NewAverageSpeed(unit interface{}, format string, startTime time.Time, wcc ...WC) Decorator { | |
| 130 | 133 | if format == "" { |
| 131 | 134 | format = "%.0f" |
| 135 | } else if strings.Count(format, "%") != 1 { | |
| 136 | panic("expected format with exactly 1 verb") | |
| 132 | 137 | } |
| 133 | 138 | d := &averageSpeed{ |
| 134 | 139 | WC: initWC(wcc...), |
| 158 | 163 | d.startTime = startTime |
| 159 | 164 | } |
| 160 | 165 | |
| 161 | func chooseSpeedProducer(unit int, format string) func(float64) string { | |
| 162 | switch unit { | |
| 163 | case UnitKiB: | |
| 166 | func chooseSpeedProducer(unit interface{}, format string) func(float64) string { | |
| 167 | switch unit.(type) { | |
| 168 | case SizeB1024: | |
| 164 | 169 | return func(speed float64) string { |
| 165 | 170 | return fmt.Sprintf(format, FmtAsSpeed(SizeB1024(math.Round(speed)))) |
| 166 | 171 | } |
| 167 | case UnitKB: | |
| 172 | case SizeB1000: | |
| 168 | 173 | return func(speed float64) string { |
| 169 | 174 | return fmt.Sprintf(format, FmtAsSpeed(SizeB1000(math.Round(speed)))) |
| 170 | 175 | } |
| 8 | 8 | cases := []struct { |
| 9 | 9 | name string |
| 10 | 10 | fmt string |
| 11 | unit int | |
| 11 | unit interface{} | |
| 12 | 12 | current int64 |
| 13 | 13 | elapsed time.Duration |
| 14 | 14 | expected string |
| 15 | 15 | }{ |
| 16 | 16 | { |
| 17 | 17 | name: "empty fmt", |
| 18 | unit: UnitKiB, | |
| 18 | unit: SizeB1024(0), | |
| 19 | 19 | fmt: "", |
| 20 | 20 | current: 0, |
| 21 | 21 | elapsed: time.Second, |
| 22 | 22 | expected: "0b/s", |
| 23 | 23 | }, |
| 24 | 24 | { |
| 25 | name: "UnitKiB:%d:0b", | |
| 26 | unit: UnitKiB, | |
| 27 | fmt: "%d", | |
| 28 | current: 0, | |
| 29 | elapsed: time.Second, | |
| 30 | expected: "0b/s", | |
| 31 | }, | |
| 32 | { | |
| 33 | name: "UnitKiB:% .2f:0b", | |
| 34 | unit: UnitKiB, | |
| 25 | name: "SizeB1024(0):%d:0b", | |
| 26 | unit: SizeB1024(0), | |
| 27 | fmt: "%d", | |
| 28 | current: 0, | |
| 29 | elapsed: time.Second, | |
| 30 | expected: "0b/s", | |
| 31 | }, | |
| 32 | { | |
| 33 | name: "SizeB1024(0):% .2f:0b", | |
| 34 | unit: SizeB1024(0), | |
| 35 | 35 | fmt: "% .2f", |
| 36 | 36 | current: 0, |
| 37 | 37 | elapsed: time.Second, |
| 38 | 38 | expected: "0.00 b/s", |
| 39 | 39 | }, |
| 40 | 40 | { |
| 41 | name: "UnitKiB:%d:1b", | |
| 42 | unit: UnitKiB, | |
| 41 | name: "SizeB1024(0):%d:1b", | |
| 42 | unit: SizeB1024(0), | |
| 43 | 43 | fmt: "%d", |
| 44 | 44 | current: 1, |
| 45 | 45 | elapsed: time.Second, |
| 46 | 46 | expected: "1b/s", |
| 47 | 47 | }, |
| 48 | 48 | { |
| 49 | name: "UnitKiB:% .2f:1b", | |
| 50 | unit: UnitKiB, | |
| 49 | name: "SizeB1024(0):% .2f:1b", | |
| 50 | unit: SizeB1024(0), | |
| 51 | 51 | fmt: "% .2f", |
| 52 | 52 | current: 1, |
| 53 | 53 | elapsed: time.Second, |
| 54 | 54 | expected: "1.00 b/s", |
| 55 | 55 | }, |
| 56 | 56 | { |
| 57 | name: "UnitKiB:%d:KiB", | |
| 58 | unit: UnitKiB, | |
| 57 | name: "SizeB1024(0):%d:KiB", | |
| 58 | unit: SizeB1024(0), | |
| 59 | 59 | fmt: "%d", |
| 60 | 60 | current: 2 * int64(_iKiB), |
| 61 | 61 | elapsed: 1 * time.Second, |
| 62 | 62 | expected: "2KiB/s", |
| 63 | 63 | }, |
| 64 | 64 | { |
| 65 | name: "UnitKiB:% .f:KiB", | |
| 66 | unit: UnitKiB, | |
| 65 | name: "SizeB1024(0):% .f:KiB", | |
| 66 | unit: SizeB1024(0), | |
| 67 | 67 | fmt: "% .2f", |
| 68 | 68 | current: 2 * int64(_iKiB), |
| 69 | 69 | elapsed: 1 * time.Second, |
| 70 | 70 | expected: "2.00 KiB/s", |
| 71 | 71 | }, |
| 72 | 72 | { |
| 73 | name: "UnitKiB:%d:MiB", | |
| 74 | unit: UnitKiB, | |
| 73 | name: "SizeB1024(0):%d:MiB", | |
| 74 | unit: SizeB1024(0), | |
| 75 | 75 | fmt: "%d", |
| 76 | 76 | current: 2 * int64(_iMiB), |
| 77 | 77 | elapsed: 1 * time.Second, |
| 78 | 78 | expected: "2MiB/s", |
| 79 | 79 | }, |
| 80 | 80 | { |
| 81 | name: "UnitKiB:% .2f:MiB", | |
| 82 | unit: UnitKiB, | |
| 81 | name: "SizeB1024(0):% .2f:MiB", | |
| 82 | unit: SizeB1024(0), | |
| 83 | 83 | fmt: "% .2f", |
| 84 | 84 | current: 2 * int64(_iMiB), |
| 85 | 85 | elapsed: 1 * time.Second, |
| 86 | 86 | expected: "2.00 MiB/s", |
| 87 | 87 | }, |
| 88 | 88 | { |
| 89 | name: "UnitKiB:%d:GiB", | |
| 90 | unit: UnitKiB, | |
| 89 | name: "SizeB1024(0):%d:GiB", | |
| 90 | unit: SizeB1024(0), | |
| 91 | 91 | fmt: "%d", |
| 92 | 92 | current: 2 * int64(_iGiB), |
| 93 | 93 | elapsed: 1 * time.Second, |
| 94 | 94 | expected: "2GiB/s", |
| 95 | 95 | }, |
| 96 | 96 | { |
| 97 | name: "UnitKiB:% .2f:GiB", | |
| 98 | unit: UnitKiB, | |
| 97 | name: "SizeB1024(0):% .2f:GiB", | |
| 98 | unit: SizeB1024(0), | |
| 99 | 99 | fmt: "% .2f", |
| 100 | 100 | current: 2 * int64(_iGiB), |
| 101 | 101 | elapsed: 1 * time.Second, |
| 102 | 102 | expected: "2.00 GiB/s", |
| 103 | 103 | }, |
| 104 | 104 | { |
| 105 | name: "UnitKiB:%d:TiB", | |
| 106 | unit: UnitKiB, | |
| 105 | name: "SizeB1024(0):%d:TiB", | |
| 106 | unit: SizeB1024(0), | |
| 107 | 107 | fmt: "%d", |
| 108 | 108 | current: 2 * int64(_iTiB), |
| 109 | 109 | elapsed: 1 * time.Second, |
| 110 | 110 | expected: "2TiB/s", |
| 111 | 111 | }, |
| 112 | 112 | { |
| 113 | name: "UnitKiB:% .2f:TiB", | |
| 114 | unit: UnitKiB, | |
| 113 | name: "SizeB1024(0):% .2f:TiB", | |
| 114 | unit: SizeB1024(0), | |
| 115 | 115 | fmt: "% .2f", |
| 116 | 116 | current: 2 * int64(_iTiB), |
| 117 | 117 | elapsed: 1 * time.Second, |
| 136 | 136 | cases := []struct { |
| 137 | 137 | name string |
| 138 | 138 | fmt string |
| 139 | unit int | |
| 139 | unit interface{} | |
| 140 | 140 | current int64 |
| 141 | 141 | elapsed time.Duration |
| 142 | 142 | expected string |
| 143 | 143 | }{ |
| 144 | 144 | { |
| 145 | 145 | name: "empty fmt", |
| 146 | unit: UnitKB, | |
| 146 | unit: SizeB1000(0), | |
| 147 | 147 | fmt: "", |
| 148 | 148 | current: 0, |
| 149 | 149 | elapsed: time.Second, |
| 150 | 150 | expected: "0b/s", |
| 151 | 151 | }, |
| 152 | 152 | { |
| 153 | name: "UnitKB:%d:0b", | |
| 154 | unit: UnitKB, | |
| 155 | fmt: "%d", | |
| 156 | current: 0, | |
| 157 | elapsed: time.Second, | |
| 158 | expected: "0b/s", | |
| 159 | }, | |
| 160 | { | |
| 161 | name: "UnitKB:% .2f:0b", | |
| 162 | unit: UnitKB, | |
| 153 | name: "SizeB1000(0):%d:0b", | |
| 154 | unit: SizeB1000(0), | |
| 155 | fmt: "%d", | |
| 156 | current: 0, | |
| 157 | elapsed: time.Second, | |
| 158 | expected: "0b/s", | |
| 159 | }, | |
| 160 | { | |
| 161 | name: "SizeB1000(0):% .2f:0b", | |
| 162 | unit: SizeB1000(0), | |
| 163 | 163 | fmt: "% .2f", |
| 164 | 164 | current: 0, |
| 165 | 165 | elapsed: time.Second, |
| 166 | 166 | expected: "0.00 b/s", |
| 167 | 167 | }, |
| 168 | 168 | { |
| 169 | name: "UnitKB:%d:1b", | |
| 170 | unit: UnitKB, | |
| 169 | name: "SizeB1000(0):%d:1b", | |
| 170 | unit: SizeB1000(0), | |
| 171 | 171 | fmt: "%d", |
| 172 | 172 | current: 1, |
| 173 | 173 | elapsed: time.Second, |
| 174 | 174 | expected: "1b/s", |
| 175 | 175 | }, |
| 176 | 176 | { |
| 177 | name: "UnitKB:% .2f:1b", | |
| 178 | unit: UnitKB, | |
| 177 | name: "SizeB1000(0):% .2f:1b", | |
| 178 | unit: SizeB1000(0), | |
| 179 | 179 | fmt: "% .2f", |
| 180 | 180 | current: 1, |
| 181 | 181 | elapsed: time.Second, |
| 182 | 182 | expected: "1.00 b/s", |
| 183 | 183 | }, |
| 184 | 184 | { |
| 185 | name: "UnitKB:%d:KB", | |
| 186 | unit: UnitKB, | |
| 185 | name: "SizeB1000(0):%d:KB", | |
| 186 | unit: SizeB1000(0), | |
| 187 | 187 | fmt: "%d", |
| 188 | 188 | current: 2 * int64(_KB), |
| 189 | 189 | elapsed: 1 * time.Second, |
| 190 | 190 | expected: "2KB/s", |
| 191 | 191 | }, |
| 192 | 192 | { |
| 193 | name: "UnitKB:% .f:KB", | |
| 194 | unit: UnitKB, | |
| 193 | name: "SizeB1000(0):% .f:KB", | |
| 194 | unit: SizeB1000(0), | |
| 195 | 195 | fmt: "% .2f", |
| 196 | 196 | current: 2 * int64(_KB), |
| 197 | 197 | elapsed: 1 * time.Second, |
| 198 | 198 | expected: "2.00 KB/s", |
| 199 | 199 | }, |
| 200 | 200 | { |
| 201 | name: "UnitKB:%d:MB", | |
| 202 | unit: UnitKB, | |
| 201 | name: "SizeB1000(0):%d:MB", | |
| 202 | unit: SizeB1000(0), | |
| 203 | 203 | fmt: "%d", |
| 204 | 204 | current: 2 * int64(_MB), |
| 205 | 205 | elapsed: 1 * time.Second, |
| 206 | 206 | expected: "2MB/s", |
| 207 | 207 | }, |
| 208 | 208 | { |
| 209 | name: "UnitKB:% .2f:MB", | |
| 210 | unit: UnitKB, | |
| 209 | name: "SizeB1000(0):% .2f:MB", | |
| 210 | unit: SizeB1000(0), | |
| 211 | 211 | fmt: "% .2f", |
| 212 | 212 | current: 2 * int64(_MB), |
| 213 | 213 | elapsed: 1 * time.Second, |
| 214 | 214 | expected: "2.00 MB/s", |
| 215 | 215 | }, |
| 216 | 216 | { |
| 217 | name: "UnitKB:%d:GB", | |
| 218 | unit: UnitKB, | |
| 217 | name: "SizeB1000(0):%d:GB", | |
| 218 | unit: SizeB1000(0), | |
| 219 | 219 | fmt: "%d", |
| 220 | 220 | current: 2 * int64(_GB), |
| 221 | 221 | elapsed: 1 * time.Second, |
| 222 | 222 | expected: "2GB/s", |
| 223 | 223 | }, |
| 224 | 224 | { |
| 225 | name: "UnitKB:% .2f:GB", | |
| 226 | unit: UnitKB, | |
| 225 | name: "SizeB1000(0):% .2f:GB", | |
| 226 | unit: SizeB1000(0), | |
| 227 | 227 | fmt: "% .2f", |
| 228 | 228 | current: 2 * int64(_GB), |
| 229 | 229 | elapsed: 1 * time.Second, |
| 230 | 230 | expected: "2.00 GB/s", |
| 231 | 231 | }, |
| 232 | 232 | { |
| 233 | name: "UnitKB:%d:TB", | |
| 234 | unit: UnitKB, | |
| 233 | name: "SizeB1000(0):%d:TB", | |
| 234 | unit: SizeB1000(0), | |
| 235 | 235 | fmt: "%d", |
| 236 | 236 | current: 2 * int64(_TB), |
| 237 | 237 | elapsed: 1 * time.Second, |
| 238 | 238 | expected: "2TB/s", |
| 239 | 239 | }, |
| 240 | 240 | { |
| 241 | name: "UnitKB:% .2f:TB", | |
| 242 | unit: UnitKB, | |
| 241 | name: "SizeB1000(0):% .2f:TB", | |
| 242 | unit: SizeB1000(0), | |
| 243 | 243 | fmt: "% .2f", |
| 244 | 244 | current: 2 * int64(_TB), |
| 245 | 245 | elapsed: 1 * time.Second, |