Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
ollama
Commits
b173cfc5
Unverified
Commit
b173cfc5
authored
Nov 28, 2023
by
Michael Yang
Committed by
GitHub
Nov 28, 2023
Browse files
Merge pull request #1195 from jmorganca/mxyng/fix-bar-rate
progress: fix bar rate
parents
e1a69d44
424d53ac
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
126 additions
and
82 deletions
+126
-82
format/bytes.go
format/bytes.go
+2
-0
progress/bar.go
progress/bar.go
+122
-80
progress/spinner.go
progress/spinner.go
+2
-2
No files found.
format/bytes.go
View file @
b173cfc5
...
...
@@ -37,6 +37,8 @@ func HumanBytes(b int64) string {
switch
{
case
value
>=
100
:
return
fmt
.
Sprintf
(
"%d %s"
,
int
(
value
),
unit
)
case
value
>=
10
:
return
fmt
.
Sprintf
(
"%d %s"
,
int
(
value
),
unit
)
case
value
!=
math
.
Trunc
(
value
)
:
return
fmt
.
Sprintf
(
"%.1f %s"
,
value
,
unit
)
default
:
...
...
progress/bar.go
View file @
b173cfc5
...
...
@@ -2,7 +2,6 @@ package progress
import
(
"fmt"
"math"
"os"
"strings"
"time"
...
...
@@ -11,12 +10,6 @@ import (
"golang.org/x/term"
)
type
Stats
struct
{
rate
int64
value
int64
remaining
time
.
Duration
}
type
Bar
struct
{
message
string
messageWidth
int
...
...
@@ -26,33 +19,45 @@ type Bar struct {
currentValue
int64
started
time
.
Time
stopped
time
.
Time
maxBuckets
int
buckets
[]
bucket
}
stats
Stats
statted
time
.
Time
type
bucket
struct
{
updated
time
.
Time
value
int64
}
func
NewBar
(
message
string
,
maxValue
,
initialValue
int64
)
*
Bar
{
return
&
Bar
{
b
:=
Bar
{
message
:
message
,
messageWidth
:
-
1
,
maxValue
:
maxValue
,
initialValue
:
initialValue
,
currentValue
:
initialValue
,
started
:
time
.
Now
(),
maxBuckets
:
10
,
}
if
initialValue
>=
maxValue
{
b
.
stopped
=
time
.
Now
()
}
return
&
b
}
// formatDuration limits the rendering of a time.Duration to 2 units
func
formatDuration
(
d
time
.
Duration
)
string
{
if
d
>=
100
*
time
.
Hour
{
switch
{
case
d
>=
100
*
time
.
Hour
:
return
"99h+"
}
if
d
>=
time
.
Hour
{
case
d
>=
time
.
Hour
:
return
fmt
.
Sprintf
(
"%dh%dm"
,
int
(
d
.
Hours
()),
int
(
d
.
Minutes
())
%
60
)
default
:
return
d
.
Round
(
time
.
Second
)
.
String
()
}
return
d
.
Round
(
time
.
Second
)
.
String
()
}
func
(
b
*
Bar
)
String
()
string
{
...
...
@@ -61,59 +66,85 @@ func (b *Bar) String() string {
termWidth
=
80
}
var
pre
,
mid
,
suf
strings
.
Builder
if
b
.
message
!=
""
{
var
pre
strings
.
Builder
if
len
(
b
.
message
)
>
0
{
message
:=
strings
.
TrimSpace
(
b
.
message
)
if
b
.
messageWidth
>
0
&&
len
(
message
)
>
b
.
messageWidth
{
message
=
message
[
:
b
.
messageWidth
]
}
fmt
.
Fprintf
(
&
pre
,
"%s"
,
message
)
if
b
.
messageWidth
-
pre
.
Len
()
>
=
0
{
pre
.
WriteString
(
strings
.
R
epeat
(
" "
,
b
.
messageWidth
-
pre
.
Len
()
))
if
padding
:=
b
.
messageWidth
-
pre
.
Len
()
;
padding
>
0
{
pre
.
WriteString
(
r
epeat
(
" "
,
padding
))
}
pre
.
WriteString
(
" "
)
}
fmt
.
Fprintf
(
&
pre
,
"%3.0f%% "
,
math
.
Floor
(
b
.
percent
()))
fmt
.
Fprintf
(
&
suf
,
"(%s/%s"
,
format
.
HumanBytes
(
b
.
currentValue
),
format
.
HumanBytes
(
b
.
maxValue
))
stats
:=
b
.
Stats
()
rate
:=
stats
.
rate
if
stats
.
value
>
b
.
initialValue
&&
stats
.
value
<
b
.
maxValue
{
fmt
.
Fprintf
(
&
suf
,
", %s/s"
,
format
.
HumanBytes
(
int64
(
rate
)))
fmt
.
Fprintf
(
&
pre
,
"%3.0f%%"
,
b
.
percent
())
var
suf
strings
.
Builder
// max 13 characters: "999 MB/999 MB"
if
b
.
stopped
.
IsZero
()
{
curValue
:=
format
.
HumanBytes
(
b
.
currentValue
)
suf
.
WriteString
(
repeat
(
" "
,
6
-
len
(
curValue
)))
suf
.
WriteString
(
curValue
)
suf
.
WriteString
(
"/"
)
maxValue
:=
format
.
HumanBytes
(
b
.
maxValue
)
suf
.
WriteString
(
repeat
(
" "
,
6
-
len
(
maxValue
)))
suf
.
WriteString
(
maxValue
)
}
else
{
maxValue
:=
format
.
HumanBytes
(
b
.
maxValue
)
suf
.
WriteString
(
repeat
(
" "
,
6
-
len
(
maxValue
)))
suf
.
WriteString
(
maxValue
)
suf
.
WriteString
(
repeat
(
" "
,
7
))
}
fmt
.
Fprintf
(
&
suf
,
")"
)
var
timing
string
if
stats
.
value
>
b
.
initialValue
&&
stats
.
value
<
b
.
maxValue
{
timing
=
fmt
.
Sprintf
(
"[%s:%s]"
,
formatDuration
(
time
.
Since
(
b
.
started
)),
formatDuration
(
stats
.
remaining
))
rate
:=
b
.
rate
()
// max 10 characters: " 999 MB/s"
if
b
.
stopped
.
IsZero
()
&&
rate
>
0
{
suf
.
WriteString
(
" "
)
humanRate
:=
format
.
HumanBytes
(
int64
(
rate
))
suf
.
WriteString
(
repeat
(
" "
,
6
-
len
(
humanRate
)))
suf
.
WriteString
(
humanRate
)
suf
.
WriteString
(
"/s"
)
}
else
{
suf
.
WriteString
(
repeat
(
" "
,
10
))
}
// 44 is the maximum width for the stats on the right of the progress bar
pad
:=
44
-
suf
.
Len
()
-
len
(
timing
)
if
pad
>
0
{
suf
.
WriteString
(
strings
.
Repeat
(
" "
,
pad
))
// max 8 characters: " 59m59s"
if
b
.
stopped
.
IsZero
()
&&
rate
>
0
{
suf
.
WriteString
(
" "
)
var
remaining
time
.
Duration
if
rate
>
0
{
remaining
=
time
.
Duration
(
int64
(
float64
(
b
.
maxValue
-
b
.
currentValue
)
/
rate
))
*
time
.
Second
}
humanRemaining
:=
formatDuration
(
remaining
)
suf
.
WriteString
(
repeat
(
" "
,
6
-
len
(
humanRemaining
)))
suf
.
WriteString
(
humanRemaining
)
}
else
{
suf
.
WriteString
(
repeat
(
" "
,
8
))
}
suf
.
WriteString
(
timing
)
// add 3 extra spaces: 2 boundary characters and 1 space at the end
f
:=
termWidth
-
pre
.
Len
()
-
suf
.
Len
()
-
3
var
mid
strings
.
Builder
// add 5 extra spaces: 2 boundary characters and 1 space at each end
f
:=
termWidth
-
pre
.
Len
()
-
suf
.
Len
()
-
5
n
:=
int
(
float64
(
f
)
*
b
.
percent
()
/
100
)
if
f
>
0
{
mid
.
WriteString
(
"▕"
)
mid
.
WriteString
(
strings
.
Repeat
(
"█"
,
n
))
if
f
-
n
>
0
{
mid
.
WriteString
(
strings
.
Repeat
(
" "
,
f
-
n
))
}
mid
.
WriteString
(
"▏"
)
mid
.
WriteString
(
" ▕"
)
if
n
>
0
{
mid
.
WriteString
(
repeat
(
"█"
,
n
))
}
if
f
-
n
>
0
{
mid
.
WriteString
(
repeat
(
" "
,
f
-
n
))
}
mid
.
WriteString
(
"▏ "
)
return
pre
.
String
()
+
mid
.
String
()
+
suf
.
String
()
}
...
...
@@ -123,6 +154,21 @@ func (b *Bar) Set(value int64) {
}
b
.
currentValue
=
value
if
b
.
currentValue
>=
b
.
maxValue
{
b
.
stopped
=
time
.
Now
()
}
// throttle bucket updates to 1 per second
if
len
(
b
.
buckets
)
==
0
||
time
.
Since
(
b
.
buckets
[
len
(
b
.
buckets
)
-
1
]
.
updated
)
>
time
.
Second
{
b
.
buckets
=
append
(
b
.
buckets
,
bucket
{
updated
:
time
.
Now
(),
value
:
value
,
})
if
len
(
b
.
buckets
)
>
b
.
maxBuckets
{
b
.
buckets
=
b
.
buckets
[
1
:
]
}
}
}
func
(
b
*
Bar
)
percent
()
float64
{
...
...
@@ -133,41 +179,37 @@ func (b *Bar) percent() float64 {
return
0
}
func
(
b
*
Bar
)
Stats
()
Stats
{
if
time
.
Since
(
b
.
statted
)
<
time
.
Second
{
return
b
.
stats
}
switch
{
case
b
.
statted
.
IsZero
()
:
b
.
stats
=
Stats
{
value
:
b
.
initialValue
,
rate
:
0
,
remaining
:
0
,
}
case
b
.
currentValue
>=
b
.
maxValue
:
b
.
stats
=
Stats
{
value
:
b
.
maxValue
,
rate
:
0
,
remaining
:
0
,
}
default
:
rate
:=
b
.
currentValue
-
b
.
stats
.
value
var
remaining
time
.
Duration
if
rate
>
0
{
remaining
=
time
.
Second
*
time
.
Duration
((
float64
(
b
.
maxValue
-
b
.
currentValue
))
/
(
float64
(
rate
)))
}
else
{
remaining
=
time
.
Duration
(
math
.
MaxInt64
)
func
(
b
*
Bar
)
rate
()
float64
{
var
numerator
,
denominator
float64
if
!
b
.
stopped
.
IsZero
()
{
numerator
=
float64
(
b
.
currentValue
-
b
.
initialValue
)
denominator
=
b
.
stopped
.
Sub
(
b
.
started
)
.
Round
(
time
.
Second
)
.
Seconds
()
}
else
{
switch
len
(
b
.
buckets
)
{
case
0
:
// noop
case
1
:
numerator
=
float64
(
b
.
buckets
[
0
]
.
value
-
b
.
initialValue
)
denominator
=
b
.
buckets
[
0
]
.
updated
.
Sub
(
b
.
started
)
.
Round
(
time
.
Second
)
.
Seconds
()
default
:
first
,
last
:=
b
.
buckets
[
0
],
b
.
buckets
[
len
(
b
.
buckets
)
-
1
]
numerator
=
float64
(
last
.
value
-
first
.
value
)
denominator
=
last
.
updated
.
Sub
(
first
.
updated
)
.
Round
(
time
.
Second
)
.
Seconds
()
}
}
b
.
stats
=
Stats
{
value
:
b
.
currentValue
,
rate
:
rate
,
remaining
:
remaining
,
}
if
denominator
!=
0
{
return
numerator
/
denominator
}
b
.
statted
=
time
.
Now
()
return
0
}
func
repeat
(
s
string
,
n
int
)
string
{
if
n
>
0
{
return
strings
.
Repeat
(
s
,
n
)
}
return
b
.
stats
return
""
}
progress/spinner.go
View file @
b173cfc5
...
...
@@ -40,8 +40,8 @@ func (s *Spinner) String() string {
}
fmt
.
Fprintf
(
&
sb
,
"%s"
,
message
)
if
s
.
messageWidth
-
sb
.
Len
()
>
=
0
{
sb
.
WriteString
(
strings
.
Repeat
(
" "
,
s
.
messageWidth
-
sb
.
Len
()
))
if
padding
:=
s
.
messageWidth
-
sb
.
Len
()
;
padding
>
0
{
sb
.
WriteString
(
strings
.
Repeat
(
" "
,
padding
))
}
sb
.
WriteString
(
" "
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment