Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
Miloslav Trmač
2024-05-09 21:49:41 +02:00
parent dcf937e170
commit 7649059a0d
474 changed files with 30496 additions and 30923 deletions

View File

@@ -44,12 +44,11 @@ type bState struct {
rmOnComplete bool
noPop bool
autoRefresh bool
aDecorators []decor.Decorator
pDecorators []decor.Decorator
buffers [3]*bytes.Buffer
decorators [2][]decor.Decorator
averageDecorators []decor.AverageDecorator
ewmaDecorators []decor.EwmaDecorator
shutdownListeners []decor.ShutdownListener
buffers [3]*bytes.Buffer
filler BarFiller
extender extenderFunc
renderReq chan<- time.Time
@@ -159,10 +158,7 @@ func (b *Bar) TraverseDecorators(cb func(decor.Decorator)) {
iter := make(chan decor.Decorator)
select {
case b.operateState <- func(s *bState) {
for _, decorators := range [][]decor.Decorator{
s.pDecorators,
s.aDecorators,
} {
for _, decorators := range s.decorators {
for _, d := range decorators {
iter <- d
}
@@ -250,9 +246,7 @@ func (b *Bar) EwmaSetCurrent(current int64, iterDur time.Duration) {
}
select {
case b.operateState <- func(s *bState) {
if n := current - s.current; n > 0 {
s.decoratorEwmaUpdate(n, iterDur)
}
s.decoratorEwmaUpdate(current-s.current, iterDur)
s.current = current
if s.triggerComplete && s.current >= s.total {
s.current = s.total
@@ -411,22 +405,21 @@ func (b *Bar) serve(ctx context.Context, bs *bState) {
func (b *Bar) render(tw int) {
fn := func(s *bState) {
var rows []io.Reader
frame := new(renderFrame)
stat := newStatistics(tw, s)
r, err := s.draw(stat)
if err != nil {
b.frameCh <- &renderFrame{err: err}
for _, buf := range s.buffers {
buf.Reset()
}
frame.err = err
b.frameCh <- frame
return
}
rows = append(rows, r)
frame.rows = append(frame.rows, r)
if s.extender != nil {
rows, err = s.extender(rows, stat)
if err != nil {
b.frameCh <- &renderFrame{err: err}
return
}
frame.rows, frame.err = s.extender(frame.rows, stat)
}
frame := &renderFrame{rows: rows}
if s.completed || s.aborted {
frame.shutdown = s.shutdown
frame.rmOnComplete = s.rmOnComplete
@@ -484,18 +477,7 @@ func (b *Bar) wSyncTable() syncTable {
}
}
func (s *bState) draw(stat decor.Statistics) (io.Reader, error) {
r, err := s.drawImpl(stat)
if err != nil {
for _, b := range s.buffers {
b.Reset()
}
return nil, err
}
return io.MultiReader(r, strings.NewReader("\n")), nil
}
func (s *bState) drawImpl(stat decor.Statistics) (io.Reader, error) {
func (s *bState) draw(stat decor.Statistics) (_ io.Reader, err error) {
decorFiller := func(buf *bytes.Buffer, decorators []decor.Decorator) (err error) {
for _, d := range decorators {
// need to call Decor in any case becase of width synchronization
@@ -515,45 +497,45 @@ func (s *bState) drawImpl(stat decor.Statistics) (io.Reader, error) {
return err
}
bufP, bufB, bufA := s.buffers[0], s.buffers[1], s.buffers[2]
err := eitherError(decorFiller(bufP, s.pDecorators), decorFiller(bufA, s.aDecorators))
if err != nil {
return nil, err
}
if !s.trimSpace && stat.AvailableWidth >= 2 {
stat.AvailableWidth -= 2
writeFiller := func(buf *bytes.Buffer) error {
return s.filler.Fill(buf, stat)
}
for _, fn := range []func(*bytes.Buffer) error{
writeSpace,
writeFiller,
writeSpace,
} {
if err := fn(bufB); err != nil {
return nil, err
}
}
} else {
err := s.filler.Fill(bufB, stat)
for i, buf := range s.buffers[:2] {
err = decorFiller(buf, s.decorators[i])
if err != nil {
return nil, err
}
}
return io.MultiReader(bufP, bufB, bufA), nil
spaces := []io.Reader{
strings.NewReader(" "),
strings.NewReader(" "),
}
if s.trimSpace || stat.AvailableWidth < 2 {
for _, r := range spaces {
_, _ = io.Copy(io.Discard, r)
}
} else {
stat.AvailableWidth -= 2
}
err = s.filler.Fill(s.buffers[2], stat)
if err != nil {
return nil, err
}
return io.MultiReader(
s.buffers[0],
spaces[0],
s.buffers[2],
spaces[1],
s.buffers[1],
strings.NewReader("\n"),
), nil
}
func (s *bState) wSyncTable() (table syncTable) {
var count int
var row []chan int
for i, decorators := range [][]decor.Decorator{
s.pDecorators,
s.aDecorators,
} {
for i, decorators := range s.decorators {
for _, d := range decorators {
if ch, ok := d.Sync(); ok {
row = append(row, ch)
@@ -640,16 +622,3 @@ func unwrap(d decor.Decorator) decor.Decorator {
}
return d
}
func writeSpace(buf *bytes.Buffer) error {
return buf.WriteByte(' ')
}
func eitherError(errors ...error) error {
for _, err := range errors {
if err != nil {
return err
}
}
return nil
}

View File

@@ -20,19 +20,19 @@ func inspect(decorators []decor.Decorator) (dest []decor.Decorator) {
return
}
// AppendDecorators let you inject decorators to the bar's right side.
func AppendDecorators(decorators ...decor.Decorator) BarOption {
decorators = inspect(decorators)
return func(s *bState) {
s.aDecorators = decorators
}
}
// PrependDecorators let you inject decorators to the bar's left side.
func PrependDecorators(decorators ...decor.Decorator) BarOption {
decorators = inspect(decorators)
return func(s *bState) {
s.pDecorators = decorators
s.decorators[0] = decorators
}
}
// AppendDecorators let you inject decorators to the bar's right side.
func AppendDecorators(decorators ...decor.Decorator) BarOption {
decorators = inspect(decorators)
return func(s *bState) {
s.decorators[1] = decorators
}
}
@@ -129,11 +129,11 @@ func makeExtenderFunc(filler BarFiller, rev bool) extenderFunc {
for {
b, err := buf.ReadBytes('\n')
if err != nil {
buf.Reset()
break
}
rows = append(rows, bytes.NewReader(b))
}
buf.Reset()
return rows, err
}

View File

@@ -85,7 +85,7 @@ type Synchronizer interface {
// in order to format string according to decor.WC settings.
// No need to implement manually as long as decor.WC is embedded.
type Formatter interface {
Format(string) (str string, viewWidth int)
Format(string) (_ string, width int)
}
// Wrapper interface.
@@ -138,17 +138,17 @@ type WC struct {
// Format should be called by any Decorator implementation.
// Returns formatted string and its view (visual) width.
func (wc WC) Format(str string) (string, int) {
viewWidth := runewidth.StringWidth(str)
if wc.W > viewWidth {
viewWidth = wc.W
width := runewidth.StringWidth(str)
if wc.W > width {
width = wc.W
} else if (wc.C & DextraSpace) != 0 {
viewWidth++
width++
}
if (wc.C & DSyncWidth) != 0 {
wc.wsync <- viewWidth
viewWidth = <-wc.wsync
wc.wsync <- width
width = <-wc.wsync
}
return wc.fill(str, viewWidth), viewWidth
return wc.fill(str, width), width
}
// Init initializes width related config.

View File

@@ -39,7 +39,7 @@ func EwmaETA(style TimeStyle, age float64, wcc ...WC) Decorator {
} else {
average = ewma.NewMovingAverage(age)
}
return MovingAverageETA(style, NewThreadSafeMovingAverage(average), nil, wcc...)
return MovingAverageETA(style, average, nil, wcc...)
}
// MovingAverageETA decorator relies on MovingAverage implementation to calculate its average.

View File

@@ -70,5 +70,5 @@ func (s *medianWindow) Set(value float64) {
// NewMedian is fixed last 3 samples median MovingAverage.
func NewMedian() ewma.MovingAverage {
return NewThreadSafeMovingAverage(new(medianWindow))
return new(medianWindow)
}

View File

@@ -56,7 +56,7 @@ type onAbortMetaWrapper struct {
}
func (d onAbortMetaWrapper) Decor(s Statistics) (string, int) {
if s.Completed {
if s.Aborted {
str, width := d.Decorator.Decor(s)
return d.fn(str), width
}

View File

@@ -46,7 +46,7 @@ func EwmaSpeed(unit interface{}, format string, age float64, wcc ...WC) Decorato
} else {
average = ewma.NewMovingAverage(age)
}
return MovingAverageSpeed(unit, format, NewThreadSafeMovingAverage(average), wcc...)
return MovingAverageSpeed(unit, format, average, wcc...)
}
// MovingAverageSpeed decorator relies on MovingAverage implementation
@@ -82,7 +82,7 @@ type movingAverageSpeed struct {
zDur time.Duration
}
func (d *movingAverageSpeed) Decor(s Statistics) (string, int) {
func (d *movingAverageSpeed) Decor(_ Statistics) (string, int) {
var str string
// ewma implementation may return 0 before accumulating certain number of samples
if v := d.average.Value(); v != 0 {

View File

@@ -3,7 +3,7 @@ package internal
// CheckRequestedWidth checks that requested width doesn't overflow
// available width
func CheckRequestedWidth(requested, available int) int {
if requested < 1 || requested >= available {
if requested < 1 || requested > available {
return available
}
return requested

View File

@@ -14,9 +14,7 @@ import (
"github.com/vbauerster/mpb/v8/decor"
)
const (
defaultRefreshRate = 150 * time.Millisecond
)
const defaultRefreshRate = 150 * time.Millisecond
// DoneError represents use after `(*Progress).Wait()` error.
var DoneError = fmt.Errorf("%T instance can't be reused after %[1]T.Wait()", (*Progress)(nil))
@@ -467,9 +465,9 @@ func (s pState) makeBarState(total int64, filler BarFiller, options ...BarOption
}
}
for i := 0; i < len(bs.buffers); i++ {
bs.buffers[i] = bytes.NewBuffer(make([]byte, 0, 512))
}
bs.buffers[0] = bytes.NewBuffer(make([]byte, 0, 128)) // prepend
bs.buffers[1] = bytes.NewBuffer(make([]byte, 0, 128)) // append
bs.buffers[2] = bytes.NewBuffer(make([]byte, 0, 256)) // filler
return bs
}