Class: Log::ProgressBar

Inherits:
Object
  • Object
show all
Defined in:
lib/rbbt/util/log/progress.rb,
lib/rbbt/util/log/progress/util.rb,
lib/rbbt/util/log/progress/report.rb

Constant Summary collapse

BAR_MUTEX =
Mutex.new
BARS =
[]
REMOVE =
[]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(max = nil, options = {}) ⇒ ProgressBar

Returns a new instance of ProgressBar.



8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/rbbt/util/log/progress.rb', line 8

def initialize(max = nil, options = {})
  options = Misc.add_defaults options, :depth => 0, :num_reports => 100, :desc => "Progress", :io => STDERR, :severity => Log.severity
  depth, num_reports, desc, io, severity = Misc.process_options options, :depth, :num_reports, :desc, :io, :severity

  @max = max
  @ticks = 0
  @frequency = 2
  @last_time = nil
  @last_count = nil
  @last_percent = nil
  @depth = depth
  @desc = desc
end

Instance Attribute Details

#depthObject

Returns the value of attribute depth.



7
8
9
# File 'lib/rbbt/util/log/progress.rb', line 7

def depth
  @depth
end

#descObject

Returns the value of attribute desc.



7
8
9
# File 'lib/rbbt/util/log/progress.rb', line 7

def desc
  @desc
end

#frequencyObject

Returns the value of attribute frequency.



7
8
9
# File 'lib/rbbt/util/log/progress.rb', line 7

def frequency
  @frequency
end

#historyObject

Returns the value of attribute history.



20
21
22
# File 'lib/rbbt/util/log/progress/report.rb', line 20

def history
  @history
end

#maxObject

Returns the value of attribute max.



7
8
9
# File 'lib/rbbt/util/log/progress.rb', line 7

def max
  @max
end

#mean_maxObject

Returns the value of attribute mean_max.



20
21
22
# File 'lib/rbbt/util/log/progress/report.rb', line 20

def mean_max
  @mean_max
end

#ticksObject

Returns the value of attribute ticks.



7
8
9
# File 'lib/rbbt/util/log/progress.rb', line 7

def ticks
  @ticks
end

Class Method Details

.cleanup_barsObject



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/rbbt/util/log/progress/util.rb', line 17

def self.cleanup_bars
  BAR_MUTEX.synchronize do
    REMOVE.each do |bar|
      index = BARS.index bar
      if index
        BARS.delete_at index
        BARS.each_with_index do |bar,i|
          bar.depth = i
        end
      end
    end
    REMOVE.clear
    BARS.length
  end
end

.new_bar(max, options = {}) ⇒ Object



7
8
9
10
11
12
13
14
15
# File 'lib/rbbt/util/log/progress/util.rb', line 7

def self.new_bar(max, options = {})
  cleanup_bars
  BAR_MUTEX.synchronize do
    Log::LAST.replace "new_bar" if Log::LAST == "progress"
    options = Misc.add_defaults options, :depth => BARS.length
    BARS << (bar = ProgressBar.new(max, options))
    bar
  end
end

.remove_bar(bar) ⇒ Object



33
34
35
36
37
38
# File 'lib/rbbt/util/log/progress/util.rb', line 33

def self.remove_bar(bar)
  bar.done if bar.respond_to? :done
  BAR_MUTEX.synchronize do
    REMOVE << bar
  end
end

.with_bar(max, options = {}) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
# File 'lib/rbbt/util/log/progress/util.rb', line 40

def self.with_bar(max, options = {})
  bar = new_bar(max, options)
  begin
    yield bar
    keep = false
  rescue KeepBar
    keep = true
  ensure
    remove_bar(bar) if bar
  end
end

Instance Method Details

#done(io = STDERR) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/rbbt/util/log/progress/report.rb', line 111

def done(io = STDERR)
  done_msg = Log.color(:magenta, desc) << " " << Log.color(:green, "done")
  if @start
    ellapsed = (Time.now - @start).to_i
  else
    ellapsed = 0
  end
  ellapsed = [ellapsed/3600, ellapsed/60 % 60, ellapsed % 60].map{|t| "%02i" % t }.join(':')
  done_msg << " " << Log.color(:blue, (@ticks).to_s) << " in " << Log.color(:green, ellapsed)
  @last_count = 0
  @last_time = @start
  done_msg << " (" << thr_msg << ")"
  print(io, up_lines(@depth) << done_msg << down_lines(@depth)) 
end

#down_lines(depth) ⇒ Object



