time_series 0.0.1

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.
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