Sha256: be396eb0229ac1201728e5841959e7a9d412e91a5a9d4cc506ba03255d3fc33d

Contents?: true

Size: 1.92 KB

Versions: 2

Compression:

Stored size: 1.92 KB

Contents

require File.expand_path('../../core', __FILE__)

module Drone
  class ExponentiallyDecayingSample
    # 1 hour in ms
    RESCALE_THRESHOLD = (1 * 60 * 60 * 1000).freeze
  
    def initialize(id, reservoir_size, alpha)
      @id = id
      @values = Drone::request_hash("#{@id}:values")
      @count = Drone::request_number("#{@id}:count", 0)
      @start_time = Drone::request_number("#{@id}:start_time", current_time())
      @next_scale_time = Drone::request_number("#{@id}:next_scale_time", current_time() + RESCALE_THRESHOLD)
      
      @alpha = alpha
      @reservoir_size = reservoir_size
    end
  
    def clear
      @values.clear()
      @count.set(0)
      @start_time.set(current_time())
      @next_scale_time.set( current_time() + RESCALE_THRESHOLD )
    end
  
    def size
      count =  @count.get
      (@values.size < count) ? @values.size : count
    end
  
  
    def update(val, time = current_time)
      priority = weight(time - @start_time.get) / rand()
      count = @count.inc
      if count <= @reservoir_size
        @values[priority] = val
      else
        first = @values.keys.min
        if first < priority
          @values[priority] = val
          while @values.delete(first) == nil
            first = @values.keys.min
          end
        end
      end
    
      now = current_time()
      if now >= @next_scale_time.get
        rescale(now)
      end
    end
  
    def values
      @values.keys.sort.inject([]) do |buff, key|
        buff << @values[key]
      end
    end
  
    def rescale(now)
      @next_scale_time.set( current_time() + RESCALE_THRESHOLD )
      new_start = current_time()
      old_start = @start_time.get_and_set(new_start)
    
      @values = Hash[ @values.map{ |k,v|
          [k * Math.exp(-@alpha * (new_start - old_start)), v]
        }]
    
    end
  
  private
  
    def current_time
      Time.now.to_f * 1000
    end
  
    def weight(n)
      Math.exp(@alpha * n)
    end
  
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
drone-1.0.4 lib/drone/utils/exponentially_decaying_sample.rb
drone-1.0.1 lib/drone/utils/exponentially_decaying_sample.rb