time_series 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module Time_Series
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,311 @@
1
+ #!/usr/bin/ruby
2
+ # http://mattsears.com/articles/2011/12/10/minitest-quick-reference
3
+
4
+ require 'bundler/setup'
5
+ require 'redis'
6
+ require_relative "../lib/time_series"
7
+
8
+ require "minitest/autorun"
9
+ require 'minitest/pride'
10
+
11
+ require 'active_support/core_ext/numeric/time.rb'
12
+ require 'active_support/core_ext/date/calculations.rb'
13
+
14
+ describe "TimeSeries" do
15
+
16
+ before do
17
+ $app_prefix="test"
18
+ @redis ||= Redis.new(:path => "/tmp/redis.sock")
19
+ @redis.keys("test:*").each{|k| @redis.del k}
20
+ end
21
+
22
+ after do
23
+ @redis.keys("test:*").each{|k| @redis.del k}
24
+ end
25
+
26
+ it "can separate older items from an array" do
27
+ ts = TimeSeries.new("test_ts")
28
+ array = Array.new
29
+ # create 7 days
30
+ (0..6).each do |i|
31
+ array << ts.time_to_key(Time.now - i.days)
32
+ end
33
+
34
+ ts.array_older_than(array, 3.days).must_be_instance_of Array
35
+ ts.array_older_than(array, 3.days).size.must_equal 4
36
+
37
+ end
38
+
39
+ it "can separate seconds, minutes,hours,... keys" do
40
+ ts = TimeSeries.new("test_ts")
41
+
42
+ # all methods must return empty arrays
43
+ ts.seconds.must_be_instance_of Array
44
+ ts.minutes.must_be_instance_of Array
45
+ ts.hours.must_be_instance_of Array
46
+ ts.days.must_be_instance_of Array
47
+ ts.months.must_be_instance_of Array
48
+ ts.years.must_be_instance_of Array
49
+
50
+ # all arrays are empty
51
+ ts.seconds.size.must_equal 0
52
+ ts.minutes.size.must_equal 0
53
+ ts.hours.size.must_equal 0
54
+ ts.days.size.must_equal 0
55
+ ts.months.size.must_equal 0
56
+ ts.years.size.must_equal 0
57
+
58
+ # seconds
59
+ @redis.zincrby "test:ts:test_ts:1986:12:30:23:59:01", 1, "one"
60
+ @redis.zincrby "test:ts:test_ts:1986:12:30:23:59:02", 1, "one"
61
+ @redis.zincrby "test:ts:test_ts:1986:12:30:23:59:03", 1, "one"
62
+ ts.seconds.size.must_equal 3
63
+
64
+ # minutes
65
+ @redis.zincrby "test:ts:test_ts:1986:12:30:23:59", 1, "one"
66
+ @redis.zincrby "test:ts:test_ts:1986:12:30:23:58", 1, "one"
67
+ @redis.zincrby "test:ts:test_ts:1986:12:30:23:57", 1, "one"
68
+ @redis.zincrby "test:ts:test_ts:1986:12:30:23:56", 1, "one"
69
+ ts.minutes.size.must_equal 4
70
+
71
+ # hours
72
+ @redis.zincrby "test:ts:test_ts:1986:12:30:23", 1, "one"
73
+ @redis.zincrby "test:ts:test_ts:1986:12:30:22", 1, "one"
74
+ @redis.zincrby "test:ts:test_ts:1986:12:30:21", 1, "one"
75
+ @redis.zincrby "test:ts:test_ts:1986:12:30:20", 1, "one"
76
+ @redis.zincrby "test:ts:test_ts:1986:12:30:19", 1, "one"
77
+ ts.hours.size.must_equal 5
78
+
79
+ # days
80
+ @redis.zincrby "test:ts:test_ts:1986:12:30", 1, "one"
81
+ @redis.zincrby "test:ts:test_ts:1986:12:29", 1, "one"
82
+ @redis.zincrby "test:ts:test_ts:1986:12:28", 1, "one"
83
+ @redis.zincrby "test:ts:test_ts:1986:12:27", 1, "one"
84
+ @redis.zincrby "test:ts:test_ts:1986:12:26", 1, "one"
85
+ @redis.zincrby "test:ts:test_ts:1986:12:25", 1, "one"
86
+ ts.days.size.must_equal 6
87
+
88
+ # months
89
+ @redis.zincrby "test:ts:test_ts:1986:12", 1, "one"
90
+ @redis.zincrby "test:ts:test_ts:1986:11", 1, "one"
91
+ @redis.zincrby "test:ts:test_ts:1986:10", 1, "one"
92
+ @redis.zincrby "test:ts:test_ts:1986:09", 1, "one"
93
+ @redis.zincrby "test:ts:test_ts:1986:08", 1, "one"
94
+ @redis.zincrby "test:ts:test_ts:1986:07", 1, "one"
95
+ @redis.zincrby "test:ts:test_ts:1986:06", 1, "one"
96
+ ts.months.size.must_equal 7
97
+
98
+ # years
99
+ @redis.zincrby "test:ts:test_ts:1986", 1, "one"
100
+ @redis.zincrby "test:ts:test_ts:1985", 1, "one"
101
+ @redis.zincrby "test:ts:test_ts:1984", 1, "one"
102
+ @redis.zincrby "test:ts:test_ts:1983", 1, "one"
103
+ @redis.zincrby "test:ts:test_ts:1982", 1, "one"
104
+ @redis.zincrby "test:ts:test_ts:1981", 1, "one"
105
+ @redis.zincrby "test:ts:test_ts:1980", 1, "one"
106
+ @redis.zincrby "test:ts:test_ts:1979", 1, "one"
107
+ ts.years.size.must_equal 8
108
+
109
+ # check everything is still as expected
110
+ ts.seconds.size.must_equal 3
111
+ ts.minutes.size.must_equal 4
112
+ ts.hours.size.must_equal 5
113
+ ts.days.size.must_equal 6
114
+ ts.months.size.must_equal 7
115
+
116
+ # make some keys volatile, volatile keys are not included
117
+ @redis.expire "test:ts:test_ts:1986:12:30:23:59:01", 10
118
+ @redis.expire "test:ts:test_ts:1986:12:30:23:59", 10
119
+ @redis.expire "test:ts:test_ts:1986:12:30:23", 10
120
+ @redis.expire "test:ts:test_ts:1986:12:30", 10
121
+ @redis.expire "test:ts:test_ts:1986:12", 10
122
+ @redis.expire "test:ts:test_ts:1986", 10
123
+
124
+ ts.seconds.size.must_equal 2
125
+ ts.minutes.size.must_equal 3
126
+ ts.hours.size.must_equal 4
127
+ ts.days.size.must_equal 5
128
+ ts.months.size.must_equal 6
129
+ ts.years.size.must_equal 7
130
+
131
+ end
132
+
133
+
134
+ it "can separate seconds, minutes,hours,... keys OLDER THAN" do
135
+ ts = TimeSeries.new("test_ts")
136
+
137
+ # create 7 seconds one day apart
138
+ (0..6).each do |i|
139
+ @redis.zincrby ts.time_to_key(Time.now - i.days), 1, "one"
140
+ end
141
+ ts.seconds(3.days).size.must_equal 4
142
+
143
+ # create 10 hours
144
+ (0..9).each do |i|
145
+ @redis.zincrby ts.time_to_key(Time.now - i.days).parent.parent, 1, "one"
146
+ end
147
+ ts.hours(1.hours).size.must_equal 9
148
+
149
+ # create 3 days
150
+ (0..2).each do |i|
151
+ @redis.zincrby ts.time_to_key(Time.now - i.days).parent.parent.parent, 1, "one"
152
+ end
153
+ ts.days(1.days).size.must_equal 2
154
+
155
+ end
156
+
157
+ it "can compress non recent seconds to minutes to hours" do
158
+ ts = TimeSeries.new("test_ts")
159
+
160
+ # create 10 seconds 30 seconds apart
161
+ (0..9).each do |i|
162
+ @redis.zincrby ts.time_to_key(Time.local(2000, 7, 31) - 30*i.seconds), 1, "one"
163
+ end
164
+
165
+ ts.keys.size.must_equal 10
166
+ ts.compress(ts.seconds).must_equal 10 # 10 seconds must be compressed
167
+ ts.keys.size.wont_equal 10
168
+ minutes_num = ts.keys.size
169
+ ts.keys.each { |k| k.minute?.must_equal true} # all keys must be minute keys
170
+ ts.compress(ts.minutes).must_equal minutes_num # all must be compressed
171
+ ts.keys.each { |k| k.hour?.must_equal true} # all keys must be hour keys
172
+ end
173
+
174
+ it "can compress non recent hours to days to months" do
175
+ ts = TimeSeries.new("test_ts")
176
+ # create 10 hours 6 hours apart
177
+ (0..9).each do |i|
178
+ @redis.zincrby ts.time_to_key(Time.local(2000, 7, 31) - 6*i.hours).parent.parent, 1, "one"
179
+ end
180
+
181
+ # create 10 minutes 6 hours apart on the year 2001
182
+ (0..9).each do |i|
183
+ @redis.zincrby ts.time_to_key(Time.local(2001, 7, 31) - 6*i.hours).parent, 1, "one"
184
+ end
185
+
186
+ ts.compress(ts.minutes).must_equal 10
187
+ ts.keys.each { |k| k.hour?.must_equal true} # all keys must be hour keys
188
+ ts.compress(ts.hours).must_equal 20
189
+ ts.keys.each { |k| k.day?.must_equal true} # all keys must be day keys
190
+ ts.compress ts.days
191
+ ts.keys.each { |k| k.month?.must_equal true} # all keys must be month keys
192
+ ts.compress ts.months
193
+ ts.keys.each { |k| k.year?.must_equal true} # all keys must be year keys
194
+ ts.keys.size.must_equal 2
195
+ end
196
+
197
+ it "can compress a mixture of minute, hour, day keys" do
198
+ ts = TimeSeries.new("test_ts")
199
+
200
+ # create 10 hours 6 hours apart
201
+ (0..9).each do |i|
202
+ @redis.zincrby ts.time_to_key(Time.local(2000, 7, 31) - 6*i.hours).parent.parent, 1, "one"
203
+ end
204
+
205
+ # create 10 minutes 6 hours apart on the year 2001
206
+ (0..9).each do |i|
207
+ @redis.zincrby ts.time_to_key(Time.local(2001, 7, 31) - 6*i.hours).parent, 1, "one"
208
+ end
209
+
210
+ # create 10 days 1 day apart on the year 2002
211
+ (0..9).each do |i|
212
+ @redis.zincrby ts.time_to_key(Time.local(2002, 7, 31) - i.days).parent.parent.parent, 1, "one"
213
+ end
214
+
215
+ ts.compress ts.keys
216
+ ts.compress ts.keys
217
+ ts.compress ts.keys
218
+ ts.compress ts.keys
219
+ ts.keys.each { |k| k.year?.must_equal true} # all keys must be year keys
220
+ ts.keys.size.must_equal 3
221
+
222
+ end
223
+
224
+ it "can compress a mixture of keys but will exclude recent keys" do
225
+ ts = TimeSeries.new("test_ts")
226
+
227
+ max_hour = Time.now.hour
228
+ max_min = Time.now.min
229
+ max_sec = Time.now.sec
230
+ max_day = Time.now.day
231
+
232
+ # create seconds
233
+ (1..max_sec).each do |i|
234
+ @redis.zincrby ts.time_to_key(Time.now - i), 1, "one"
235
+ end
236
+
237
+ # create hours
238
+ (1...max_hour).each do |i|
239
+ @redis.zincrby ts.time_to_key(Time.now - i.hours).parent.parent, 1, "one"
240
+ end
241
+
242
+ # create minutes
243
+ (1..max_min).each do |i|
244
+ @redis.zincrby ts.time_to_key(Time.now - i.minutes).parent, 1, "one"
245
+ end
246
+
247
+ # create days
248
+ (1...max_day).each do |i|
249
+ @redis.zincrby ts.time_to_key(Time.now - i.days).parent.parent.parent, 1, "one"
250
+ end
251
+
252
+ # create months
253
+ (1...max_day).each do |i|
254
+ @redis.zincrby ts.time_to_key(Time.now - i.days).parent.parent.parent, 1, "one"
255
+ end
256
+
257
+ recent_keys = ts.keys
258
+ ts.compress ts.keys
259
+ ts.compress ts.keys
260
+ ts.compress ts.keys
261
+ ts.compress ts.keys
262
+ ts.keys.must_equal recent_keys # nothing must be compressed
263
+
264
+ # Now create a mixture of non recent keys
265
+
266
+ # create non recent hours
267
+ (1...max_hour).each do |i|
268
+ @redis.zincrby ts.time_to_key(Time.local(2002, 7, 31) - i.hours).parent.parent, 1, "one"
269
+ end
270
+
271
+ all_keys = ts.keys
272
+ ts.compress ts.keys
273
+ ts.compress ts.keys
274
+ ts.compress ts.keys
275
+ ts.compress ts.keys
276
+ ts.keys.wont_equal all_keys # something must be compressed
277
+ "test:ts:test_ts:2002".exists?.must_equal true
278
+ end
279
+
280
+ it "remove terms by score" do
281
+ ts = TimeSeries.new("test_ts")
282
+
283
+ @redis.zincrby "test:ts:test_ts:1986", 1, "one"
284
+ @redis.zincrby "test:ts:test_ts:1986", 2, "two"
285
+ @redis.zincrby "test:ts:test_ts:1986", 3, "three"
286
+ @redis.zincrby "test:ts:test_ts:1986", 4, "four"
287
+ @redis.zincrby "test:ts:test_ts:1986", 5, "five"
288
+ @redis.zincrby "test:ts:test_ts:1986", 6, "six"
289
+
290
+ @redis.zincrby "test:ts:test_ts:1987", 1, "one"
291
+ @redis.zincrby "test:ts:test_ts:1987", 2, "two"
292
+ @redis.zincrby "test:ts:test_ts:1987", 3, "three"
293
+ @redis.zincrby "test:ts:test_ts:1987", 4, "four"
294
+ @redis.zincrby "test:ts:test_ts:1987", 5, "five"
295
+ @redis.zincrby "test:ts:test_ts:1987", 6, "six"
296
+
297
+ @redis.zincrby "test:ts:test_ts:1988:01", 1, "one"
298
+ @redis.zincrby "test:ts:test_ts:1988:01", 2, "two"
299
+ @redis.zincrby "test:ts:test_ts:1988:01", 3, "three"
300
+ @redis.zincrby "test:ts:test_ts:1988:01", 4, "four"
301
+ @redis.zincrby "test:ts:test_ts:1988:01", 5, "five"
302
+ @redis.zincrby "test:ts:test_ts:1988:01", 6, "six"
303
+
304
+ ts.remove_by_score ts.keys, 4
305
+
306
+ expected = { "five" => 5, "six" => 6 }
307
+ "test:ts:test_ts:1986".get.must_equal expected
308
+ "test:ts:test_ts:1987".get.must_equal expected
309
+ "test:ts:test_ts:1988:01".get.must_equal expected
310
+ end
311
+ end
data/spec/key_spec.rb ADDED
@@ -0,0 +1,256 @@
1
+ #!/usr/bin/ruby
2
+ # http://mattsears.com/articles/2011/12/10/minitest-quick-reference
3
+
4
+ require 'bundler/setup'
5
+ require 'redis'
6
+ require "minitest/autorun"
7
+ require 'minitest/pride'
8
+ require_relative '../lib/key'
9
+
10
+ describe "Key String" do
11
+
12
+ before do
13
+ $app_prefix="test"
14
+ @redis ||= Redis.new(:path => "/tmp/redis.sock")
15
+ @redis.keys("test:*").each{|k| @redis.del k}
16
+ end
17
+
18
+ after do
19
+ @redis.keys("test:*").each{|k| @redis.del k}
20
+ end
21
+
22
+ it "exists?" do
23
+ key = "test:ts:test_ts:2012:11:10:09:08"
24
+ key.exists?.must_equal false
25
+ @redis.zincrby key, 2, "one"
26
+ key.exists?.must_equal true
27
+ end
28
+
29
+ it "determines its prefix" do
30
+ key = "test:ts:test_ts:2012:11:10:09:08"
31
+ key.prefix.must_equal "test:ts:test_ts:"
32
+ end
33
+
34
+ it "has_children" do
35
+ key = "test:ts:test_ts:1986:11:04:12:05"
36
+ @redis.zincrby "test:ts:test_ts:1986:11:04:12:05:01", 2, "one"
37
+ key.has_children?.must_equal true
38
+ end
39
+
40
+ it "can determine volatile? / persistant? keys" do
41
+ key = "test:ts:test_ts:1986:11:04:12:05"
42
+ @redis.zincrby key, 2, "one"
43
+ key.persistant?.must_equal true
44
+ key.volatile?.must_equal false
45
+
46
+ @redis.expire key, 10
47
+ key.persistant?.must_equal false
48
+ key.volatile?.must_equal true
49
+
50
+ "non_existant_key".persistant?.must_equal false
51
+ "non_existant_key".volatile?.must_equal false
52
+ end
53
+
54
+ it "has parent" do
55
+ key = "test:ts:test_ts:1986:11:04:12:05"
56
+ @redis.zincrby "test:ts:test_ts:1986:11:04:12", 2, "one"
57
+ key.has_parent?.must_equal true
58
+ end
59
+
60
+ it "has non persistant parent" do
61
+ key = "test:ts:test_ts:1986:11:04:12:05" #second resolution
62
+
63
+ @redis.zincrby "test:ts:test_ts:1986:11:04:12", 2, "one" #create parent
64
+ key.has_persistant_parent?.must_equal true
65
+ @redis.expire "test:ts:test_ts:1986:11:04:12" , 10 #make parent volatile
66
+ key.has_persistant_parent?.must_equal false
67
+
68
+ "test:ts:test_ts:1986:11:04:12".has_persistant_parent?.must_equal false #key exists, parent no
69
+ "test:ts:test_ts:1986:11".has_persistant_parent?.must_equal false #key and parent do not exist
70
+ end
71
+
72
+ it "has volative parent" do
73
+ key = "test:ts:test_ts:1986:11:04:12:05"
74
+ @redis.zincrby "test:ts:test_ts:1986:11:04:12", 2, "one"
75
+ @redis.expire "test:ts:test_ts:1986:11:04:12", 2
76
+ key.has_volatile_parent?.must_equal true
77
+ end
78
+
79
+ it "has children" do
80
+ key = "test:ts:test_ts:1986:11:04:12:05"
81
+ @redis.zincrby "test:ts:test_ts:1986:11:04:12:05:01", 2, "one"
82
+ @redis.zincrby "test:ts:test_ts:1986:11:04:12:05:02", 2, "one"
83
+ @redis.zincrby "test:ts:test_ts:1986:11:04:12:05:03:00", 2, "one"
84
+ @redis.zincrby "test:ts:test_ts:1986:11:04:12:06:01", 2, "one" # non children
85
+ key.children.size.must_equal 3
86
+ end
87
+
88
+ it "can separate persistant children" do
89
+ key = "test:ts:test_ts:1986:11:04:12:05"
90
+ @redis.zincrby "test:ts:test_ts:1986:11:04:12:05:01", 2, "one"
91
+ @redis.zincrby "test:ts:test_ts:1986:11:04:12:05:02", 2, "one"
92
+ @redis.zincrby "test:ts:test_ts:1986:11:04:12:05:05", 2, "one"
93
+ @redis.zincrby "test:ts:test_ts:1986:11:04:12:05:06", 2, "one"
94
+ @redis.zincrby "test:ts:test_ts:1986:11:04:12:05:07", 2, "one"
95
+ @redis.zincrby "test:ts:test_ts:1986:11:04:12:05:08", 2, "one"
96
+ @redis.zincrby "test:ts:test_ts:1986:11:04:12:05:09", 2, "one"
97
+ @redis.zincrby "test:ts:test_ts:1986:11:04:12:05:10", 2, "one"
98
+ @redis.zincrby "test:ts:test_ts:1986:11:04:12:05:03:00", 2, "one"
99
+
100
+ @redis.expire "test:ts:test_ts:1986:11:04:12:05:01", 5
101
+ @redis.expire "test:ts:test_ts:1986:11:04:12:05:06", 5
102
+ @redis.expire "test:ts:test_ts:1986:11:04:12:05:08", 5
103
+ @redis.expire "test:ts:test_ts:1986:11:04:12:05:03:00", 5
104
+
105
+ @redis.zincrby "test:ts:test_ts:1986:11:04:12:06:01", 2, "one" # hobo
106
+ @redis.zincrby "test:ts:test_ts:1986:11:04:12:07", 2, "one" # hobo
107
+
108
+ key.children.size.must_equal 9
109
+ key.persistant_children.size.must_equal 5
110
+
111
+ end
112
+
113
+ it "has siblings" do
114
+ key = "test:ts:test_ts:1986:11"
115
+ @redis.zincrby "test:ts:test_ts:1986:12", 2, "one"
116
+ @redis.zincrby "test:ts:test_ts:1986:13", 2, "one"
117
+ @redis.zincrby "test:ts:test_ts:1986:14", 2, "one"
118
+ @redis.zincrby "test:ts:test_ts:1986:15", 2, "one"
119
+ @redis.zincrby "test:ts:test_ts:1987:15", 2, "one" # non sibling
120
+ key.siblings_keys.size.must_equal 4
121
+ end
122
+
123
+ it "can unionize persistant children children" do
124
+ key = "test:ts:test_ts:1986:01"
125
+ @redis.zincrby "test:ts:test_ts:1986:01:10", 1, "one"
126
+ @redis.zincrby "test:ts:test_ts:1986:01:11", 1, "one"
127
+ @redis.zincrby "test:ts:test_ts:1986:01:12", 1, "one"
128
+ @redis.zincrby "test:ts:test_ts:1986:01:13", 1, "one"
129
+ @redis.zincrby "test:ts:test_ts:1986:01:14:01", 1, "one"
130
+ @redis.zincrby "test:ts:test_ts:1986:01:14:02", 1, "one"
131
+ @redis.zincrby "test:ts:test_ts:1986:01:10", 2, "two"
132
+ @redis.zincrby "test:ts:test_ts:1986:01:11", 2, "two"
133
+ @redis.zincrby "test:ts:test_ts:1986:01:12", 2, "two"
134
+ @redis.zincrby "test:ts:test_ts:1986:01:13", 2, "two"
135
+ @redis.zincrby "test:ts:test_ts:1986:01:14:01", 2, "two"
136
+ @redis.zincrby "test:ts:test_ts:1986:01:14:02", 2, "two"
137
+ key.unionize_persistant_children
138
+ key.exists?.must_equal true
139
+ key.volatile?.must_equal true
140
+ end
141
+
142
+ it "detects its resolution" do
143
+ "test:ts:test_ts:1986".resolution.must_equal :year
144
+ "test:ts:test_ts:1986:01".resolution.must_equal :month
145
+ "test:ts:test_ts:1986:01:14".resolution.must_equal :day
146
+ "test:ts:test_ts:1986:01:14:02".resolution.must_equal :hour
147
+ "test:ts:test_ts:1986:01:14:02:58".resolution.must_equal :minute
148
+ "test:ts:test_ts:1986:01:14:02:10:11".resolution.must_equal :second
149
+ end
150
+
151
+ it "detects year, month, ..." do
152
+ "test:ts:test_ts:1986".year.must_equal 1986
153
+ "test:ts:test_ts:1986:01".month.must_equal 1
154
+ "test:ts:test_ts:1986:08:02".day.must_equal 2
155
+ "test:ts:test_ts:1986:09:03:04".hour.must_equal 4
156
+ "test:ts:test_ts:1986:10:05:06:07".minute.must_equal 7
157
+ "test:ts:test_ts:1986:11:08:09:10:11".second.must_equal 11
158
+ end
159
+
160
+ it "recent" do
161
+ year = Time.now.year
162
+ month = Time.now.month
163
+ day = Time.now.day
164
+ hour = Time.now.hour
165
+ minute = Time.now.min
166
+
167
+ #year
168
+ "test:ts:test_ts:#{year+1}".recent?.must_equal false
169
+ "test:ts:test_ts:#{year}".recent?.must_equal true
170
+
171
+ #month
172
+ "test:ts:test_ts:#{year+1}:#{month}".recent?.must_equal false
173
+ "test:ts:test_ts:#{year}:#{month}".recent?.must_equal true
174
+
175
+ #second
176
+ "test:ts:test_ts:#{year}:#{month}:#{day}:#{hour}:#{minute+1}:10".recent?.must_equal false
177
+ "test:ts:test_ts:#{year}:#{month}:#{day}:#{hour}:#{minute}:10".recent?.must_equal true
178
+ end
179
+
180
+
181
+ it "get array and hash from redis" do
182
+ key = "test:ts:test_ts:1986"
183
+ @redis.zincrby "test:ts:test_ts:1986", 1, "one"
184
+ @redis.zincrby "test:ts:test_ts:1986", 2, "two"
185
+ @redis.zincrby "test:ts:test_ts:1986", 3, "three"
186
+ @redis.zincrby "test:ts:test_ts:1986", 4, "four"
187
+ @redis.zincrby "test:ts:test_ts:1986", 5, "five"
188
+ @redis.zincrby "test:ts:test_ts:1986", 6, "six"
189
+ @redis.zincrby "test:ts:test_ts:1986", 7, "seven"
190
+ key.get_array.must_be_instance_of Array
191
+ key.get.must_be_instance_of Hash
192
+ h = {"one"=>1, "two"=>2, "three"=>3, "four"=>4, "five"=>5, "six"=>6, "seven"=>7}
193
+ key.get.must_equal h
194
+ end
195
+
196
+ it "time from key" do
197
+ "test:ts:test_ts:1986".time.must_be_instance_of Time
198
+ "test:ts:test_ts:2000".time.year.must_equal 2000
199
+ "test:ts:test_ts:2001:01".time.month.must_equal 1
200
+ "test:ts:test_ts:2001:01:30:23:00:59".time.sec.must_equal 59
201
+ end
202
+
203
+
204
+
205
+ it "can return a non-existing key based on its children" do
206
+ key = "test:ts:test_ts:2000:12:30" #day
207
+ time = Time.new(2000, 12, 30)
208
+
209
+ keys = %w(
210
+ test:ts:test_ts:2000:12:30:01 test:ts:test_ts:2000:12:30:02 test:ts:test_ts:2000:12:30:03
211
+ test:ts:test_ts:2000:12:30:04 test:ts:test_ts:2000:12:30:05 test:ts:test_ts:2000:12:30:06
212
+
213
+ test:ts:test_ts:2000:12:30:07:01 test:ts:test_ts:2000:12:30:07:02 test:ts:test_ts:2000:12:30:07:03
214
+
215
+ test:ts:test_ts:2000:12:30:07:05:01 test:ts:test_ts:2000:12:30:07:01:05:02 test:ts:test_ts:2000:12:30:07:01:05:03
216
+ )
217
+
218
+ expire = %w( test:ts:test_ts:2000:12:30:01 test:ts:test_ts:2000:12:30:02 test:ts:test_ts:2000:12:30:06
219
+ test:ts:test_ts:2000:12:30:07:02 test:ts:test_ts:2000:12:30:07:01:05:02 test:ts:test_ts:2000:12:30:07:01:05:03
220
+ )
221
+ keys.each{|k| @redis.zincrby k, 1, "one"}
222
+ expire.each{|k| @redis.expire k, 1}
223
+
224
+ key.exists?.must_equal false # key does not exists
225
+ key.get.must_be_instance_of Hash # key is created from its children
226
+ key.exists?.must_equal true # now key exists
227
+ key.volatile?.must_equal true # key is volatile
228
+ key.get["one"].must_equal 6
229
+ end
230
+
231
+ it "can return a non-existing key without children based on its parent" do
232
+ key = "test:ts:test_ts:2000:12:30" #day
233
+ # 6 sibling days and 6 non children hours
234
+ keys = %w(
235
+ test:ts:test_ts:2000:12:29 test:ts:test_ts:2000:12:28 test:ts:test_ts:2000:12:27
236
+ test:ts:test_ts:2000:12:26 test:ts:test_ts:2000:12:25 test:ts:test_ts:2000:12:24
237
+
238
+ test:ts:test_ts:2000:12:31:01 test:ts:test_ts:2000:12:31:02 test:ts:test_ts:2000:12:31:03
239
+ test:ts:test_ts:2000:12:31:04 test:ts:test_ts:2000:12:31:05 test:ts:test_ts:2000:12:31:06
240
+ )
241
+
242
+ expire = %w( test:ts:test_ts:2000:12:29 test:ts:test_ts:2000:12:31:04 )
243
+ keys.each{|k| @redis.zincrby k, 1, "one"}
244
+ expire.each{|k| @redis.expire k, 10}
245
+
246
+ #ap key.parent.persistant_children
247
+ key.exists?.must_equal false
248
+ key.has_children?.must_equal false # key has no children, only siblings
249
+ key.get.must_be_instance_of Hash # get will be retrive info from its parent children
250
+ key.exists?.must_equal true
251
+ key.get["one"].must_equal 1
252
+ key.volatile?.must_equal true
253
+
254
+ end
255
+
256
+ end