7
8
9
# File 'lib/rbbt/util/log/progress/report.rb', line 7

def down_lines(depth)
  "\n\033[#{depth + 2}E"
end

#eta_msgObject



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/rbbt/util/log/progress/report.rb', line 51

def eta_msg
  percent = self.percent
  time = Time.now

  indicator = ""
  10.times{|i|
    if i < percent / 10 then
      indicator << Log.color(:yellow, ".")
    else
      indicator << " "
    end
  }

  indicator << " #{Log.color(:blue, percent.to_s << "%")}"

  used = time - @start
  if @mean_max and @mean_max > 0
    eta =  (@max - @ticks) / @mean
  else
    eta =  (@max - @ticks) / (@ticks/used)
  end

  used = Misc.format_seconds(used) 
  eta = [eta/3600, eta/60 % 60, eta % 60].map{|t| "%02i" % t }.join(':')

  indicator << " #{Log.color :yellow, used} used #{Log.color :yellow, eta} left"

  indicator
end

#percentObject



22
23
24
# File 'lib/rbbt/util/log/progress.rb', line 22

def percent
  (@ticks * 100) / @max
end


11
12
13
14
15
16
17
18
# File 'lib/rbbt/util/log/progress/report.rb', line 11

def print(io, str)
  return if ENV["RBBT_NO_PROGRESS"] == "true"
  LOG_MUTEX.synchronize do
    STDERR.print str
    Log.logfile.puts str unless Log.logfile.nil?
    Log::LAST.replace "progress"
  end
end

#report(io = STDERR) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/rbbt/util/log/progress/report.rb', line 93

def report(io = STDERR)
  if Log::LAST != "progress"
    length = Log::ProgressBar.cleanup_bars
    bars = BARS
    print(io, Log.color(:yellow, "...Progress\n"))
    bars.sort_by{|b| b.depth }.reverse.each do |bar|
      print(io, Log.color(:yellow ,bar.report_msg) << "\n")
    end
  else
    bars = BARS
  end
  print(io, up_lines(bars.length) << Log.color(:yellow, "...Progress\n") << down_lines(bars.length)) 
  print(io, up_lines(@depth) << report_msg << down_lines(@depth)) 
  @last_time = Time.now
  @last_count = ticks
  @last_percent = percent if max
end

#report_msgObject



81
82
83
84
85
86
87
88
89
90
91
# File 'lib/rbbt/util/log/progress/report.rb', line 81

def report_msg
  str = Log.color :magenta, desc
  return str << " " << Log.color(:yellow, "waiting") if @ticks == 0
  str << " " << thr_msg
  if max
    str << Log.color(:blue, " -- ") << eta_msg 
  else
    str << Log.color(:blue, " -- ") << ticks.to_s
  end
  str
end

#thrObject



21
22
23
24
25
26
27
28
29
# File 'lib/rbbt/util/log/progress/report.rb', line 21

def thr
  count = @ticks - @last_count
  if @last_time.nil?
    seconds = 0.001
  else
    seconds = Time.now - @last_time
  end
  thr = count / seconds
end

#thr_msgObject



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/rbbt/util/log/progress/report.rb', line 31

def thr_msg
  thr = self.thr
  if @history.nil?
    @history ||= []
  else
    @history << thr
    @history.shift if @history.length > 20
  end

  @mean_max ||= 0
  if @history.length > 3
    mean = @mean = Misc.mean(@history)
    @mean_max = mean if mean > @mean_max
  end

  str = "#{ Log.color :blue, thr.to_i.to_s } per sec."
  str << " #{ Log.color :yellow, mean.to_i.to_s } avg. #{Log.color :yellow, @mean_max.to_i.to_s} max." if @mean_max > 0
  str
end

#tick(step = nil) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/rbbt/util/log/progress.rb', line 26

def tick(step = nil)
  return if ENV["RBBT_NO_PROGRESS"] == "true"
  @ticks += 1

  time = Time.now
  if @last_time.nil?
    @last_time = time
    @last_count = @ticks
    @start = time
    return
  end

  diff = time - @last_time
  report and return if diff > @frequency
  return unless max

  percent = self.percent
  if @last_percent.nil?
    @last_percent = percent
    return
  end
  report and return if percent > @last_percent and diff > 0.3
end

#up_lines(depth) ⇒ Object



3
4
5
# File 'lib/rbbt/util/log/progress/report.rb', line 3

def up_lines(depth)
  "\033[#{depth + 1}F\033[2K"
end