rhcf-timeseries 0.0.6 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rhcf/extensions/fixnum.rb +34 -0
- data/lib/rhcf/timeseries/constants.rb +25 -0
- data/lib/rhcf/timeseries/manager.rb +119 -0
- data/lib/rhcf/timeseries/query.rb +69 -0
- data/lib/rhcf/timeseries/redis_strategies.rb +175 -0
- data/lib/rhcf/timeseries/version.rb +1 -1
- data/rhcf-timeseries.gemspec +2 -2
- data/spec/lib/rhcf/timeseries/manager_spec.rb +193 -0
- data/spec/lib/rhcf/timeseries/{result_spec.rb → query_spec.rb} +6 -6
- data/spec/lib/rhcf/timeseries/redis_get_strategy_spec.rb +7 -0
- data/spec/lib/rhcf/timeseries/redis_hgetall_strategy_spec.rb +7 -0
- data/spec/lib/rhcf/timeseries/redis_mget_lua_strategy_spec.rb +7 -0
- data/spec/lib/rhcf/timeseries/redis_mget_strategy_spec.rb +7 -0
- data/spec/spec_helper.rb +1 -2
- data/spec/support/database_cleaner.rb +14 -0
- data/spec/support/simplecov.rb +2 -0
- data/spec/support/valid_strategy_spec.rb +119 -0
- metadata +53 -7
- data/lib/rhcf/timeseries/redis.rb +0 -269
- data/spec/lib/rhcf/timeseries/redis_spec.rb +0 -182
data/spec/spec_helper.rb
CHANGED
@@ -4,8 +4,7 @@
|
|
4
4
|
# loaded once.
|
5
5
|
#
|
6
6
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
-
|
8
|
-
#SimpleCov.start_with?
|
7
|
+
Dir[File.join(File.dirname(__FILE__), "support/**/*.rb")].each {|f| require f}
|
9
8
|
require 'timecop'
|
10
9
|
RSpec.configure do |config|
|
11
10
|
config.run_all_when_everything_filtered = true
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'database_cleaner'
|
2
|
+
RSpec.configure do |config|
|
3
|
+
|
4
|
+
config.before(:suite) do
|
5
|
+
DatabaseCleaner.strategy = :truncation
|
6
|
+
DatabaseCleaner.clean_with(:truncation)
|
7
|
+
end
|
8
|
+
|
9
|
+
config.around(:each) do |example|
|
10
|
+
DatabaseCleaner.cleaning do
|
11
|
+
example.run
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'redis'
|
2
|
+
require 'rhcf/timeseries/manager'
|
3
|
+
RSpec.shared_examples 'a valid strategy' do
|
4
|
+
let(:redis){Redis.new}
|
5
|
+
let(:manager) { Rhcf::Timeseries::Manager.new(connection: redis, strategy: described_class) }
|
6
|
+
let(:start_time){ Time.parse("2000-01-01 00:00:00") }
|
7
|
+
|
8
|
+
before do
|
9
|
+
Timecop.travel(start_time)
|
10
|
+
manager.store("views/product/15", {"web/firefox/3" => 1})
|
11
|
+
|
12
|
+
Timecop.travel(15.minutes) #00:00:15
|
13
|
+
manager.store("views/product/13", {"web/firefox/3" => 1}, Time.now)
|
14
|
+
manager.store("views/product/13", {"web/firefox/3" => 1}, Time.now)
|
15
|
+
manager.store("views/product/13", {"web/firefox/3" => 0}, Time.now)
|
16
|
+
|
17
|
+
Timecop.travel(15.minutes) #00:00:30
|
18
|
+
manager.store("views/product/15", {"web/ie/6" => 3})
|
19
|
+
|
20
|
+
Timecop.travel(15.minutes) #00:00:45
|
21
|
+
manager.store("views/product/15", {"web/ie/6" => 2})
|
22
|
+
|
23
|
+
Timecop.travel(15.minutes) #00:00:00
|
24
|
+
manager.store("views/product/11", {"web/ie/5" => 2})
|
25
|
+
|
26
|
+
Timecop.travel(15.minutes) #00:00:15
|
27
|
+
manager.store("views/product/11", {"web/chrome/11"=> 4})
|
28
|
+
|
29
|
+
Timecop.travel(15.minutes) #00:00:30
|
30
|
+
manager.store("views/product/11", {"web/chrome/11"=> 2})
|
31
|
+
end
|
32
|
+
|
33
|
+
it "is similar to redistat" do
|
34
|
+
|
35
|
+
expect(manager.find("views/product", start_time, start_time + 55.minutes).total(:ever)).to eq({
|
36
|
+
"web" => 16.0,
|
37
|
+
"web/chrome" => 6.0,
|
38
|
+
"web/chrome/11" => 6.0,
|
39
|
+
"web/firefox" => 3.0,
|
40
|
+
"web/firefox/3" => 3.0,
|
41
|
+
"web/ie" => 7.0,
|
42
|
+
"web/ie/5" => 2.0,
|
43
|
+
"web/ie/6" => 5.0
|
44
|
+
})
|
45
|
+
|
46
|
+
expect(manager.find("views/product", start_time, start_time + 55.minutes).total(:year)).to eq({
|
47
|
+
"web" => 16.0,
|
48
|
+
"web/chrome" => 6.0,
|
49
|
+
"web/chrome/11" => 6.0,
|
50
|
+
"web/firefox" => 3.0,
|
51
|
+
"web/firefox/3" => 3.0,
|
52
|
+
"web/ie" => 7.0,
|
53
|
+
"web/ie/5" => 2.0,
|
54
|
+
"web/ie/6" => 5.0
|
55
|
+
})
|
56
|
+
|
57
|
+
expect( manager.find("views/product", start_time, start_time + 55.minutes).total ).to eq({
|
58
|
+
'web' => 8,
|
59
|
+
'web/firefox' => 3,
|
60
|
+
'web/firefox/3' => 3,
|
61
|
+
'web/ie' => 5,
|
62
|
+
'web/ie/6' => 5,
|
63
|
+
})
|
64
|
+
|
65
|
+
expect(manager.find("views/product/15", start_time, start_time + 55.minutes).points(:minute)).to eq([
|
66
|
+
{:moment=>"2000-01-01T00:00", :values=>{"web/firefox"=>1, "web/firefox/3"=>1, "web"=>1}},
|
67
|
+
{:moment=>"2000-01-01T00:30", :values=>{"web"=>3, "web/ie/6"=>3, "web/ie"=>3}},
|
68
|
+
{:moment=>"2000-01-01T00:45", :values=>{"web"=>2, "web/ie/6"=>2, "web/ie"=>2}}
|
69
|
+
])
|
70
|
+
|
71
|
+
expect(manager.find("views/product/13", start_time, start_time + 55.minutes).points(:minute)).to eq([
|
72
|
+
{:moment=>"2000-01-01T00:15", :values=>{"web/firefox"=>2, "web/firefox/3"=>2, "web"=>2}},
|
73
|
+
])
|
74
|
+
|
75
|
+
expect(manager.find("views/product", start_time, start_time + 55.minutes).points(:minute)).to eq([
|
76
|
+
{:moment=>"2000-01-01T00:00", :values=>{"web/firefox"=>1, "web/firefox/3"=>1, "web"=>1}},
|
77
|
+
{:moment=>"2000-01-01T00:15", :values=>{"web/firefox"=>2, "web/firefox/3"=>2, "web"=>2}},
|
78
|
+
{:moment=>"2000-01-01T00:30", :values=>{"web"=>3, "web/ie/6"=>3, "web/ie"=>3}},
|
79
|
+
{:moment=>"2000-01-01T00:45", :values=>{"web"=>2, "web/ie/6"=>2, "web/ie"=>2}}
|
80
|
+
])
|
81
|
+
|
82
|
+
expect(manager.find("views", start_time, start_time + 55.minutes).points(:minute)).to eq([
|
83
|
+
{:moment=>"2000-01-01T00:00", :values=>{"web/firefox"=>1, "web/firefox/3"=>1, "web"=>1}},
|
84
|
+
{:moment=>"2000-01-01T00:15", :values=>{"web/firefox"=>2, "web/firefox/3"=>2, "web"=>2}},
|
85
|
+
{:moment=>"2000-01-01T00:30", :values=>{"web"=>3, "web/ie/6"=>3, "web/ie"=>3}},
|
86
|
+
{:moment=>"2000-01-01T00:45", :values=>{"web"=>2, "web/ie/6"=>2, "web/ie"=>2}}
|
87
|
+
])
|
88
|
+
|
89
|
+
expect(manager.find("views", start_time).points(:hour)).to eq([
|
90
|
+
{
|
91
|
+
:moment=>"2000-01-01T00",
|
92
|
+
:values=> {
|
93
|
+
"web/ie"=>5.0,
|
94
|
+
"web"=>8.0,
|
95
|
+
"web/firefox"=>3.0,
|
96
|
+
"web/ie/6"=>5.0,
|
97
|
+
"web/firefox/3"=>3.0}
|
98
|
+
},{
|
99
|
+
:moment=>"2000-01-01T01",
|
100
|
+
:values=>{
|
101
|
+
"web/ie"=>2.0,
|
102
|
+
"web/chrome"=>6.0,
|
103
|
+
"web/chrome/11"=>6.0,
|
104
|
+
"web"=>8.0,
|
105
|
+
"web/ie/5"=>2.0
|
106
|
+
}
|
107
|
+
}
|
108
|
+
])
|
109
|
+
end
|
110
|
+
|
111
|
+
let(:filter) { Rhcf::Timeseries::Filter.new([:source, :browser], browser: 'firefox.*' )}
|
112
|
+
it "can find with filter" do
|
113
|
+
|
114
|
+
expect(manager.find("views", start_time, start_time + 55.minutes, filter).points(:minute)).to eq([
|
115
|
+
{:moment=>"2000-01-01T00:00", :values=>{"web/firefox"=>1, "web/firefox/3"=>1}},
|
116
|
+
{:moment=>"2000-01-01T00:15", :values=>{"web/firefox"=>2, "web/firefox/3"=>2}},
|
117
|
+
])
|
118
|
+
end
|
119
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rhcf-timeseries
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Romeu Fonseca
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: timecop
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +108,20 @@ dependencies:
|
|
94
108
|
- - ">="
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: database_cleaner
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
97
125
|
description: Gem to allow your system to keep record of time series on rhcf
|
98
126
|
email:
|
99
127
|
- romeu.hcf@gmail.com
|
@@ -110,14 +138,25 @@ files:
|
|
110
138
|
- LICENSE.txt
|
111
139
|
- README.md
|
112
140
|
- Rakefile
|
141
|
+
- lib/rhcf/extensions/fixnum.rb
|
113
142
|
- lib/rhcf/timeseries.rb
|
114
|
-
- lib/rhcf/timeseries/
|
143
|
+
- lib/rhcf/timeseries/constants.rb
|
144
|
+
- lib/rhcf/timeseries/manager.rb
|
145
|
+
- lib/rhcf/timeseries/query.rb
|
146
|
+
- lib/rhcf/timeseries/redis_strategies.rb
|
115
147
|
- lib/rhcf/timeseries/version.rb
|
116
148
|
- rhcf-timeseries.gemspec
|
117
149
|
- spec/lib/rhcf/timeseries/TODO
|
118
|
-
- spec/lib/rhcf/timeseries/
|
119
|
-
- spec/lib/rhcf/timeseries/
|
150
|
+
- spec/lib/rhcf/timeseries/manager_spec.rb
|
151
|
+
- spec/lib/rhcf/timeseries/query_spec.rb
|
152
|
+
- spec/lib/rhcf/timeseries/redis_get_strategy_spec.rb
|
153
|
+
- spec/lib/rhcf/timeseries/redis_hgetall_strategy_spec.rb
|
154
|
+
- spec/lib/rhcf/timeseries/redis_mget_lua_strategy_spec.rb
|
155
|
+
- spec/lib/rhcf/timeseries/redis_mget_strategy_spec.rb
|
120
156
|
- spec/spec_helper.rb
|
157
|
+
- spec/support/database_cleaner.rb
|
158
|
+
- spec/support/simplecov.rb
|
159
|
+
- spec/support/valid_strategy_spec.rb
|
121
160
|
homepage: ''
|
122
161
|
licenses:
|
123
162
|
- MIT
|
@@ -144,6 +183,13 @@ specification_version: 4
|
|
144
183
|
summary: Redistat inspired redis time series.
|
145
184
|
test_files:
|
146
185
|
- spec/lib/rhcf/timeseries/TODO
|
147
|
-
- spec/lib/rhcf/timeseries/
|
148
|
-
- spec/lib/rhcf/timeseries/
|
186
|
+
- spec/lib/rhcf/timeseries/manager_spec.rb
|
187
|
+
- spec/lib/rhcf/timeseries/query_spec.rb
|
188
|
+
- spec/lib/rhcf/timeseries/redis_get_strategy_spec.rb
|
189
|
+
- spec/lib/rhcf/timeseries/redis_hgetall_strategy_spec.rb
|
190
|
+
- spec/lib/rhcf/timeseries/redis_mget_lua_strategy_spec.rb
|
191
|
+
- spec/lib/rhcf/timeseries/redis_mget_strategy_spec.rb
|
149
192
|
- spec/spec_helper.rb
|
193
|
+
- spec/support/database_cleaner.rb
|
194
|
+
- spec/support/simplecov.rb
|
195
|
+
- spec/support/valid_strategy_spec.rb
|
@@ -1,269 +0,0 @@
|
|
1
|
-
require 'date'
|
2
|
-
|
3
|
-
class Fixnum
|
4
|
-
def minutes
|
5
|
-
self * 60
|
6
|
-
end
|
7
|
-
|
8
|
-
def hours
|
9
|
-
self.minutes * 60
|
10
|
-
end
|
11
|
-
|
12
|
-
def days
|
13
|
-
self.hours * 24
|
14
|
-
end
|
15
|
-
|
16
|
-
def seconds
|
17
|
-
self
|
18
|
-
end
|
19
|
-
|
20
|
-
def weeks
|
21
|
-
self.days * 7
|
22
|
-
end
|
23
|
-
|
24
|
-
def years
|
25
|
-
self.days * 365
|
26
|
-
end
|
27
|
-
|
28
|
-
alias_method :day, :days
|
29
|
-
alias_method :week, :weeks
|
30
|
-
alias_method :hour, :hours
|
31
|
-
alias_method :second, :seconds
|
32
|
-
alias_method :minute, :minutes
|
33
|
-
alias_method :year, :years
|
34
|
-
end
|
35
|
-
|
36
|
-
class NilLogger
|
37
|
-
def log(*args)
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
alias_method :warn, :log
|
42
|
-
alias_method :debug, :log
|
43
|
-
alias_method :info, :log
|
44
|
-
alias_method :error, :log
|
45
|
-
end
|
46
|
-
|
47
|
-
module Rhcf
|
48
|
-
module Timeseries
|
49
|
-
|
50
|
-
class Result
|
51
|
-
def initialize(subject, from, to, series)
|
52
|
-
if from > to
|
53
|
-
fail ArgumentError, "Argument 'from' can not be bigger then 'to'"
|
54
|
-
end
|
55
|
-
@series = series
|
56
|
-
@subject = subject
|
57
|
-
@from = from
|
58
|
-
@to = to
|
59
|
-
end
|
60
|
-
|
61
|
-
def total(resolution_id=nil)
|
62
|
-
accumulator={}
|
63
|
-
points(resolution_id || better_resolution[:id]) do |data|
|
64
|
-
data[:values].each do |key, value|
|
65
|
-
accumulator[key]||=0
|
66
|
-
accumulator[key]+=value
|
67
|
-
end
|
68
|
-
end
|
69
|
-
accumulator
|
70
|
-
end
|
71
|
-
|
72
|
-
def points(resolution_id)
|
73
|
-
list =[]
|
74
|
-
|
75
|
-
point_range(resolution_id) do |point|
|
76
|
-
values = {}
|
77
|
-
|
78
|
-
@series.events_for_subject_on(@subject, point, resolution_id).each do |event|
|
79
|
-
value = @series.get('point', @subject, event, resolution_id, point)
|
80
|
-
values[event] = value.to_i
|
81
|
-
end
|
82
|
-
|
83
|
-
next if values.empty?
|
84
|
-
data = {moment: point, values: values }
|
85
|
-
if block_given?
|
86
|
-
yield data
|
87
|
-
else
|
88
|
-
list << data
|
89
|
-
end
|
90
|
-
end
|
91
|
-
list unless block_given?
|
92
|
-
end
|
93
|
-
|
94
|
-
def point_range(resolution_id)
|
95
|
-
resolution = @series.resolution(resolution_id)
|
96
|
-
span = resolution[:span]
|
97
|
-
ptr = @from.dup
|
98
|
-
while ptr < @to
|
99
|
-
point = @series.resolution_value_at(ptr, resolution_id)
|
100
|
-
yield point
|
101
|
-
ptr += span.to_i
|
102
|
-
end
|
103
|
-
rescue FloatDomainError
|
104
|
-
# OK
|
105
|
-
end
|
106
|
-
|
107
|
-
def better_resolution
|
108
|
-
span = @to.to_time - @from.to_time
|
109
|
-
|
110
|
-
resolutions = @series.resolutions.sort_by{|h| h[:span]}.reverse
|
111
|
-
5.downto(1) do |div|
|
112
|
-
res = resolutions.find{|r| r[:span] < span / div }
|
113
|
-
return res if res
|
114
|
-
end
|
115
|
-
return nil
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
|
120
|
-
class Redis
|
121
|
-
|
122
|
-
RESOLUTIONS_MAP={
|
123
|
-
:ever => {span:Float::INFINITY, formatter: "ever", ttl: (2 * 366).days},
|
124
|
-
:year => {span: 365.days,formatter: "%Y", ttl: (2 * 366).days},
|
125
|
-
:week => {span: 1.week, formatter: "%Y-CW%w", ttl: 90.days},
|
126
|
-
:month => {span: 30.days, formatter: "%Y-%m", ttl: 366.days},
|
127
|
-
:day => {span: 1.day, formatter: "%Y-%m-%d", ttl: 30.days},
|
128
|
-
:hour => {span: 1.hour, formatter: "%Y-%m-%dT%H", ttl: 24.hours},
|
129
|
-
:minute => {span: 1.minute, formatter: "%Y-%m-%dT%H:%M", ttl: 120.minutes},
|
130
|
-
:second => {span: 1, formatter: "%Y-%m-%dT%H:%M:%S", ttl: 1.hour},
|
131
|
-
:"5seconds" => {span: 5.seconds, formatter: ->(time){ [time.strftime("%Y-%m-%dT%H:%M:") , time.to_i % 60/5, '*',5].join('') }, ttl: 1.hour},
|
132
|
-
:"5minutes" => {span: 5.minutes, formatter: ->(time){ [time.strftime("%Y-%m-%dT%H:") , (time.to_i/60) % 60/5, '*',5].join('') }, ttl: 3.hour},
|
133
|
-
:"15minutes" => {span: 15.minutes, formatter: ->(time){ [time.strftime("%Y-%m-%dT%H:") , (time.to_i/60) % 60/15, '*',15].join('') }, ttl: 24.hours}
|
134
|
-
|
135
|
-
}
|
136
|
-
DEFAULT_RESOLUTIONS = RESOLUTIONS_MAP.keys
|
137
|
-
NAMESPACE_SEPARATOR = '|'
|
138
|
-
|
139
|
-
attr_reader :logger
|
140
|
-
|
141
|
-
def initialize(logger, redis, options = {})
|
142
|
-
@resolution_ids = options[:resolutions] || DEFAULT_RESOLUTIONS
|
143
|
-
@prefix = options[:prefix] || self.class.name
|
144
|
-
@logger = logger || NilLogger.new
|
145
|
-
@connection_to_use = redis
|
146
|
-
end
|
147
|
-
|
148
|
-
def on_connection(conn)
|
149
|
-
old_connection = @connection_to_use
|
150
|
-
@connection_to_use = conn
|
151
|
-
yield self
|
152
|
-
@connection_to_use = old_connection
|
153
|
-
end
|
154
|
-
|
155
|
-
def redis_connection_to_use
|
156
|
-
@connection_to_use || fail("No redis connection given")
|
157
|
-
end
|
158
|
-
|
159
|
-
def store(subject, event_point_hash, moment = Time.now, descend_subject = true, descend_event = true)
|
160
|
-
resolutions = resolutions_of(moment)
|
161
|
-
|
162
|
-
descend(subject, descend_subject) do |subject_path|
|
163
|
-
event_point_hash.each do |event, point_value|
|
164
|
-
descend(event, descend_event) do |event_path|
|
165
|
-
resolutions.each do |res|
|
166
|
-
resolution_name, resolution_value = *res
|
167
|
-
store_point_value(subject_path, event_path, resolution_name, resolution_value, point_value)
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
def resolutions_of(moment)
|
175
|
-
@resolution_ids.collect do |res_id|
|
176
|
-
[res_id, resolution_value_at(moment, res_id)]
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
def resolution_value_at(moment, res_id)
|
181
|
-
res_config = RESOLUTIONS_MAP[res_id]
|
182
|
-
if res_config.nil?
|
183
|
-
fail "No resolution config for id: #{res_id.class}:#{res_id}"
|
184
|
-
end
|
185
|
-
|
186
|
-
time_resolution_formater = res_config[:formatter]
|
187
|
-
case time_resolution_formater
|
188
|
-
when String
|
189
|
-
moment.strftime(time_resolution_formater)
|
190
|
-
when Proc
|
191
|
-
time_resolution_formater.call(moment)
|
192
|
-
else
|
193
|
-
fail ArgumentError, "Unexpected moment formater type #{time_resolution_formater.class}"
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
def descend(path, do_descend = true , &block)
|
198
|
-
return if path.empty? or path == "."
|
199
|
-
block.call(path)
|
200
|
-
descend(File.dirname(path), do_descend, &block) if do_descend
|
201
|
-
end
|
202
|
-
|
203
|
-
def store_point_event( resolution_name, resolution_value, subject_path, event_path)
|
204
|
-
key = [@prefix, 'event_set', resolution_name, resolution_value, subject_path].join(NAMESPACE_SEPARATOR)
|
205
|
-
logger.debug("EVENTSET SADD #{key} -> #{event_path}")
|
206
|
-
redis_connection_to_use.sadd(key, event_path)
|
207
|
-
end
|
208
|
-
|
209
|
-
def store_point_value( subject_path, event_path, resolution_name, resolution_value, point_value)
|
210
|
-
store_point_event(resolution_name, resolution_value, subject_path, event_path)
|
211
|
-
|
212
|
-
key = [@prefix, 'point' ,subject_path, event_path, resolution_name, resolution_value].join(NAMESPACE_SEPARATOR)
|
213
|
-
logger.debug("SETTING KEY #{key}")
|
214
|
-
redis_connection_to_use.incrby(key, point_value)
|
215
|
-
redis_connection_to_use.expire(key, RESOLUTIONS_MAP[resolution_name][:ttl])
|
216
|
-
end
|
217
|
-
|
218
|
-
def find(subject, from, to = Time.now)
|
219
|
-
Rhcf::Timeseries::Result.new(subject, from, to, self)
|
220
|
-
end
|
221
|
-
|
222
|
-
def flush!
|
223
|
-
every_key{|a_key| delete_key(a_key)}
|
224
|
-
end
|
225
|
-
|
226
|
-
def every_key(pattern=nil, &block)
|
227
|
-
pattern = [@prefix, pattern,'*'].compact.join(NAMESPACE_SEPARATOR)
|
228
|
-
redis_connection_to_use.keys(pattern).each do |key|
|
229
|
-
yield key
|
230
|
-
end
|
231
|
-
end
|
232
|
-
|
233
|
-
def delete_key(a_key)
|
234
|
-
logger.debug("DELETING KEY #{a_key}")
|
235
|
-
redis_connection_to_use.del(a_key)
|
236
|
-
end
|
237
|
-
|
238
|
-
def keys(*a_key)
|
239
|
-
fail "GIVEUP"
|
240
|
-
a_key = [@prefix, a_key].flatten.join(NAMESPACE_SEPARATOR)
|
241
|
-
logger.debug("FINDING KEY #{a_key}")
|
242
|
-
redis_connection_to_use.keys(a_key).collect{|k| k.split(NAMESPACE_SEPARATOR)[1,1000].join(NAMESPACE_SEPARATOR) }
|
243
|
-
end
|
244
|
-
|
245
|
-
def get(*a_key)
|
246
|
-
a_key = [@prefix, a_key].flatten.join(NAMESPACE_SEPARATOR)
|
247
|
-
logger.debug("GETTING KEY #{a_key}")
|
248
|
-
redis_connection_to_use.get(a_key)
|
249
|
-
end
|
250
|
-
|
251
|
-
|
252
|
-
def resolution(id)
|
253
|
-
res = RESOLUTIONS_MAP[id]
|
254
|
-
fail ArgumentError, "Invalid resolution name #{id} for this time series" if res.nil?
|
255
|
-
res.merge(:id => id)
|
256
|
-
end
|
257
|
-
|
258
|
-
def resolutions
|
259
|
-
@_resolutions ||= @resolution_ids.map { |id| resolution(id) }
|
260
|
-
end
|
261
|
-
|
262
|
-
def events_for_subject_on(subject, point, resolution_id)
|
263
|
-
key = [@prefix, 'event_set', resolution_id, point, subject].join(NAMESPACE_SEPARATOR)
|
264
|
-
logger.debug("EVENTSET SMEMBERS #{key}")
|
265
|
-
redis_connection_to_use.smembers(key)
|
266
|
-
end
|
267
|
-
end
|
268
|
-
end
|
269
|
-
end
|