Module: Overwatch::Collection::Attributes

Included in:
Resource
Defined in:
lib/overwatch/collection/attributes.rb

Instance Method Summary collapse

Instance Method Details

#attribute_keysObject



5
6
7
# File 'lib/overwatch/collection/attributes.rb', line 5

def attribute_keys
  $redis.smembers("overwatch::resource:#{self.id}:attribute_keys").sort
end

#average(attr, options = {}) ⇒ Object



9
10
11
# File 'lib/overwatch/collection/attributes.rb', line 9

def average(attr, options={})
  function(:average, attr, options)
end

#first(attr, options = {}) ⇒ Object



25
26
27
# File 'lib/overwatch/collection/attributes.rb', line 25

def first(attr, options={})
  function(:first, attr, options)
end

#from_dotted_hash(source = self.attribute_keys) ⇒ Object



116
117
118
119
120
121
122
# File 'lib/overwatch/collection/attributes.rb', line 116

def from_dotted_hash(source=self.attribute_keys)
  source.map do |main_value|
    main_value.to_s.split(".").reverse.inject(main_value) do |value, key|
      {key.to_sym => value}
    end
  end
end

#function(func, attr, options = {}) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/overwatch/collection/attributes.rb', line 33

def function(func, attr, options={})
  case func
  when :max
    values_for(attr, options)[:data].max
  when :min
    values_for(attr, options)[:data].min
  when :average
    values = values_for(attr, options)[:data]
    if is_a_number?(values.first)
      values.map!(&:to_f)
      values.inject(:+) / values.size
    else
      values.first
    end
  when :median
    values = values_for(attr, options)[:data].sort
    mid = values.size / 2
    values[mid]
  when :first
    value = $redis.zrangebyscore("resource:#{self.id}:#{attr}", options[:start_at], options[:end_at])[0]
    value.split(":")[1] rescue nil
  when :last 
    value = $redis.zrevrangebyscore("resource:#{self.id}:#{attr}", options[:end_at], options[:start_at])[0]
    value.split(":")[1] rescue nil
  end
end

#is_a_number?(str) ⇒ Boolean

Returns:

  • (Boolean)


86
87
88
# File 'lib/overwatch/collection/attributes.rb', line 86

def is_a_number?(str)
  str.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? false : true
end

#last(attr, options = {}) ⇒ Object



29
30
31
# File 'lib/overwatch/collection/attributes.rb', line 29

def last(attr, options={})
  function(:last, attr, options)
end

#max(attr, options = {}) ⇒ Object



17
18
19
# File 'lib/overwatch/collection/attributes.rb', line 17

def max(attr, options={})
  function(:max, attr, options)
end

#median(attr, options = {}) ⇒ Object



21
22
23
# File 'lib/overwatch/collection/attributes.rb', line 21

def median(attr, options={})
  function(:median, attr, options)
end

#min(attr, options = {}) ⇒ Object



13
14
15
# File 'lib/overwatch/collection/attributes.rb', line 13

def min(attr, options={})
  function(:min, attr, options)
end

#sub_attributes(sub_attr) ⇒ Object



131
132
133
# File 'lib/overwatch/collection/attributes.rb', line 131

def sub_attributes(sub_attr)
  self.attribute_keys.select {|k| k =~ /^#{sub_attr}/ }
end

#top_level_attributesObject



125
126
127
128
129
# File 'lib/overwatch/collection/attributes.rb', line 125

def top_level_attributes
  self.attribute_keys.map do |key|
    key.split(".")[0]
  end.uniq
end

#values_for(attr, options = {}) ⇒ Object

Raises:

  • (ArgumentError)


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/overwatch/collection/attributes.rb', line 60

def values_for(attr, options={})
  raise ArgumentError, "attribute does not exist" unless attribute_keys.include?(attr)
  start_at = options[:start_at] ||  "-inf" #(Time.now - 1.day).to_i.to_s
  end_at = options[:end_at] || "+inf"
  interval = options[:interval]
  values = $redis.zrangebyscore("overwatch::resource:#{self.id}:#{attr}", start_at, end_at)
  values.map! do |v|
    val = v.split(":")[1]
    is_a_number?(val) ? val.to_f : val
  end
  values.compact!
  values = case interval
  when 'hour'
    values
  when 'day'
    values.each_slice(60).map { |s| s[0] }
  when 'week'
    values.each_slice(100).map { |s| s[0] }
  when 'month'
    values.each_slice(432).map { |s| s[0] }
  else
    values
  end
  { :name => attr, :data => values }#, :start_at => start_at, :end_at => end_at }
end

#values_with_dates_for(attr, options = {}) ⇒ Object

Raises:

  • (ArgumentError)


90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/overwatch/collection/attributes.rb', line 90

def values_with_dates_for(attr, options={})
  raise ArgumentError, "attribute does not exist" unless attribute_keys.include?(attr)
  start_at = options[:start_at] || "-inf"
  end_at = options[:end_at] || "+inf"
  interval = options[:interval]
  values = $redis.zrangebyscore("overwatch::resource:#{self.id}:#{attr}", start_at, end_at)
  values.map! do |v|
    val = v.split(":")
    [ val[0].to_i * 1000, is_a_number?(val[1]) ? val[1].to_f : val[1] ]
  end
  values.compact!
  values = case interval
  when 'hour'
    values
  when 'day'
    values.each_slice(60).map { |s| s[0] }
  when 'week'
    values.each_slice(100).map { |s| s[0] }
  when 'month'
    values.each_slice(432).map { |s| s[0] }
  else
    values
  end
  { :name => attr, :data => values } #, :start_at => start_at, :end_at => end_at }
end