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