Class: Metrics::Statistics::ExponentialSample

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby-metrics/statistics/exponential_sample.rb

Instance Method Summary collapse

Constructor Details

#initialize(size = 1028, alpha = 0.015) ⇒ ExponentialSample

Returns a new instance of ExponentialSample.



4
5
6
7
8
9
10
11
# File 'lib/ruby-metrics/statistics/exponential_sample.rb', line 4

def initialize(size = 1028, alpha = 0.015)
  @values = Hash.new
  @count  = 0
  @size   = size
  @alpha  = alpha
  @rescale_window = 3600  #seconds -- 1 hour
  self.clear
end

Instance Method Details

#clearObject



13
14
15
16
17
18
# File 'lib/ruby-metrics/statistics/exponential_sample.rb', line 13

def clear
  @values           = Hash.new
  @start_time       = tick
  @next_scale_time  = Time.now.to_f + @rescale_window
  @count            = 0
end

#rescale(now, next_scale_time) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/ruby-metrics/statistics/exponential_sample.rb', line 58

def rescale(now, next_scale_time)
  if @next_scale_time == next_scale_time
    # writelock
    @next_scale_time = now + @rescale_window
    old_start_time = @start_time
    @start_time = tick
    time_delta = @start_time - old_start_time
    keys = @values.keys
    keys.each do |key|
      value = @values.delete(key)
      new_key = (key * Math.exp(-@alpha * time_delta))
      @values[new_key] = value
    end
    # unlock
  end  
end

#sizeObject



20
21
22
# File 'lib/ruby-metrics/statistics/exponential_sample.rb', line 20

def size
  [@values.keys.length, @count].min
end

#tickObject



24
25
26
# File 'lib/ruby-metrics/statistics/exponential_sample.rb', line 24

def tick
  Time.now.to_f
end

#update(value) ⇒ Object



28
29
30
# File 'lib/ruby-metrics/statistics/exponential_sample.rb', line 28

def update(value)
  update_with_timestamp(value, tick)
end

#update_with_timestamp(value, timestamp) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/ruby-metrics/statistics/exponential_sample.rb', line 32

def update_with_timestamp(value, timestamp)
  priority = weight(timestamp.to_f - @start_time.to_f) / rand
  @count += 1
  newcount = @count
  if (newcount <= @size)
    @values[priority] = value
  else
    firstkey = @values.keys[0]
    if firstkey && (firstkey < priority)
      @values[priority] = value
      
      while(@values.delete(firstkey) == nil)
        firstkey = @values.keys[0]
      end
    end
  end
  
  now = Time.now.to_f
  next_scale_time = @next_scale_time
  
  if (now >= next_scale_time)
    self.rescale(now, next_scale_time)
  end
end

#valuesObject



79
80
81
82
83
84
85
86
87
88
# File 'lib/ruby-metrics/statistics/exponential_sample.rb', line 79

def values
  # read-lock?
  result = Array.new
  keys = @values.keys.sort
  keys.each do |key|
    result << @values[key]
  end
  
  result
end

#weight(factor) ⇒ Object



75
76
77
# File 'lib/ruby-metrics/statistics/exponential_sample.rb', line 75

def weight(factor)
  return @alpha.to_f * factor.to_f
end