rhcf-timeseries 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 43ad07821290e60cc41c8741c44ef2f2e5b7769d
|
4
|
+
data.tar.gz: dae3053f370a61499301acfe5b841156ace2bc3a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42b5890b40e7084f54987deac6f52050c65bd01191edc2730346703962489e41468b93700113d96d7f219995374cde592c49957b56a1c22d2d40dfcb6087eea6
|
7
|
+
data.tar.gz: 2671b695bd0edb1d1b8e077d77dde591b3d16f31455c7315024fd0f9495740f2a54bf7e58202f381996d72693d84fb820f4facfea72e0d0dc6f50c817885c766
|
@@ -98,8 +98,8 @@ module Rhcf
|
|
98
98
|
@strategy.store_point_value(self, subject_path, resolution_name, resolution_value, point_value, event_path)
|
99
99
|
end
|
100
100
|
|
101
|
-
def find(subject, from, to = Time.now, filter = nil)
|
102
|
-
Rhcf::Timeseries::Query.new(subject, from, to, self, filter)
|
101
|
+
def find(subject, from, to = Time.now, filter = nil, limit = 1000)
|
102
|
+
Rhcf::Timeseries::Query.new(subject, from, to, self, filter, limit)
|
103
103
|
end
|
104
104
|
|
105
105
|
def resolution(id)
|
@@ -112,8 +112,8 @@ module Rhcf
|
|
112
112
|
@_resolutions ||= @resolution_ids.map { |id| resolution(id) }
|
113
113
|
end
|
114
114
|
|
115
|
-
def crunch_values(subject, resolution_id, point, filter)
|
116
|
-
@strategy.crunch_values(self, subject, resolution_id, point, filter)
|
115
|
+
def crunch_values(subject, resolution_id, point, filter, limit = 1000)
|
116
|
+
@strategy.crunch_values(self, subject, resolution_id, point, filter, limit)
|
117
117
|
end
|
118
118
|
end
|
119
119
|
end
|
@@ -1,14 +1,16 @@
|
|
1
1
|
module Rhcf
|
2
2
|
module Timeseries
|
3
3
|
class Query
|
4
|
-
def initialize(subject, from, to, series, filter = nil)
|
5
|
-
|
4
|
+
def initialize(subject, from, to, series, filter = nil, limit = 1000)
|
5
|
+
from, to = to, from if from > to
|
6
|
+
|
6
7
|
@series = series
|
7
8
|
@subject = subject
|
8
9
|
@from = from
|
9
10
|
@to = to
|
10
11
|
|
11
12
|
@filter = filter
|
13
|
+
@limit = limit
|
12
14
|
end
|
13
15
|
|
14
16
|
def total(resolution_id=nil)
|
@@ -28,7 +30,7 @@ module Rhcf
|
|
28
30
|
|
29
31
|
point_range(resolution_id) do |point|
|
30
32
|
|
31
|
-
values = @series.crunch_values(@subject, resolution_id, point, @filter)
|
33
|
+
values = @series.crunch_values(@subject, resolution_id, point, @filter, @limit)
|
32
34
|
|
33
35
|
next if values.empty?
|
34
36
|
data = {moment: point, values: values }
|
@@ -5,7 +5,7 @@ module Rhcf
|
|
5
5
|
'H'
|
6
6
|
end
|
7
7
|
|
8
|
-
def crunch_values(manager, subject, resolution_id, point, filter)
|
8
|
+
def crunch_values(manager, subject, resolution_id, point, filter, limit = 100)
|
9
9
|
values = hgetall(manager, EVENT_POINT_TOKEN, subject, resolution_id, point)
|
10
10
|
values.reject!{|event, value| !filter.match?(event) } if filter
|
11
11
|
values
|
@@ -56,7 +56,7 @@ module Rhcf
|
|
56
56
|
'M'
|
57
57
|
end
|
58
58
|
|
59
|
-
def crunch_values(manager, subject, resolution_id, point, filter)
|
59
|
+
def crunch_values(manager, subject, resolution_id, point, filter, limit = 100)
|
60
60
|
events = events_for_subject_on(manager, subject, point, resolution_id, filter)
|
61
61
|
mget(manager, EVENT_POINT_TOKEN, subject, resolution_id, point, events)
|
62
62
|
end
|
@@ -87,20 +87,25 @@ module Rhcf
|
|
87
87
|
events
|
88
88
|
end
|
89
89
|
|
90
|
-
def crunch_values(manager, subject, resolution_id, point, filter)
|
90
|
+
def crunch_values(manager, subject, resolution_id, point, filter, limit = 1000)
|
91
91
|
register_lua_scripts!(manager.connection_to_use)
|
92
92
|
point_prefix = [manager.prefix, EVENT_POINT_TOKEN, subject, resolution_id, point].join(NAMESPACE_SEPARATOR)
|
93
93
|
set_key = [manager.prefix, EVENT_SET_TOKEN, resolution_id, point, subject].join(NAMESPACE_SEPARATOR)
|
94
94
|
|
95
95
|
data = manager.connection_to_use.evalsha(evalsha_for(:mget_matching_smembers),
|
96
|
-
keys: [set_key], argv: [point_prefix, filter && filter.to_lua_pattern])
|
96
|
+
keys: [set_key], argv: [point_prefix, filter && filter.to_lua_pattern, limit])
|
97
97
|
|
98
98
|
return {} if data.nil?
|
99
99
|
result = {}
|
100
|
+
begin
|
100
101
|
data.first.each_with_index do |evt, idx|
|
101
102
|
value = data.last[idx].to_i
|
102
103
|
result[evt] = value
|
103
104
|
end
|
105
|
+
rescue
|
106
|
+
p $!, $!.message
|
107
|
+
raise
|
108
|
+
end
|
104
109
|
|
105
110
|
result
|
106
111
|
end
|
@@ -110,6 +115,7 @@ module Rhcf
|
|
110
115
|
end
|
111
116
|
|
112
117
|
def register_lua_scripts!(connection)
|
118
|
+
|
113
119
|
@lua_script_register ||=
|
114
120
|
begin
|
115
121
|
smembers_matching = <<-EOF
|
@@ -123,13 +129,73 @@ module Rhcf
|
|
123
129
|
EOF
|
124
130
|
|
125
131
|
mget_matching_smembers = <<-EOF
|
126
|
-
local matches = {}
|
127
132
|
local set_key = KEYS[1]
|
128
133
|
local key_prefix = ARGV[1]
|
129
134
|
local filter_pattern = ARGV[2]
|
135
|
+
local limit = tonumber(ARGV[3])
|
130
136
|
local keys = {}
|
131
137
|
local keys_to_mget = {}
|
132
138
|
|
139
|
+
local function log(msg)
|
140
|
+
-- redis.call('publish', 'log', msg)
|
141
|
+
end
|
142
|
+
|
143
|
+
local function mget_in_batches(keys_to_mget)
|
144
|
+
local step = 1024
|
145
|
+
local results = {}
|
146
|
+
local last_end = 0
|
147
|
+
local partial = {}
|
148
|
+
|
149
|
+
local function mget_batch(ini , fin)
|
150
|
+
log("Getting from " .. ini .. ' to ' .. fin .. ' on a total of ' .. #keys_to_mget)
|
151
|
+
partial = redis.call('MGET', unpack(keys_to_mget, ini, fin))
|
152
|
+
for _, value in pairs(partial) do table.insert(results, value) end
|
153
|
+
end
|
154
|
+
|
155
|
+
for ending = step, #keys_to_mget, step do
|
156
|
+
mget_batch(last_end + 1, ending)
|
157
|
+
last_end = ending
|
158
|
+
end
|
159
|
+
|
160
|
+
if last_end < #keys_to_mget then
|
161
|
+
mget_batch(last_end + 1, #keys_to_mget)
|
162
|
+
end
|
163
|
+
|
164
|
+
return results;
|
165
|
+
end
|
166
|
+
|
167
|
+
local function sort_and_limit_tuples(subjects, values)
|
168
|
+
local dictionary = {}
|
169
|
+
for i, subject in pairs(subjects) do
|
170
|
+
local value = values[i] or 0
|
171
|
+
-- redis.call('publish', 'log', subject .. ' += ' .. value)
|
172
|
+
dictionary[subject] = (dictionary[subject] or 0) + value
|
173
|
+
end
|
174
|
+
|
175
|
+
local tuples = {}
|
176
|
+
for subject, value in pairs(dictionary) do
|
177
|
+
-- redis.call('publish', 'log', subject .. ' = ' .. value)
|
178
|
+
table.insert(tuples, { subject, value } )
|
179
|
+
end
|
180
|
+
|
181
|
+
table.sort(tuples, function(a, b) return b[2] < a[2] end )
|
182
|
+
|
183
|
+
local new_subjects = {}
|
184
|
+
local new_counts = {}
|
185
|
+
|
186
|
+
for i, tuple in pairs(tuples) do
|
187
|
+
if #new_subjects >= limit then break end
|
188
|
+
|
189
|
+
local subject = tuple[1]
|
190
|
+
local value = tuple[2]
|
191
|
+
|
192
|
+
table.insert(new_subjects, subject)
|
193
|
+
table.insert(new_counts, value)
|
194
|
+
end
|
195
|
+
|
196
|
+
return {new_subjects, new_counts}
|
197
|
+
end
|
198
|
+
|
133
199
|
for _, val in ipairs(redis.call('smembers', set_key)) do
|
134
200
|
if (filter_pattern and string.match(val, filter_pattern)) or not filter_pattern then
|
135
201
|
table.insert(keys, val)
|
@@ -138,9 +204,13 @@ module Rhcf
|
|
138
204
|
end
|
139
205
|
|
140
206
|
if table.getn(keys) > 0 then
|
141
|
-
|
207
|
+
local values = mget_in_batches(keys_to_mget)
|
208
|
+
local sorted = sort_and_limit_tuples(keys, values)
|
209
|
+
log ("Values card " .. #values .. " | keys card: " .. #keys)
|
210
|
+
return sorted
|
211
|
+
else
|
212
|
+
return {{},{}}
|
142
213
|
end
|
143
|
-
return {{},{}}
|
144
214
|
EOF
|
145
215
|
|
146
216
|
{
|
@@ -156,7 +226,7 @@ module Rhcf
|
|
156
226
|
'G'
|
157
227
|
end
|
158
228
|
|
159
|
-
def crunch_values(manager, subject, resolution_id, point, filter)
|
229
|
+
def crunch_values(manager, subject, resolution_id, point, filter, limit = 100)
|
160
230
|
events = events_for_subject_on(manager, subject, point, resolution_id, filter)
|
161
231
|
values = {}
|
162
232
|
events.each do |event|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,19 +1,7 @@
|
|
1
|
-
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
-
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
-
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
-
# loaded once.
|
5
|
-
#
|
6
|
-
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
1
|
Dir[File.join(File.dirname(__FILE__), "support/**/*.rb")].each {|f| require f}
|
8
2
|
require 'timecop'
|
9
3
|
RSpec.configure do |config|
|
10
4
|
config.run_all_when_everything_filtered = true
|
11
5
|
config.filter_run :focus
|
12
|
-
|
13
|
-
# Run specs in random order to surface order dependencies. If you find an
|
14
|
-
# order dependency and want to debug it, you can fix the order by providing
|
15
|
-
# the seed, which is printed after each run.
|
16
|
-
# --seed 1234
|
17
6
|
config.order = 'random'
|
18
|
-
|
19
7
|
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: 1.0.
|
4
|
+
version: 1.0.3
|
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-
|
11
|
+
date: 2015-06-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|