redistat 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,23 @@
1
+ module Redistat
2
+ class Result < ::ActiveSupport::HashWithIndifferentAccess
3
+
4
+ attr_accessor :from
5
+ attr_accessor :till
6
+
7
+ alias :date :from
8
+ alias :date= :from=
9
+
10
+ def initialize(options = {})
11
+ @from = options[:from] ||= nil
12
+ @till = options[:till] ||= nil
13
+ end
14
+
15
+
16
+ def set_or_incr(key, value)
17
+ self[key] = 0 if !self.has_key?(key)
18
+ self[key] += value
19
+ self
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ module Redistat
2
+ class Scope
3
+ include Database
4
+
5
+ def initialize(name)
6
+ @name = name.to_s
7
+ end
8
+
9
+ def to_s
10
+ @name
11
+ end
12
+
13
+ def next_id
14
+ db.incr("#{@name}#{KEY_NEXT_ID}")
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,24 @@
1
+ module Redistat
2
+ class Summary
3
+ include Database
4
+
5
+ def self.update_all(key, stats = {}, depth_limit = nil)
6
+ stats ||= {}
7
+ depth_limit ||= key.depth
8
+ return nil if stats.size == 0
9
+ Date::DEPTHS.each do |depth|
10
+ update(key, stats, depth)
11
+ break if depth == depth_limit
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def self.update(key, stats, depth)
18
+ stats.each do |field, value|
19
+ db.hincrby key.to_s(depth), field, value
20
+ end
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,34 @@
1
+ require "spec_helper"
2
+
3
+ describe Redistat do
4
+ include Redistat::Database
5
+
6
+ before(:each) do
7
+ db.flushdb
8
+ end
9
+
10
+ it "should have a valid Redis client instance" do
11
+ db.should_not be_nil
12
+ end
13
+
14
+ it "should be connected to the testing server" do
15
+ db.client.port.should == 8379
16
+ db.client.host.should == "127.0.0.1"
17
+ end
18
+
19
+ it "should be able to set and get data" do
20
+ db.set("hello", "world")
21
+ db.get("hello").should == "world"
22
+ db.del("hello").should be_true
23
+ end
24
+
25
+ it "should be able to store hashes to Redis" do
26
+ db.hset("key", "field", "1")
27
+ db.hget("key", "field").should == "1"
28
+ db.hincrby("key", "field", 1)
29
+ db.hget("key", "field").should == "2"
30
+ db.hincrby("key", "field", -1)
31
+ db.hget("key", "field").should == "1"
32
+ end
33
+
34
+ end
@@ -0,0 +1,13 @@
1
+ require "spec_helper"
2
+
3
+ describe Redistat::Collection do
4
+
5
+ it "should should initialize properly" do
6
+ options = {:from => "from", :till => "till", :depth => "depth"}
7
+ result = Redistat::Collection.new(options)
8
+ result.from.should == options[:from]
9
+ result.till.should == options[:till]
10
+ result.depth.should == options[:depth]
11
+ end
12
+
13
+ end
data/spec/date_spec.rb ADDED
@@ -0,0 +1,95 @@
1
+ require "spec_helper"
2
+
3
+ describe Redistat::Date do
4
+
5
+ it "should initialize from Time object" do
6
+ now = Time.now
7
+ [Redistat::Date.new(now), now.to_rs].each do |rdate|
8
+ Redistat::Date::DEPTHS.each { |k| rdate.send(k).should == now.send(k) }
9
+ end
10
+ end
11
+
12
+ it "should initialize from Date object" do
13
+ today = Date.today
14
+ [Redistat::Date.new(today), today.to_rs].each do |rdate|
15
+ [:year, :month, :day].each { |k| rdate.send(k).should == today.send(k) }
16
+ [:hour, :min, :sec, :usec].each { |k| rdate.send(k).should == 0 }
17
+ end
18
+ end
19
+
20
+ it "should initialize from Fixnum object (UNIX Timestamp)" do
21
+ now = Time.now.to_i
22
+ time = Time.at(now)
23
+ [Redistat::Date.new(now), now.to_rs].each do |rdate|
24
+ [:year, :month, :day, :hour, :min, :sec].each { |k| rdate.send(k).should == time.send(k) }
25
+ end
26
+ end
27
+
28
+ it "should initialize from String object" do
29
+ now = Time.now
30
+ rdate = Redistat::Date.new(now.to_s)
31
+ [:year, :month, :day, :hour, :min, :sec].each { |k| rdate.send(k).should == now.send(k) }
32
+ end
33
+
34
+ it "should initialize from Redistat date String" do
35
+ now = Time.now
36
+ rdate = Redistat::Date.new(now.to_s)
37
+ [:year, :month, :day, :hour, :min, :sec].each { |k|
38
+ rdate.to_s(k).should == Redistat::Date.new(rdate.to_s(k)).to_s(k)
39
+ }
40
+ end
41
+
42
+ it "should convert to Time object" do
43
+ now = Time.now
44
+ rdate = Redistat::Date.new(now)
45
+ rdate.to_time.to_s.should == now.to_s
46
+ end
47
+
48
+ it "should convert to Date object" do
49
+ today = Date.today
50
+ rdate = Redistat::Date.new(today)
51
+ rdate.to_date.to_s.should == today.to_s
52
+ end
53
+
54
+ it "should convert to Fixnum object (UNIX Timestamp)" do
55
+ now = Time.now
56
+ rdate = Redistat::Date.new(now)
57
+ rdate.to_i.should == now.to_i
58
+ end
59
+
60
+ it "should convert to string with correct depths" do
61
+ today = Date.today
62
+ now = Time.now
63
+ [[now, Redistat::Date.new(now)], [today, Redistat::Date.new(today)]].each do |current, rdate|
64
+ props = [:year, :month, :day, :hour, :min, :sec, nil]
65
+ if rdate.usec > 0
66
+ rdate.to_s(:usec).should == props.map { |k| current.send(k).to_s.rjust(2, '0') if !k.nil? }.join + "." + current.usec.to_s.rjust(6, '0')
67
+ end
68
+ props.clone.each do
69
+ rdate.to_s(props.last).should == props.map { |k| current.send(k).to_s.rjust(2, '0') if !k.nil? }.join
70
+ props.pop
71
+ end
72
+ end
73
+ end
74
+
75
+ it "should add helper methods to Date, Time and Fixnum classes" do
76
+ Date.today.to_time.should == Time.parse(Date.today.to_s)
77
+ Time.now.to_i.to_time.should == Time.at(Time.now.to_i)
78
+ Date.today.to_rs.to_date.should == Date.today
79
+ end
80
+
81
+ it "should have a depth property" do
82
+ now = Time.now
83
+
84
+ date = Redistat::Date.new(now)
85
+ date.depth.should be_nil
86
+ date.to_s.should == now.to_rs(:sec).to_s
87
+ date.to_s.should == now.to_rs.to_s(:sec)
88
+
89
+ date = Redistat::Date.new(now, :hour)
90
+ date.depth.should == :hour
91
+ date.to_s.should == now.to_rs(:hour).to_s
92
+ date.to_s.should == now.to_rs.to_s(:hour)
93
+ end
94
+
95
+ end
@@ -0,0 +1,83 @@
1
+ require "spec_helper"
2
+
3
+ describe Redistat::Event do
4
+ include Redistat::Database
5
+
6
+ before(:each) do
7
+ db.flushdb
8
+ @scope = "PageViews"
9
+ @label = "about_us"
10
+ @label_hash = Digest::SHA1.hexdigest(@label)
11
+ @stats = {:views => 1}
12
+ @meta = {:user_id => 239}
13
+ @options = {:depth => :hour}
14
+ @date = Time.now
15
+ @event = Redistat::Event.new(@scope, @label, @date, @stats, @options, @meta)
16
+ end
17
+
18
+ it "should initialize properly" do
19
+ @event.id.should be_nil
20
+ @event.scope.should == @scope
21
+ @event.label.should == @label
22
+ @event.label_hash.should == @label_hash
23
+ @event.date.to_time.should == @date
24
+ @event.stats.should == @stats
25
+ @event.meta.should == @meta
26
+ @event.options.should == @event.default_options.merge(@options)
27
+ end
28
+
29
+ it "should allow changing attributes" do
30
+ # date
31
+ @event.date.to_time.should == @date
32
+ @date = Time.now
33
+ @event.date = @date
34
+ @event.date.to_time.should == @date
35
+ # label
36
+ @event.label.should == @label
37
+ @event.label_hash.should == @label_hash
38
+ @label = "contact_us"
39
+ @label_hash = Digest::SHA1.hexdigest(@label)
40
+ @event.label = @label
41
+ @event.label.should == @label
42
+ @event.label_hash.should == @label_hash
43
+ end
44
+
45
+ it "should increment next_id" do
46
+ event = Redistat::Event.new("VisitorCount", @label, @date, @stats, @options, @meta)
47
+ @event.next_id.should == 1
48
+ event.next_id.should == 1
49
+ @event.next_id.should == 2
50
+ event.next_id.should == 2
51
+ end
52
+
53
+ it "should store event properly" do
54
+ @event = Redistat::Event.new(@scope, @label, @date, @stats, @options.merge({:store_event => true}), @meta)
55
+ @event.new?.should be_true
56
+ @event.save
57
+ @event.new?.should be_false
58
+ keys = db.keys "*"
59
+ keys.should include("#{@event.scope}#{Redistat::KEY_EVENT}#{@event.id}")
60
+ keys.should include("#{@event.scope}#{Redistat::KEY_EVENT_IDS}")
61
+ end
62
+
63
+ it "should find event by id" do
64
+ @event = Redistat::Event.new(@scope, @label, @date, @stats, @options.merge({:store_event => true}), @meta).save
65
+ fetched = Redistat::Event.find(@scope, @event.id)
66
+ @event.scope.should == fetched.scope
67
+ @event.label.should == fetched.label
68
+ @event.date.to_s.should == fetched.date.to_s
69
+ end
70
+
71
+ it "should store summarized statistics" do
72
+ 2.times do |i|
73
+ @event = Redistat::Event.new(@scope, @label, @date, @stats, @options, @meta).save
74
+ Redistat::Date::DEPTHS.each do |depth|
75
+ summary = db.hgetall @event.key.to_s(depth)
76
+ summary.should have_at_least(1).items
77
+ summary["views"].should == (i+1).to_s
78
+ break if depth == :hour
79
+ end
80
+ end
81
+ end
82
+
83
+ end
@@ -0,0 +1,525 @@
1
+ require "spec_helper"
2
+
3
+ describe Redistat::Finder::DateSet do
4
+
5
+ before(:all) do
6
+ @finder = Redistat::Finder::DateSet.new
7
+ end
8
+
9
+ it "should initialize properly" do
10
+ t_start = Time.utc(2010, 8, 28, 22, 54, 57)
11
+ t_end = Time.utc(2013, 12, 4, 22, 52, 3)
12
+ result = Redistat::Finder::DateSet.new(t_start, t_end)
13
+ result.should == [
14
+ { :add => ["2010082822", "2010082823"], :rem => [] },
15
+ { :add => ["20131204"], :rem => ["2013120423"] },
16
+ { :add => ["20100829", "20100830", "20100831"], :rem => [] },
17
+ { :add => ["20131201", "20131202", "20131203"], :rem => [] },
18
+ { :add => ["201009", "201010", "201011", "201012"], :rem => [] },
19
+ { :add => ["2013"], :rem => ["201312"] },
20
+ { :add => ["2011", "2012"], :rem => [] }
21
+ ]
22
+ end
23
+
24
+ it "should find date sets by interval" do
25
+ t_start = Time.utc(2010, 8, 28, 18, 54, 57)
26
+
27
+ t_end = t_start + 4.hours
28
+ result = Redistat::Finder::DateSet.new.find_date_sets(t_start, t_end, :hour, true)
29
+ result[0][:add].should == ["2010082818", "2010082819", "2010082820", "2010082821", "2010082822"]
30
+ result[0][:rem].should == []
31
+
32
+ t_end = t_start + 4.days
33
+ result = Redistat::Finder::DateSet.new.find_date_sets(t_start, t_end, :day, true)
34
+ result[0][:add].should == ["20100828", "20100829", "20100830", "20100831", "20100901"]
35
+ result[0][:rem].should == []
36
+ end
37
+
38
+ it "should find start keys properly" do
39
+
40
+ #
41
+ # Simple fetching
42
+ # Dates: 22:54, 26th August, 2010 --> 22:52, 14th December, 2010
43
+ #
44
+
45
+ t_start = Time.utc(2010, 8, 26, 22, 54, 57)
46
+ t_end = Time.utc(2013, 12, 14, 22, 52, 3)
47
+
48
+ result = @finder.send(:find_start_keys_for, :sec, t_start, t_end)
49
+ result[:add].should == ["20100826225458", "20100826225459"]
50
+ result[:rem].should == []
51
+
52
+ result = @finder.send(:find_start_keys_for, :min, t_start, t_end)
53
+ result[:add].should == ["201008262255", "201008262256", "201008262257", "201008262258", "201008262259"]
54
+ result[:rem].should == []
55
+
56
+ result = @finder.send(:find_start_keys_for, :hour, t_start, t_end)
57
+ result[:add].should == ["2010082623"]
58
+ result[:rem].should == []
59
+
60
+ result = @finder.send(:find_start_keys_for, :day, t_start, t_end)
61
+ result[:add].should == ["20100827", "20100828", "20100829", "20100830", "20100831"]
62
+ result[:rem].should == []
63
+
64
+ result = @finder.send(:find_start_keys_for, :month, t_start, t_end)
65
+ result[:add].should == ["201009", "201010", "201011", "201012"]
66
+ result[:rem].should == []
67
+
68
+ result = @finder.send(:find_start_keys_for, :year, t_start, t_end)
69
+ result[:add].should == ["2011", "2012"]
70
+ result[:rem].should == []
71
+
72
+ #
73
+ # Reverse / Inteligent fetching
74
+ # Dates: 5:06, 4th April, 2010 --> 22:52, 14th February, 2011
75
+ #
76
+
77
+ t_start = Time.utc(2010, 4, 4, 5, 6, 4)
78
+ t_end = Time.utc(2011, 2, 14, 22, 52, 3)
79
+
80
+ result = @finder.send(:find_start_keys_for, :sec, t_start, t_end)
81
+ result[:add].should == ["201004040506"]
82
+ result[:rem].should == ["20100404050600", "20100404050601", "20100404050602", "20100404050603", "20100404050604"]
83
+
84
+ result = @finder.send(:find_start_keys_for, :min, t_start, t_end)
85
+ result[:add].should == ["2010040405"]
86
+ result[:rem].should == ["201004040500", "201004040501", "201004040502", "201004040503", "201004040504", "201004040505", "201004040506"]
87
+
88
+ result = @finder.send(:find_start_keys_for, :hour, t_start, t_end)
89
+ result[:add].should == ["20100404"]
90
+ result[:rem].should == ["2010040400", "2010040401", "2010040402", "2010040403", "2010040404", "2010040405"]
91
+
92
+ result = @finder.send(:find_start_keys_for, :day, t_start, t_end)
93
+ result[:add].should == ["201004"]
94
+ result[:rem].should == ["20100401", "20100402", "20100403", "20100404"]
95
+
96
+ result = @finder.send(:find_start_keys_for, :month, t_start, t_end)
97
+ result[:add].should == ["2010"]
98
+ result[:rem].should == ["201001", "201002", "201003", "201004"]
99
+
100
+ result = @finder.send(:find_start_keys_for, :year, t_start, t_end)
101
+ result[:add].should == []
102
+ result[:rem].should == []
103
+
104
+ end
105
+
106
+ it "should find end keys properly" do
107
+
108
+ #
109
+ # Simple fetching
110
+ # Dates: 22:04, 26th December, 2007 --> 5:06, 7th May, 2010
111
+ #
112
+
113
+ t_start = Time.utc(2007, 12, 26, 22, 4, 4)
114
+ t_end = Time.utc(2010, 5, 7, 5, 6, 3)
115
+
116
+ result = @finder.send(:find_end_keys_for, :sec, t_start, t_end)
117
+ result[:add].should == ["20100507050600", "20100507050601", "20100507050602"]
118
+ result[:rem].should == []
119
+
120
+ result = @finder.send(:find_end_keys_for, :min, t_start, t_end)
121
+ result[:add].should == ["201005070500", "201005070501", "201005070502", "201005070503", "201005070504", "201005070505"]
122
+ result[:rem].should == []
123
+
124
+ result = @finder.send(:find_end_keys_for, :hour, t_start, t_end)
125
+ result[:add].should == ["2010050700", "2010050701", "2010050702", "2010050703", "2010050704"]
126
+ result[:rem].should == []
127
+
128
+ result = @finder.send(:find_end_keys_for, :day, t_start, t_end)
129
+ result[:add].should == ["20100501", "20100502", "20100503", "20100504", "20100505", "20100506"]
130
+ result[:rem].should == []
131
+
132
+ result = @finder.send(:find_end_keys_for, :month, t_start, t_end)
133
+ result[:add].should == ["201001", "201002", "201003", "201004"]
134
+ result[:rem].should == []
135
+
136
+ result = @finder.send(:find_end_keys_for, :year, t_start, t_end)
137
+ result[:add].should == []
138
+ result[:rem].should == []
139
+
140
+ #
141
+ # Reverse / Inteligent fetching
142
+ # Dates: 22:04, 26th December, 2009 --> 22:56, 27th October, 2010
143
+ #
144
+
145
+ t_start = Time.utc(2009, 12, 26, 22, 4, 4)
146
+ t_end = Time.utc(2010, 10, 27, 22, 56, 57)
147
+
148
+ result = @finder.send(:find_end_keys_for, :sec, t_start, t_end)
149
+ result[:add].should == ["201010272256"]
150
+ result[:rem].should == ["20101027225657", "20101027225658", "20101027225659"]
151
+
152
+ result = @finder.send(:find_end_keys_for, :min, t_start, t_end)
153
+ result[:add].should == ["2010102722"]
154
+ result[:rem].should == ["201010272256", "201010272257", "201010272258", "201010272259"]
155
+
156
+ result = @finder.send(:find_end_keys_for, :hour, t_start, t_end)
157
+ result[:add].should == ["20101027"]
158
+ result[:rem].should == ["2010102722", "2010102723"]
159
+
160
+ result = @finder.send(:find_end_keys_for, :day, t_start, t_end)
161
+ result[:add].should == ["201010"]
162
+ result[:rem].should == ["20101027", "20101028", "20101029", "20101030", "20101031"]
163
+
164
+ result = @finder.send(:find_end_keys_for, :month, t_start, t_end)
165
+ result[:add].should == ["2010"]
166
+ result[:rem].should == ["201010", "201011", "201012"]
167
+
168
+ result = @finder.send(:find_end_keys_for, :year, t_start, t_end)
169
+ result[:add].should == []
170
+ result[:rem].should == []
171
+
172
+ end
173
+
174
+ it "should fetch start/end keys with limits" do
175
+
176
+ #
177
+ # Simple fetching with Limits
178
+ #
179
+
180
+ # seconds
181
+ t_start = Time.utc(2010, 8, 26, 20, 54, 45)
182
+ t_end = t_start + 4.seconds
183
+
184
+ result = @finder.send(:find_start_keys_for, :sec, t_start, t_end)
185
+ result[:add].should == ["20100826205446", "20100826205447", "20100826205448"]
186
+ result[:rem].should == []
187
+
188
+ result = @finder.send(:find_end_keys_for, :sec, t_start, t_end)
189
+ result[:add].should == []
190
+ result[:rem].should == []
191
+
192
+ t_start = Time.utc(2010, 8, 26, 20, 54, 4)
193
+ t_end = t_start + 4.seconds
194
+
195
+ result = @finder.send(:find_start_keys_for, :sec, t_start, t_end)
196
+ result[:add].should == ["20100826205405", "20100826205406", "20100826205407"]
197
+ result[:rem].should == []
198
+
199
+ result = @finder.send(:find_end_keys_for, :sec, t_start, t_end)
200
+ result[:add].should == []
201
+ result[:rem].should == []
202
+
203
+ # minutes
204
+ t_start = Time.utc(2010, 8, 26, 20, 54)
205
+ t_end = t_start + 4.minutes
206
+
207
+ result = @finder.send(:find_start_keys_for, :min, t_start, t_end)
208
+ result[:add].should == ["201008262055", "201008262056", "201008262057"]
209
+ result[:rem].should == []
210
+
211
+ result = @finder.send(:find_end_keys_for, :min, t_start, t_end)
212
+ result[:add].should == []
213
+ result[:rem].should == []
214
+
215
+ t_start = Time.utc(2010, 8, 26, 20, 4)
216
+ t_end = t_start + 4.minutes
217
+
218
+ result = @finder.send(:find_start_keys_for, :min, t_start, t_end)
219
+ result[:add].should == ["201008262005", "201008262006", "201008262007"]
220
+ result[:rem].should == []
221
+
222
+ result = @finder.send(:find_end_keys_for, :min, t_start, t_end)
223
+ result[:add].should == []
224
+ result[:rem].should == []
225
+
226
+ # hours
227
+ t_start = Time.utc(2010, 8, 26, 20, 54)
228
+ t_end = t_start + 2.hours
229
+
230
+ result = @finder.send(:find_start_keys_for, :min, t_start, t_end)
231
+ result[:add].should == ["201008262055", "201008262056", "201008262057", "201008262058", "201008262059"]
232
+ result[:rem].should == []
233
+
234
+ result = @finder.send(:find_start_keys_for, :hour, t_start, t_end)
235
+ result[:add].should == ["2010082621"]
236
+ result[:rem].should == []
237
+
238
+ result = @finder.send(:find_end_keys_for, :hour, t_start, t_end)
239
+ result[:add].should == []
240
+ result[:rem].should == []
241
+
242
+ result = @finder.send(:find_end_keys_for, :min, t_start, t_end)
243
+ result[:add].should == ["2010082622"]
244
+ result[:rem].should == ["201008262254", "201008262255", "201008262256", "201008262257", "201008262258", "201008262259"]
245
+
246
+ t_start = Time.utc(2010, 8, 26, 4, 54)
247
+ t_end = t_start + 5.hours
248
+
249
+ result = @finder.send(:find_start_keys_for, :min, t_start, t_end)
250
+ result[:add].should == ["201008260455", "201008260456", "201008260457", "201008260458", "201008260459"]
251
+ result[:rem].should == []
252
+
253
+ result = @finder.send(:find_start_keys_for, :hour, t_start, t_end)
254
+ result[:add].should == ["2010082605", "2010082606", "2010082607", "2010082608"]
255
+ result[:rem].should == []
256
+
257
+ result = @finder.send(:find_end_keys_for, :hour, t_start, t_end)
258
+ result[:add].should == []
259
+ result[:rem].should == []
260
+
261
+ result = @finder.send(:find_end_keys_for, :min, t_start, t_end)
262
+ result[:add].should == ["2010082609"]
263
+ result[:rem].should == ["201008260954", "201008260955", "201008260956", "201008260957", "201008260958", "201008260959"]
264
+
265
+ # days
266
+ t_start = Time.utc(2010, 8, 26, 20, 54)
267
+ t_end = t_start + 2.day
268
+
269
+ result = @finder.send(:find_start_keys_for, :min, t_start, t_end)
270
+ result[:add].should == ["201008262055", "201008262056", "201008262057", "201008262058", "201008262059"]
271
+ result[:rem].should == []
272
+
273
+ result = @finder.send(:find_start_keys_for, :hour, t_start, t_end)
274
+ result[:add].should == ["2010082621", "2010082622", "2010082623"]
275
+ result[:rem].should == []
276
+
277
+ result = @finder.send(:find_start_keys_for, :day, t_start, t_end)
278
+ result[:add].should == ["20100827"]
279
+ result[:rem].should == []
280
+
281
+ result = @finder.send(:find_end_keys_for, :day, t_start, t_end)
282
+ result[:add].should == []
283
+ result[:rem].should == []
284
+
285
+ result = @finder.send(:find_end_keys_for, :hour, t_start, t_end)
286
+ result[:add].should == ["20100828"]
287
+ result[:rem].should == ["2010082820", "2010082821", "2010082822", "2010082823"]
288
+
289
+ result = @finder.send(:find_end_keys_for, :min, t_start, t_end)
290
+ result[:add].should == ["2010082820"]
291
+ result[:rem].should == ["201008282054", "201008282055", "201008282056", "201008282057", "201008282058", "201008282059"]
292
+
293
+ t_start = Time.utc(2010, 8, 6, 20, 54)
294
+ t_end = t_start + 2.day
295
+
296
+ result = @finder.send(:find_start_keys_for, :min, t_start, t_end)
297
+ result[:add].should == ["201008062055", "201008062056", "201008062057", "201008062058", "201008062059"]
298
+ result[:rem].should == []
299
+
300
+ result = @finder.send(:find_start_keys_for, :hour, t_start, t_end)
301
+ result[:add].should == ["2010080621", "2010080622", "2010080623"]
302
+ result[:rem].should == []
303
+
304
+ result = @finder.send(:find_start_keys_for, :day, t_start, t_end)
305
+ result[:add].should == ["20100807"]
306
+ result[:rem].should == []
307
+
308
+ result = @finder.send(:find_end_keys_for, :day, t_start, t_end)
309
+ result[:add].should == []
310
+ result[:rem].should == []
311
+
312
+ result = @finder.send(:find_end_keys_for, :hour, t_start, t_end)
313
+ result[:add].should == ["20100808"]
314
+ result[:rem].should == ["2010080820", "2010080821", "2010080822", "2010080823"]
315
+
316
+ result = @finder.send(:find_end_keys_for, :min, t_start, t_end)
317
+ result[:add].should == ["2010080820"]
318
+ result[:rem].should == ["201008082054", "201008082055", "201008082056", "201008082057", "201008082058", "201008082059"]
319
+
320
+ # months
321
+ t_start = Time.utc(2010, 8, 26, 20, 54)
322
+ t_end = t_start + 3.months
323
+
324
+ result = @finder.send(:find_start_keys_for, :min, t_start, t_end)
325
+ result[:add].should == ["201008262055", "201008262056", "201008262057", "201008262058", "201008262059"]
326
+ result[:rem].should == []
327
+
328
+ result = @finder.send(:find_start_keys_for, :hour, t_start, t_end)
329
+ result[:add].should == ["2010082621", "2010082622", "2010082623"]
330
+ result[:rem].should == []
331
+
332
+ result = @finder.send(:find_start_keys_for, :day, t_start, t_end)
333
+ result[:add].should == ["20100827", "20100828", "20100829", "20100830", "20100831"]
334
+ result[:rem].should == []
335
+
336
+ result = @finder.send(:find_start_keys_for, :month, t_start, t_end)
337
+ result[:add].should == ["201009", "201010"]
338
+ result[:rem].should == []
339
+
340
+ result = @finder.send(:find_end_keys_for, :month, t_start, t_end)
341
+ result[:add].should == []
342
+ result[:rem].should == []
343
+
344
+ result = @finder.send(:find_end_keys_for, :day, t_start, t_end)
345
+ result[:add].should == ["201011"]
346
+ result[:rem].should == ["20101126", "20101127", "20101128", "20101129", "20101130"]
347
+
348
+ result = @finder.send(:find_end_keys_for, :hour, t_start, t_end)
349
+ result[:add].should == ["20101126"]
350
+ result[:rem].should == ["2010112620", "2010112621", "2010112622", "2010112623"]
351
+
352
+ result = @finder.send(:find_end_keys_for, :min, t_start, t_end)
353
+ result[:add].should == ["2010112620"]
354
+ result[:rem].should == ["201011262054", "201011262055", "201011262056", "201011262057", "201011262058", "201011262059"]
355
+
356
+ t_start = Time.utc(2010, 4, 26, 20, 54)
357
+ t_end = t_start + 3.months
358
+
359
+ result = @finder.send(:find_start_keys_for, :min, t_start, t_end)
360
+ result[:add].should == ["201004262055", "201004262056", "201004262057", "201004262058", "201004262059"]
361
+ result[:rem].should == []
362
+
363
+ result = @finder.send(:find_start_keys_for, :hour, t_start, t_end)
364
+ result[:add].should == ["2010042621", "2010042622", "2010042623"]
365
+ result[:rem].should == []
366
+
367
+ result = @finder.send(:find_start_keys_for, :day, t_start, t_end)
368
+ result[:add].should == ["20100427", "20100428", "20100429", "20100430"]
369
+ result[:rem].should == []
370
+
371
+ result = @finder.send(:find_start_keys_for, :month, t_start, t_end)
372
+ result[:add].should == ["201005", "201006"]
373
+ result[:rem].should == []
374
+
375
+ result = @finder.send(:find_end_keys_for, :month, t_start, t_end)
376
+ result[:add].should == []
377
+ result[:rem].should == []
378
+
379
+ result = @finder.send(:find_end_keys_for, :day, t_start, t_end)
380
+ result[:add].should == ["201007"]
381
+ result[:rem].should == ["20100726", "20100727", "20100728", "20100729", "20100730", "20100731"]
382
+
383
+ result = @finder.send(:find_end_keys_for, :hour, t_start, t_end)
384
+ result[:add].should == ["20100726"]
385
+ result[:rem].should == ["2010072620", "2010072621", "2010072622", "2010072623"]
386
+
387
+ result = @finder.send(:find_end_keys_for, :min, t_start, t_end)
388
+ result[:add].should == ["2010072620"]
389
+ result[:rem].should == ["201007262054", "201007262055", "201007262056", "201007262057", "201007262058", "201007262059"]
390
+
391
+ end
392
+
393
+ it "should find inclusive keys on lowest depth" do
394
+
395
+ #
396
+ # Simple start fetching
397
+ # Dates: 22:54, 26th August, 2010 --> 22:52, 14th December, 2010
398
+ #
399
+
400
+ t_start = Time.utc(2010, 8, 26, 22, 54, 57)
401
+ t_end = Time.utc(2013, 12, 14, 22, 52, 3)
402
+
403
+ result = @finder.send(:find_start_keys_for, :sec, t_start, t_end, true)
404
+ result[:add].should == ["20100826225457", "20100826225458", "20100826225459"]
405
+ result[:rem].should == []
406
+
407
+ result = @finder.send(:find_start_keys_for, :min, t_start, t_end, true)
408
+ result[:add].should == ["201008262254", "201008262255", "201008262256", "201008262257", "201008262258", "201008262259"]
409
+ result[:rem].should == []
410
+
411
+ result = @finder.send(:find_start_keys_for, :hour, t_start, t_end, true)
412
+ result[:add].should == ["2010082622", "2010082623"]
413
+ result[:rem].should == []
414
+
415
+ result = @finder.send(:find_start_keys_for, :day, t_start, t_end, true)
416
+ result[:add].should == ["20100826", "20100827", "20100828", "20100829", "20100830", "20100831"]
417
+ result[:rem].should == []
418
+
419
+ result = @finder.send(:find_start_keys_for, :month, t_start, t_end, true)
420
+ result[:add].should == ["201008", "201009", "201010", "201011", "201012"]
421
+ result[:rem].should == []
422
+
423
+ result = @finder.send(:find_start_keys_for, :year, t_start, t_end, true)
424
+ result[:add].should == ["2011", "2012", "2013"]
425
+ result[:rem].should == []
426
+
427
+ #
428
+ # Reverse / Inteligent start fetching
429
+ # Dates: 5:06, 4th April, 2010 --> 22:52, 14th February, 2011
430
+ #
431
+
432
+ t_start = Time.utc(2010, 4, 4, 5, 6, 4)
433
+ t_end = Time.utc(2013, 2, 14, 22, 52, 3)
434
+
435
+ result = @finder.send(:find_start_keys_for, :sec, t_start, t_end, true)
436
+ result[:add].should == ["201004040506"]
437
+ result[:rem].should == ["20100404050600", "20100404050601", "20100404050602", "20100404050603"]
438
+
439
+ result = @finder.send(:find_start_keys_for, :min, t_start, t_end, true)
440
+ result[:add].should == ["2010040405"]
441
+ result[:rem].should == ["201004040500", "201004040501", "201004040502", "201004040503", "201004040504", "201004040505"]
442
+
443
+ result = @finder.send(:find_start_keys_for, :hour, t_start, t_end, true)
444
+ result[:add].should == ["20100404"]
445
+ result[:rem].should == ["2010040400", "2010040401", "2010040402", "2010040403", "2010040404"]
446
+
447
+ result = @finder.send(:find_start_keys_for, :day, t_start, t_end, true)
448
+ result[:add].should == ["201004"]
449
+ result[:rem].should == ["20100401", "20100402", "20100403"]
450
+
451
+ result = @finder.send(:find_start_keys_for, :month, t_start, t_end, true)
452
+ result[:add].should == ["2010"]
453
+ result[:rem].should == ["201001", "201002", "201003"]
454
+
455
+ result = @finder.send(:find_start_keys_for, :year, t_start, t_end, true)
456
+ result[:add].should == ["2011", "2012", "2013"]
457
+ result[:rem].should == []
458
+
459
+ #
460
+ # Simple fetching
461
+ # Dates: 22:04, 26th December, 2007 --> 5:06, 7th May, 2010
462
+ #
463
+
464
+ t_start = Time.utc(2007, 12, 26, 22, 4, 4)
465
+ t_end = Time.utc(2010, 5, 7, 5, 6, 3)
466
+
467
+ result = @finder.send(:find_end_keys_for, :sec, t_start, t_end, true)
468
+ result[:add].should == ["20100507050600", "20100507050601", "20100507050602", "20100507050603"]
469
+ result[:rem].should == []
470
+
471
+ result = @finder.send(:find_end_keys_for, :min, t_start, t_end, true)
472
+ result[:add].should == ["201005070500", "201005070501", "201005070502", "201005070503", "201005070504", "201005070505", "201005070506"]
473
+ result[:rem].should == []
474
+
475
+ result = @finder.send(:find_end_keys_for, :hour, t_start, t_end, true)
476
+ result[:add].should == ["2010050700", "2010050701", "2010050702", "2010050703", "2010050704", "2010050705"]
477
+ result[:rem].should == []
478
+
479
+ result = @finder.send(:find_end_keys_for, :day, t_start, t_end, true)
480
+ result[:add].should == ["20100501", "20100502", "20100503", "20100504", "20100505", "20100506", "20100507"]
481
+ result[:rem].should == []
482
+
483
+ result = @finder.send(:find_end_keys_for, :month, t_start, t_end, true)
484
+ result[:add].should == ["201001", "201002", "201003", "201004", "201005"]
485
+ result[:rem].should == []
486
+
487
+ result = @finder.send(:find_end_keys_for, :year, t_start, t_end, true)
488
+ result[:add].should == ["2010"]
489
+ result[:rem].should == []
490
+
491
+ #
492
+ # Reverse / Inteligent fetching
493
+ # Dates: 22:04, 26th December, 2009 --> 22:56, 27th October, 2010
494
+ #
495
+
496
+ t_start = Time.utc(2009, 12, 26, 22, 4, 4)
497
+ t_end = Time.utc(2010, 10, 27, 22, 56, 57)
498
+
499
+ result = @finder.send(:find_end_keys_for, :sec, t_start, t_end, true)
500
+ result[:add].should == ["201010272256"]
501
+ result[:rem].should == ["20101027225658", "20101027225659"]
502
+
503
+ result = @finder.send(:find_end_keys_for, :min, t_start, t_end, true)
504
+ result[:add].should == ["2010102722"]
505
+ result[:rem].should == ["201010272257", "201010272258", "201010272259"]
506
+
507
+ result = @finder.send(:find_end_keys_for, :hour, t_start, t_end, true)
508
+ result[:add].should == ["20101027"]
509
+ result[:rem].should == ["2010102723"]
510
+
511
+ result = @finder.send(:find_end_keys_for, :day, t_start, t_end, true)
512
+ result[:add].should == ["201010"]
513
+ result[:rem].should == ["20101028", "20101029", "20101030", "20101031"]
514
+
515
+ result = @finder.send(:find_end_keys_for, :month, t_start, t_end, true)
516
+ result[:add].should == ["2010"]
517
+ result[:rem].should == ["201011", "201012"]
518
+
519
+ result = @finder.send(:find_end_keys_for, :year, t_start, t_end, true)
520
+ result[:add].should == ["2010"]
521
+ result[:rem].should == []
522
+
523
+ end
524
+
525
+ end