@@ -14,6 +14,7 @@ type Status struct {
1414 Task string `json:"task"`
1515 DonePercent float64 `json:"done_percent"`
1616 LinesCompleted int64 `json:"lines_completed"`
17+ BytesCompleted int64 `json:"bytes_completed"`
1718 SpeedMBPS float64 `json:"speed_mbps"`
1819 SpeedLPS float64 `json:"speed_lps"`
1920 Elapsed time.Duration `json:"-"`
@@ -27,13 +28,20 @@ type Progress struct {
2728 Print func (status Status )
2829 ShowHeapStats bool
2930 ShowLinesStats bool
30- done chan bool
31- task Task
32- lines func () int64
33- current func () int64
34- tot func () int64
35- prnt func (s Status )
36- start time.Time
31+
32+ // IncrementalSpeed shows speed and remaining estimate based on performance between two status updates.
33+ IncrementalSpeed bool
34+
35+ done chan bool
36+ task Task
37+ lines func () int64
38+ current func () int64
39+ tot func () int64
40+ prnt func (s Status )
41+ start time.Time
42+
43+ prevStatus Status
44+
3745 continuedLines int64
3846 continuedBytes int64
3947 metrics []Metric
@@ -191,16 +199,34 @@ func (p *Progress) Reset() {
191199 p .metrics = nil
192200}
193201
194- func (p * Progress ) printStatus (last bool ) {
195- s := Status {}
196- s .Task = p .task .Task
197- s .LinesCompleted = p .Lines ()
198- s .Metrics = p .metrics
202+ func (p * Progress ) speedStatus (s * Status ) {
203+ if p .IncrementalSpeed {
204+ lc := s .LinesCompleted - p .prevStatus .LinesCompleted
205+ bc := s .BytesCompleted - p .prevStatus .BytesCompleted
206+ dc := s .DonePercent - p .prevStatus .DonePercent
207+ ela := s .Elapsed - p .prevStatus .Elapsed
199208
200- b := float64 (p .Bytes ())
201- s .DonePercent = 100 * b / float64 (p .tot ())
202- s .Elapsed = time .Since (p .start )
203- s .SpeedMBPS = (b / s .Elapsed .Seconds ()) / (1024 * 1024 )
209+ if lc > 0 {
210+ s .SpeedLPS = float64 (lc ) / ela .Seconds ()
211+ }
212+
213+ if bc > 0 {
214+ s .SpeedMBPS = (float64 (bc ) / ela .Seconds ()) / (1024 * 1024 )
215+ }
216+
217+ if s .DonePercent > 0 {
218+ s .Remaining = time .Duration ((100.0 - s .DonePercent ) * float64 (ela ) / dc )
219+ s .Remaining = s .Remaining .Truncate (time .Second )
220+ } else {
221+ s .Remaining = 0
222+ }
223+
224+ p .prevStatus = * s
225+
226+ return
227+ }
228+
229+ s .SpeedMBPS = (float64 (s .BytesCompleted ) / s .Elapsed .Seconds ()) / (1024 * 1024 )
204230 s .SpeedLPS = float64 (s .LinesCompleted ) / s .Elapsed .Seconds ()
205231
206232 if s .DonePercent > 0 {
@@ -209,6 +235,18 @@ func (p *Progress) printStatus(last bool) {
209235 } else {
210236 s .Remaining = 0
211237 }
238+ }
239+
240+ func (p * Progress ) printStatus (last bool ) {
241+ s := Status {}
242+ s .Task = p .task .Task
243+ s .LinesCompleted = p .Lines ()
244+ s .BytesCompleted = p .Bytes ()
245+ s .Metrics = p .metrics
246+ s .Elapsed = time .Since (p .start )
247+ s .DonePercent = 100 * float64 (s .BytesCompleted ) / float64 (p .tot ())
248+
249+ p .speedStatus (& s )
212250
213251 if s .Remaining > 100 * time .Millisecond || s .Remaining == 0 || last {
214252 p .prnt (s )
0 commit comments