reduce alloc for: Completed, Total, Current, ID, NumOfAppenders, NumOfPrependers
Vladimir Bauer
7 years ago
| 24 | 24 | formatLen = 5 |
| 25 | 25 | ) |
| 26 | 26 | |
| 27 | const ( | |
| 28 | cmdId = 1 << iota | |
| 29 | cmdTotal | |
| 30 | cmdCurrent | |
| 31 | cmdALen | |
| 32 | cmdPLen | |
| 33 | cmdCompleted | |
| 34 | ) | |
| 35 | ||
| 27 | 36 | type barRunes [formatLen]rune |
| 28 | 37 | |
| 29 | 38 | // Bar represents a progress Bar |
| 34 | 43 | runningBar *Bar |
| 35 | 44 | cacheState *bState |
| 36 | 45 | operateState chan func(*bState) |
| 46 | cmdValue chan int | |
| 37 | 47 | frameReaderCh chan io.Reader |
| 38 | 48 | |
| 39 | 49 | // done is closed by Bar's goroutine, after cacheState is written |
| 46 | 56 | bState struct { |
| 47 | 57 | id int |
| 48 | 58 | width int |
| 49 | runes barRunes | |
| 50 | 59 | total int64 |
| 51 | 60 | current int64 |
| 52 | 61 | totalAutoIncrTrigger int64 |
| 53 | 62 | totalAutoIncrBy int64 |
| 63 | runes barRunes | |
| 54 | 64 | trimLeftSpace bool |
| 55 | 65 | trimRightSpace bool |
| 56 | 66 | toComplete bool |
| 108 | 118 | priority: s.priority, |
| 109 | 119 | runningBar: s.runningBar, |
| 110 | 120 | operateState: make(chan func(*bState)), |
| 121 | cmdValue: make(chan int), | |
| 111 | 122 | frameReaderCh: make(chan io.Reader, 1), |
| 112 | 123 | done: make(chan struct{}), |
| 113 | 124 | shutdown: make(chan struct{}), |
| 148 | 159 | |
| 149 | 160 | // NumOfAppenders returns current number of append decorators. |
| 150 | 161 | func (b *Bar) NumOfAppenders() int { |
| 151 | result := make(chan int) | |
| 152 | select { | |
| 153 | case b.operateState <- func(s *bState) { result <- len(s.aDecorators) }: | |
| 154 | return <-result | |
| 162 | select { | |
| 163 | case b.cmdValue <- cmdALen: | |
| 164 | return <-b.cmdValue | |
| 155 | 165 | case <-b.done: |
| 156 | 166 | return len(b.cacheState.aDecorators) |
| 157 | 167 | } |
| 159 | 169 | |
| 160 | 170 | // NumOfPrependers returns current number of prepend decorators. |
| 161 | 171 | func (b *Bar) NumOfPrependers() int { |
| 162 | result := make(chan int) | |
| 163 | select { | |
| 164 | case b.operateState <- func(s *bState) { result <- len(s.pDecorators) }: | |
| 165 | return <-result | |
| 172 | select { | |
| 173 | case b.cmdValue <- cmdPLen: | |
| 174 | return <-b.cmdValue | |
| 166 | 175 | case <-b.done: |
| 167 | 176 | return len(b.cacheState.pDecorators) |
| 168 | 177 | } |
| 170 | 179 | |
| 171 | 180 | // ID returs id of the bar. |
| 172 | 181 | func (b *Bar) ID() int { |
| 173 | result := make(chan int) | |
| 174 | select { | |
| 175 | case b.operateState <- func(s *bState) { result <- s.id }: | |
| 176 | return <-result | |
| 182 | select { | |
| 183 | case b.cmdValue <- cmdId: | |
| 184 | return <-b.cmdValue | |
| 177 | 185 | case <-b.done: |
| 178 | 186 | return b.cacheState.id |
| 179 | 187 | } |
| 181 | 189 | |
| 182 | 190 | // Current returns bar's current number, in other words sum of all increments. |
| 183 | 191 | func (b *Bar) Current() int64 { |
| 184 | result := make(chan int64) | |
| 185 | select { | |
| 186 | case b.operateState <- func(s *bState) { result <- s.current }: | |
| 187 | return <-result | |
| 192 | select { | |
| 193 | case b.cmdValue <- cmdCurrent: | |
| 194 | return int64(<-b.cmdValue) | |
| 188 | 195 | case <-b.done: |
| 189 | 196 | return b.cacheState.current |
| 190 | 197 | } |
| 192 | 199 | |
| 193 | 200 | // Total returns bar's total number. |
| 194 | 201 | func (b *Bar) Total() int64 { |
| 195 | result := make(chan int64) | |
| 196 | select { | |
| 197 | case b.operateState <- func(s *bState) { result <- s.total }: | |
| 198 | return <-result | |
| 202 | select { | |
| 203 | case b.cmdValue <- cmdTotal: | |
| 204 | return int64(<-b.cmdValue) | |
| 199 | 205 | case <-b.done: |
| 200 | 206 | return b.cacheState.total |
| 201 | 207 | } |
| 252 | 258 | |
| 253 | 259 | // Completed reports whether the bar is in completed state. |
| 254 | 260 | func (b *Bar) Completed() bool { |
| 255 | result := make(chan bool) | |
| 256 | b.operateState <- func(s *bState) { result <- s.toComplete } | |
| 257 | return <-result | |
| 261 | b.cmdValue <- cmdCompleted | |
| 262 | if v := <-b.cmdValue; v == 1 { | |
| 263 | return true | |
| 264 | } | |
| 265 | return false | |
| 258 | 266 | } |
| 259 | 267 | |
| 260 | 268 | func (b *Bar) serve(wg *sync.WaitGroup, s *bState, cancel <-chan struct{}) { |
| 263 | 271 | select { |
| 264 | 272 | case op := <-b.operateState: |
| 265 | 273 | op(s) |
| 274 | case cmd := <-b.cmdValue: | |
| 275 | switch { | |
| 276 | case cmd&cmdId != 0: | |
| 277 | b.cmdValue <- s.id | |
| 278 | case cmd&cmdTotal != 0: | |
| 279 | b.cmdValue <- int(s.total) | |
| 280 | case cmd&cmdCurrent != 0: | |
| 281 | b.cmdValue <- int(s.current) | |
| 282 | case cmd&cmdPLen != 0: | |
| 283 | b.cmdValue <- len(s.pDecorators) | |
| 284 | case cmd&cmdALen != 0: | |
| 285 | b.cmdValue <- len(s.aDecorators) | |
| 286 | case cmd&cmdCompleted != 0: | |
| 287 | var v int | |
| 288 | if s.toComplete { | |
| 289 | v = 1 | |
| 290 | } | |
| 291 | b.cmdValue <- v | |
| 292 | } | |
| 266 | 293 | case <-cancel: |
| 267 | 294 | s.toComplete = true |
| 268 | 295 | cancel = nil |