class QuartzTorrent::Rate

Class that keeps track of a rate, for example a download or upload rate. The class is used by calling ‘update’ with samples (numbers) representing the amount of units being measured accrued since the last call, and value returns the rate in units/second.

This is implemented as an exponential moving average. The weight of the current sample is based on an exponention function of the time since the last sample. To reduce CPU usage, when update is called with a new sample the new average is not calculated immediately, but instead the samples are summed until 1 second has elapsed before recalculating the average.

Public Class Methods

new(avgPeriod = 4.0) click to toggle source

Create a new Rate that measures the rate using samples. avgPeriod specifies the duration over which the samples are averaged.

# File lib/quartz_torrent/rate.rb, line 15
def initialize(avgPeriod = 4.0)
  reset
  @avgPeriod = avgPeriod.to_f
end

Public Instance Methods

reset() click to toggle source

Reset the rate to empty.

# File lib/quartz_torrent/rate.rb, line 40
def reset
  @value = nil
  @time = Time.new
  @sum = 0.0
end
update(sample) click to toggle source

Update the rate by passing another sample (number) representing units accrued since the last call to update.

# File lib/quartz_torrent/rate.rb, line 28
def update(sample)
  now = Time.new
  elapsed = now - @time
  @sum += sample
  if elapsed > 1.0
    @value = newValue elapsed, @sum/elapsed
    @time = now
    @sum = 0.0
  end
end
value() click to toggle source

Get the current rate. If there are too few samples, 0 is returned.

# File lib/quartz_torrent/rate.rb, line 21
def value
  update 0
  @value ? @value : 0.0
end

Private Instance Methods

alpha(elapsed) click to toggle source

See en.wikipedia.org/wiki/Moving_average#Application_to_measuring_computer_performance

# File lib/quartz_torrent/rate.rb, line 54
def alpha(elapsed)
  1 - Math.exp(-elapsed/@avgPeriod)
end
newValue(elapsed, sample) click to toggle source
# File lib/quartz_torrent/rate.rb, line 47
def newValue(elapsed, sample)
  return sample if ! @value
  a = alpha elapsed
  a*sample + (1-a)*@value
end