bar.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package progress
  2. import (
  3. "fmt"
  4. "os"
  5. "strings"
  6. "time"
  7. "github.com/jmorganca/ollama/format"
  8. "golang.org/x/term"
  9. )
  10. type Bar struct {
  11. message string
  12. messageWidth int
  13. maxValue int64
  14. initialValue int64
  15. currentValue int64
  16. started time.Time
  17. stopped time.Time
  18. }
  19. func NewBar(message string, maxValue, initialValue int64) *Bar {
  20. return &Bar{
  21. message: message,
  22. messageWidth: -1,
  23. maxValue: maxValue,
  24. initialValue: initialValue,
  25. currentValue: initialValue,
  26. started: time.Now(),
  27. }
  28. }
  29. func (b *Bar) String() string {
  30. termWidth, _, err := term.GetSize(int(os.Stderr.Fd()))
  31. if err != nil {
  32. panic(err)
  33. }
  34. var pre, mid, suf strings.Builder
  35. if b.message != "" {
  36. message := strings.TrimSpace(b.message)
  37. if b.messageWidth > 0 && len(message) > b.messageWidth {
  38. message = message[:b.messageWidth]
  39. }
  40. fmt.Fprintf(&pre, "%s", message)
  41. if b.messageWidth-pre.Len() >= 0 {
  42. pre.WriteString(strings.Repeat(" ", b.messageWidth-pre.Len()))
  43. }
  44. pre.WriteString(" ")
  45. }
  46. fmt.Fprintf(&pre, "%.1f%% ", b.percent())
  47. fmt.Fprintf(&suf, "(%s/%s, %s/s, %s)",
  48. format.HumanBytes(b.currentValue),
  49. format.HumanBytes(b.maxValue),
  50. format.HumanBytes(int64(b.rate())),
  51. b.elapsed())
  52. mid.WriteString("[")
  53. // pad 3 for last = or > and "] "
  54. f := termWidth - pre.Len() - mid.Len() - suf.Len() - 3
  55. n := int(float64(f) * b.percent() / 100)
  56. if n > 0 {
  57. mid.WriteString(strings.Repeat("=", n))
  58. }
  59. if b.currentValue >= b.maxValue {
  60. mid.WriteString("=")
  61. } else {
  62. mid.WriteString(">")
  63. }
  64. if f-n > 0 {
  65. mid.WriteString(strings.Repeat(" ", f-n))
  66. }
  67. mid.WriteString("] ")
  68. return pre.String() + mid.String() + suf.String()
  69. }
  70. func (b *Bar) Set(value int64) {
  71. if value >= b.maxValue {
  72. value = b.maxValue
  73. b.stopped = time.Now()
  74. }
  75. b.currentValue = value
  76. }
  77. func (b *Bar) percent() float64 {
  78. if b.maxValue > 0 {
  79. return float64(b.currentValue) / float64(b.maxValue) * 100
  80. }
  81. return 0
  82. }
  83. func (b *Bar) rate() float64 {
  84. return (float64(b.currentValue) - float64(b.initialValue)) / b.elapsed().Seconds()
  85. }
  86. func (b *Bar) elapsed() time.Duration {
  87. stopped := b.stopped
  88. if stopped.IsZero() {
  89. stopped = time.Now()
  90. }
  91. return stopped.Sub(b.started).Round(time.Second)
  92. }