class Metrics::Statistics::ExponentialSample

Constants

RESCALE_WINDOW_SECONDS

Public Class Methods

new(size = 1028, alpha = 0.015) click to toggle source
# File lib/ruby-metrics/statistics/exponential_sample.rb, line 6
def initialize(size = 1028, alpha = 0.015)
  @size   = size
  @alpha  = alpha
  clear
end

Public Instance Methods

clear() click to toggle source
# File lib/ruby-metrics/statistics/exponential_sample.rb, line 12
def clear
  @values           = { }
  @start_time       = tick
  @next_scale_time  = Time.now.to_f + RESCALE_WINDOW_SECONDS
  @count            = 0
end
size() click to toggle source
# File lib/ruby-metrics/statistics/exponential_sample.rb, line 19
def size
  [@values.size, @count].min
end
tick() click to toggle source
# File lib/ruby-metrics/statistics/exponential_sample.rb, line 23
def tick
  Time.now.to_f
end
update(value) click to toggle source
# File lib/ruby-metrics/statistics/exponential_sample.rb, line 27
def update(value)
  update_with_timestamp(value, tick)
end
update_with_timestamp(value, timestamp) click to toggle source
# File lib/ruby-metrics/statistics/exponential_sample.rb, line 31
def update_with_timestamp(value, timestamp)
  priority = weight(timestamp.to_f - @start_time.to_f) / rand
  @count += 1
  if @count <= @size
    @values[priority] = value
  else
    first_key = @values.keys.first
    if first_key && first_key < priority
      @values[priority] = value
      
      while values.any? && @values.delete(first_key).nil?
        first_key = @values.keys.first
      end
    end
  end
  
  now = Time.now.to_f

  if now >= @next_scale_time
    rescale(now + RESCALE_WINDOW_SECONDS)
  end
end
values() click to toggle source
# File lib/ruby-metrics/statistics/exponential_sample.rb, line 54
def values
  # read-lock?
  @values.keys.sort.map do |key|
    @values[key]
  end
end

Private Instance Methods

rescale(next_scale_time) click to toggle source
# File lib/ruby-metrics/statistics/exponential_sample.rb, line 62
def rescale(next_scale_time)
  # writelock
  @next_scale_time = next_scale_time
  old_start_time = @start_time
  @start_time = tick
  time_delta = @start_time - old_start_time
  @values.keys.each do |key|
    value = @values.delete(key)
    new_key = key * Math.exp(-@alpha * time_delta)
    @values[new_key] = value
  end
  # unlock
end
weight(factor) click to toggle source
# File lib/ruby-metrics/statistics/exponential_sample.rb, line 76
def weight(factor)
  @alpha.to_f * factor.to_f
end