Created
December 3, 2015 04:46
-
-
Save matschaffer/210b1d08112620bb905c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'gsl' | |
require 'time' | |
module Diskalerter | |
class ThresholdEstimator | |
attr_reader :timestamps, :signal, :threshold, :now | |
# timestamps - a list of timestamps in epoch milliseconds | |
# signal - a list of values for the provided timestamps | |
# threshold - the "exhaustion" threshold (e.g., 100 for a percentage signal) | |
def initialize(timestamps, signal, threshold) | |
@timestamps = timestamps | |
@signal = signal | |
@threshold = threshold | |
@now = Time.now.to_i | |
end | |
def alertable? | |
now < intersect && intersect < warning_threshold | |
end | |
def will_intersect? | |
now < intersect && intersect < never | |
end | |
def intersect | |
x_intersect, slope = linear_fit | |
(threshold - x_intersect) / slope | |
end | |
def linear_fit | |
return @linear_fit if @linear_fit | |
timestamps, signal = filtered_data | |
x = GSL::Vector[*timestamps] | |
y = GSL::Vector[*signal] | |
@linear_fit = GSL::Fit.linear(x, y) | |
end | |
def warning_threshold | |
now + one_week | |
end | |
def one_week | |
3600 * 24 * 7 | |
end | |
def five_years | |
one_week * 52 * 5 | |
end | |
def never | |
now + five_years | |
end | |
def intersect_time | |
Time.at(intersect) | |
end | |
def intersect_days | |
(intersect - now) / 24 / 3600 | |
end | |
def intersect_milliseconds | |
(intersect - now) * 1000 | |
end | |
def intersect_time_string | |
if will_intersect? | |
'%s (%0.2f days)' % [intersect_time.iso8601, intersect_days] | |
else | |
'Never' | |
end | |
end | |
private | |
def filtered_data | |
timestamps.map { |t| t / 1000 }.zip(signal).reject { |pair| pair[1].nil? }.transpose | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment