time_window_drop_collector 0.0.11 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,8 +3,10 @@ require "dalli"
3
3
  require_relative "time_window_drop_collector/version"
4
4
  require_relative "time_window_drop_collector/config"
5
5
  require_relative "time_window_drop_collector/logger"
6
+ require_relative "time_window_drop_collector/utils"
6
7
  require_relative "time_window_drop_collector/storage"
7
8
  require_relative "time_window_drop_collector/wrapper"
9
+ require_relative "time_window_drop_collector/results"
8
10
  require_relative "time_window_drop_collector/wrappers/memcache"
9
11
  require_relative "time_window_drop_collector/wrappers/mock"
10
12
  require_relative "time_window_drop_collector/wrappers/redis"
@@ -14,6 +16,8 @@ class TimeWindowDropCollector
14
16
  attr_reader :config, :wrapper, :storage
15
17
 
16
18
  def initialize( &block )
19
+ TimeWindowDropCollector::Logger.log "INITIALIZING version: #{TimeWindowDropCollector::VERSION}"
20
+
17
21
  @config = {
18
22
  :window => 600,
19
23
  :slices => 10,
@@ -23,15 +27,32 @@ class TimeWindowDropCollector
23
27
 
24
28
  @config.merge!( TimeWindowDropCollector::Config.extract( block ) ) if block_given?
25
29
 
30
+ TimeWindowDropCollector::Logger.log "CONFIG: #{config}"
31
+
26
32
  @wrapper = TimeWindowDropCollector::Wrapper.instance( config[:client], config[:client_opts] )
27
33
  @storage = TimeWindowDropCollector::Storage.new( wrapper, config[:window], config[:slices] )
28
34
  end
29
35
 
30
- def drop( key )
31
- storage.incr( key )
36
+ def drop( keys )
37
+ keys = [keys] unless keys.is_a? Array
38
+ keys = keys.map(&:to_s)
39
+
40
+ TimeWindowDropCollector::Logger.log "DROP keys: #{keys.join(", ")}"
41
+ storage.incr( keys )
32
42
  end
33
43
 
34
- def count( key )
35
- storage.count( key )
44
+ def count( orig_keys )
45
+ keys = orig_keys.is_a?(Array) ? orig_keys : [orig_keys]
46
+ keys = keys.map(&:to_s)
47
+
48
+ TimeWindowDropCollector::Logger.log "COUNT keys: #{keys.join(", ")}"
49
+
50
+ result = storage.count( keys )
51
+ result = TimeWindowDropCollector::Results.new( result )
52
+ result = result[orig_keys.to_s] unless orig_keys.is_a? Array
53
+
54
+ TimeWindowDropCollector::Logger.log "COUNT result: #{result}"
55
+
56
+ result
36
57
  end
37
58
  end
@@ -1,5 +1,5 @@
1
1
  module TimeWindowDropCollector::Logger
2
2
  def self.log( message )
3
- puts "[TWDC #{Time.now.strftime( "%F %T" )}] #{message}"
3
+ puts "[TWDC #{Time.now.strftime( "%F %T" )}] #{message}" if ENV["TWDC_DEBUG"]
4
4
  end
5
5
  end
@@ -0,0 +1,11 @@
1
+ class TimeWindowDropCollector::Results
2
+ attr_reader :keys_values
3
+
4
+ def initialize( keys_values )
5
+ @keys_values = keys_values
6
+ end
7
+
8
+ def []( key )
9
+ keys_values[key].to_i
10
+ end
11
+ end
@@ -1,46 +1,22 @@
1
1
  class TimeWindowDropCollector::Storage
2
+ include TimeWindowDropCollector::Utils
3
+
2
4
  attr_reader :wrapper, :window, :slices
3
5
 
4
6
  def initialize( wrapper, window, slices )
5
7
  @wrapper = wrapper
6
- @window = window
7
- @slices = slices
8
- end
9
-
10
- def incr( key )
11
- wrapper.incr( time_key( key ), window )
12
- end
13
-
14
- def count( key )
15
- time_keys = time_keys( key )
16
- values = wrapper.values_for( time_keys )
17
-
18
- values.map( &:to_i ).inject( :+ ).to_i
19
- end
20
-
21
- def time_key( key, time = timestamp )
22
- "drop_window_#{key}_#{slice_start_timestamp( time )}"
23
- end
24
-
25
- def time_keys( key )
26
- now = timestamp
27
-
28
- ( 0..( slices - 1 ) ).map{ |i|
29
- time_key( key, now - ( ( i*slice_milliseconds ) / 1000 ) )
30
- }
31
- end
32
-
33
- def timestamp
34
- Time.now
8
+ @window = window
9
+ @slices = slices
35
10
  end
36
11
 
37
- def slice_milliseconds
38
- ( window * 1000 ) / slices
12
+ def incr( keys )
13
+ wrapper.incr( timestamp_key_multi( keys ), window )
39
14
  end
40
15
 
41
- def slice_start_timestamp( time )
42
- time_milliseconds = ( time.to_f * 1000 ).truncate
16
+ def count( keys )
17
+ window_keys = window_keys_multi( keys )
18
+ keys_values = wrapper.get( window_keys )
43
19
 
44
- ( time_milliseconds / slice_milliseconds ) * slice_milliseconds
20
+ grouping_count( keys_values )
45
21
  end
46
22
  end
@@ -0,0 +1,49 @@
1
+ module TimeWindowDropCollector::Utils
2
+ def grouping_count( key_values )
3
+ groups = key_values.group_by { |k,v| k.match( /drop_window_(.*)_/ )[1] }
4
+
5
+ result = {}
6
+
7
+ groups.each do |k,v|
8
+ result[k] = v.inject(0) { |acc,e| acc += e[1].to_i }
9
+ end
10
+
11
+ result
12
+ end
13
+
14
+ def timestamp_key( key, time = timestamp )
15
+ "drop_window_#{key}_#{slice_start_timestamp( time )}"
16
+ end
17
+
18
+ def timestamp_key_multi( keys )
19
+ now = timestamp
20
+
21
+ keys.map { |key| timestamp_key( key, now ) }.flatten
22
+ end
23
+
24
+ def window_keys( key, now = timestamp )
25
+ ( 0..( slices - 1 ) ).map{ |i|
26
+ timestamp_key( key, now - ( ( i*slice_milliseconds ) / 1000 ) )
27
+ }
28
+ end
29
+
30
+ def window_keys_multi( keys )
31
+ now = timestamp
32
+
33
+ keys.map { |key| window_keys( key, now ) }.flatten
34
+ end
35
+
36
+ def timestamp
37
+ Time.now
38
+ end
39
+
40
+ def slice_milliseconds
41
+ @slice_milliseconds ||= ( window * 1000 ) / slices
42
+ end
43
+
44
+ def slice_start_timestamp( time )
45
+ time_milliseconds = ( time.to_f * 1000 ).truncate
46
+
47
+ ( time_milliseconds / slice_milliseconds ) * slice_milliseconds
48
+ end
49
+ end
@@ -1,3 +1,3 @@
1
1
  class TimeWindowDropCollector
2
- VERSION = "0.0.11"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -7,12 +7,16 @@ class TimeWindowDropCollector
7
7
  @client = Dalli::Client.new( opts )
8
8
  end
9
9
 
10
- def incr( key, expire_time )
11
- client.incr( key, 1, expire_time, 1 )
10
+ def incr( keys, expire_time )
11
+ client.multi do
12
+ keys.each do |key|
13
+ client.incr( key, 1, expire_time, 1 )
14
+ end
15
+ end
12
16
  end
13
17
 
14
- def values_for( keys )
15
- client.get_multi( keys ).values
18
+ def get( keys )
19
+ client.get_multi( keys )
16
20
  end
17
21
  end
18
22
  end
@@ -7,12 +7,14 @@ class TimeWindowDropCollector
7
7
  @client = MemcacheMock.new
8
8
  end
9
9
 
10
- def incr( key, expire_time )
11
- client.incr( key, 1, nil, 1 )
10
+ def incr( keys, expire_time )
11
+ keys.each do |key|
12
+ client.incr( key, 1, nil, 1 )
13
+ end
12
14
  end
13
15
 
14
- def values_for( keys )
15
- client.get_multi( keys ).values
16
+ def get( keys )
17
+ client.get_multi( keys )
16
18
  end
17
19
  end
18
20
  end
@@ -7,13 +7,14 @@ class TimeWindowDropCollector
7
7
  @client = Rails.cache
8
8
  end
9
9
 
10
- def incr( key, expire_time )
11
- value = client.read( key ).to_i + 1
12
- client.write( key, value, :expires_in => expire_time )
10
+ def incr( keys, expire_time )
11
+ keys.each do |key|
12
+ client.increment( key, 1, :expires_in => expire_time )
13
+ end
13
14
  end
14
15
 
15
- def values_for( keys )
16
- client.read_multi( keys ).values
16
+ def get( keys )
17
+ client.read_multi( keys )
17
18
  end
18
19
  end
19
20
  end
@@ -7,15 +7,25 @@ class TimeWindowDropCollector
7
7
  @client = ::Redis.new( opts )
8
8
  end
9
9
 
10
- def incr( key, expire_time )
10
+ def incr( keys, expire_time )
11
11
  client.multi do
12
- client.incr( key )
13
- client.expire( key, expire_time )
12
+ keys.each do |key|
13
+ client.incr( key )
14
+ client.expire( key, expire_time )
15
+ end
14
16
  end
15
17
  end
16
18
 
17
- def values_for( keys )
18
- client.mget( *keys )
19
+ def get( keys )
20
+ values = client.mget( *keys )
21
+
22
+ result = {}
23
+
24
+ keys.each_with_index do |key, i|
25
+ result[key] = values[i]
26
+ end
27
+
28
+ result
19
29
  end
20
30
  end
21
31
  end
data/test/logger_test.rb CHANGED
@@ -1,6 +1,15 @@
1
1
  require_relative "test_helper"
2
2
 
3
3
  class LoggerTest < Test::Unit::TestCase
4
+ def setup
5
+ @old_env = ENV["TWDC_DEBUG"]
6
+ ENV["TWDC_DEBUG"] = "on"
7
+ end
8
+
9
+ def teardown
10
+ ENV["TWDC_DEBUG"] = @old_env
11
+ end
12
+
4
13
  def test_log
5
14
  IO.any_instance.expects( :puts ).with( "[TWDC 2001-02-01 04:05:06] hello!" )
6
15
 
@@ -9,13 +9,14 @@ class MockWrapperTest < Test::Unit::TestCase
9
9
 
10
10
  def test_incr
11
11
  wrapper = TimeWindowDropCollector::Wrappers::Mock.new( ["arg1"] )
12
- wrapper.client.expects( :incr ).with( "key", 1, nil, 1 )
13
- wrapper.incr( "key", "expire_time" )
12
+ wrapper.client.expects( :incr ).with( "key1", 1, nil, 1 )
13
+ wrapper.client.expects( :incr ).with( "key2", 1, nil, 1 )
14
+ wrapper.incr( ["key1", "key2"], "expire_time" )
14
15
  end
15
16
 
16
17
  def test_values_for
17
18
  wrapper = TimeWindowDropCollector::Wrappers::Mock.new( ["arg1"] )
18
- wrapper.client.expects( :get_multi ).with( "keys" ).returns( {:a => 1, :b => 2} )
19
- assert_equal( [1, 2], wrapper.values_for( "keys" ))
19
+ wrapper.client.expects( :get_multi ).with( "keys" ).returns( "keys_values" )
20
+ assert_equal( "keys_values", wrapper.get( "keys" ))
20
21
  end
21
22
  end
@@ -14,15 +14,15 @@ class MemcacheWrapperTest < Test::Unit::TestCase
14
14
 
15
15
  def test_incr
16
16
  wrapper = TimeWindowDropCollector::Wrappers::RailsCache.new( ["arg1"] )
17
- wrapper.client.expects( :read ).with( "key" ).returns( 2 )
18
- wrapper.client.expects( :write ).with( "key", 3, :expires_in => "expire_time" )
17
+ wrapper.client.expects( :increment ).with( "key1", 1, :expires_in => "expire_time" )
18
+ wrapper.client.expects( :increment ).with( "key2", 1, :expires_in => "expire_time" )
19
19
 
20
- wrapper.incr( "key", "expire_time" )
20
+ wrapper.incr( ["key1", "key2"], "expire_time" )
21
21
  end
22
22
 
23
23
  def test_values_for
24
24
  wrapper = TimeWindowDropCollector::Wrappers::RailsCache.new( ["arg1"] )
25
- wrapper.client.expects( :read_multi ).with( "keys" ).returns( {:a => 1, :b => 2} )
26
- assert_equal( [1, 2], wrapper.values_for( "keys" ))
25
+ wrapper.client.expects( :read_multi ).with( "keys" ).returns( "keys_values" )
26
+ assert_equal( "keys_values", wrapper.get( "keys" ))
27
27
  end
28
28
  end
@@ -21,10 +21,13 @@ class RedisWrapperTest < Test::Unit::TestCase
21
21
  Redis.expects( :new ).returns( RedisMock.new )
22
22
  wrapper = TimeWindowDropCollector::Wrappers::Redis.new( nil )
23
23
 
24
- wrapper.client.expects( :incr ).with( "key" )
25
- wrapper.client.expects( :expire ).with( "key", "expire_time" )
24
+ wrapper.client.expects( :incr ).with( "key1" )
25
+ wrapper.client.expects( :expire ).with( "key1", "expire_time" )
26
26
 
27
- wrapper.incr( "key", "expire_time" )
27
+ wrapper.client.expects( :incr ).with( "key2" )
28
+ wrapper.client.expects( :expire ).with( "key2", "expire_time" )
29
+
30
+ wrapper.incr( ["key1", "key2"], "expire_time" )
28
31
  end
29
32
 
30
33
  def test_incr_agregates_commands_under_multi
@@ -36,12 +39,12 @@ class RedisWrapperTest < Test::Unit::TestCase
36
39
  wrapper.incr( nil, nil )
37
40
  end
38
41
 
39
- def test_values_for
42
+ def test_get
40
43
  Redis.expects( :new ).returns( RedisMock.new )
41
44
  wrapper = TimeWindowDropCollector::Wrappers::Redis.new( nil )
42
45
 
43
46
  wrapper.client.expects( :mget ).with( "key1", "key2" ).returns( [1, 2] )
44
47
 
45
- assert_equal( [1, 2], wrapper.values_for( ["key1", "key2"] ))
48
+ assert_equal( { "key1" => 1, "key2" => 2 }, wrapper.get( ["key1", "key2"] ))
46
49
  end
47
50
  end
data/test/storage_test.rb CHANGED
@@ -2,21 +2,21 @@ require_relative "test_helper"
2
2
 
3
3
  class StorageTest < Test::Unit::TestCase
4
4
  def setup
5
- @client = mock()
6
- @storage = TimeWindowDropCollector::Storage.new( @client, 600, 10 )
5
+ @wrapper = mock()
6
+ @storage = TimeWindowDropCollector::Storage.new( @wrapper, 600, 10 )
7
7
  end
8
8
 
9
- def test_time_key_when_time_is_present
9
+ def test_timestamp_key_when_time_is_present
10
10
  timestamp = Time.new( 2001, 2, 3, 4, 5 )
11
- assert_equal( "drop_window_key_981169500000", @storage.time_key( "key", timestamp ) )
11
+ assert_equal( "drop_window_key_981169500000", @storage.timestamp_key( "key", timestamp ) )
12
12
  end
13
13
 
14
- def test_time_key_when_time_is_not_present
14
+ def test_timestamp_key_when_time_is_not_present
15
15
  @storage.stubs( :timestamp ).returns( Time.new( 2012, 4, 3, 2, 1 ))
16
- assert_equal( "drop_window_key_1333411260000", @storage.time_key( "key" ))
16
+ assert_equal( "drop_window_key_1333411260000", @storage.timestamp_key( "key" ))
17
17
  end
18
18
 
19
- def test_time_keys_should_return_10_keys_for_the_last_10_minutes
19
+ def test_window_keys_should_return_10_keys_for_the_last_10_minutes
20
20
  keys = [
21
21
  "drop_window_key_1325560800000",
22
22
  "drop_window_key_1325560740000",
@@ -31,56 +31,87 @@ class StorageTest < Test::Unit::TestCase
31
31
  ]
32
32
 
33
33
  Delorean.time_travel_to( '2012-01-03 04:20' ) do
34
- assert_equal( keys, @storage.time_keys( "key" ))
34
+ assert_equal( keys, @storage.window_keys( "key" ))
35
35
  end
36
36
  end
37
37
 
38
38
  def test_incr
39
- @storage.expects( :time_key ).with( "key" ).returns( "time_key" )
40
- @client.expects( :incr ).with( "time_key", 600 )
39
+ @storage.expects( :timestamp_key_multi ).with( ["keys"] ).returns( "timestamp_keys" )
40
+ @wrapper.expects( :incr ).with( "timestamp_keys", 600 )
41
41
 
42
- @storage.incr( "key" )
42
+ @storage.incr( ["keys"] )
43
43
  end
44
44
 
45
45
  def test_count
46
- keys = [
47
- "drop_window_key_201201031416",
48
- "drop_window_key_201201031415",
49
- "drop_window_key_201201031414",
50
- "drop_window_key_201201031413",
51
- "drop_window_key_201201031412"
52
- ]
46
+ @storage.expects( :window_keys_multi ).with( "keys" ).returns( "window_keys" )
47
+ @wrapper.expects( :get ).with( "window_keys" ).returns( "keys_values" )
48
+ @storage.expects( :grouping_count ).with( "keys_values" ).returns( "grouping_keys_counts" )
53
49
 
54
- values = [nil, 1, "2", 3, 4, 5]
50
+ assert_equal( "grouping_keys_counts", @storage.count( "keys" ))
51
+ end
52
+
53
+ def test_grouping_count
54
+ key_values = {
55
+ "drop_window_key1_201201031416" => 1,
56
+ "drop_window_key1_201201031415" => 2,
57
+ "drop_window_key1_201201031414" => 3,
58
+ "drop_window_key1_201201031413" => 4,
59
+ "drop_window_key1_201201031412" => 5,
60
+ "drop_window_key2_201201031413" => 6,
61
+ "drop_window_key2_201201031412" => 7
62
+ }
63
+
64
+ key_counts = @storage.grouping_count( key_values )
65
+
66
+ assert_equal( 15, key_counts["key1"])
67
+ assert_equal( 13, key_counts["key2"])
68
+ end
55
69
 
56
- @storage.expects( :time_keys ).with( "key" ).returns( "keys" )
57
- @client.expects( :values_for ).with( "keys" ).returns( values )
70
+ def test_grouping_count_with_nil_values
71
+ key_values = {
72
+ "drop_window_key1_201201031416" => 1,
73
+ "drop_window_key1_201201031414" => nil,
74
+ "drop_window_key2_201201031413" => 6,
75
+ "drop_window_key2_201201031412" => 7,
76
+ "drop_window_key3_201201031412" => nil
77
+ }
58
78
 
59
- assert_equal( 15, @storage.count( "key" ))
79
+ key_counts = @storage.grouping_count( key_values )
80
+
81
+ assert_equal( 1, key_counts["key1"])
82
+ assert_equal( 13, key_counts["key2"])
83
+ assert_equal( 0, key_counts["key3"])
60
84
  end
61
85
 
62
- def test_count_when_empty_values
63
- @storage.stubs( :time_keys )
64
- @client.expects( :values_for ).returns( [] )
65
- assert_equal( 0, @storage.count( "key" ))
86
+ def test_grouping_when_not_key
87
+ key_values = {
88
+ "drop_window_key1_201201031416" => 1,
89
+ "drop_window_key2_201201031412" => 7
90
+ }
91
+
92
+ key_counts = @storage.grouping_count( key_values )
93
+
94
+ assert_equal( 1, key_counts["key1"])
95
+ assert_equal( 7, key_counts["key2"])
96
+ assert_equal( nil, key_counts["key3"])
66
97
  end
67
98
 
68
99
  def test_integration_count
69
100
  client = TimeWindowDropCollector::Wrapper.instance( :mock )
70
101
  storage = TimeWindowDropCollector::Storage.new( client, 600, 10 )
71
102
 
72
- key_1 = 1
73
- key_2 = 2
74
- key_3 = 3
103
+ storage.incr( ["key_1"] )
104
+ storage.incr( ["key_2"] )
105
+ storage.incr( ["key_3"] )
106
+ storage.incr( ["key_2"] )
107
+ storage.incr( ["key_2", "key_1"] )
75
108
 
76
- storage.incr( key_1 )
77
- storage.incr( key_2 )
78
- storage.incr( key_3 )
79
- storage.incr( key_2 )
109
+ keys_values = storage.count( ["key_1", "key_2", "key_3", "key_4"] )
80
110
 
81
- assert_equal( 1, storage.count( key_1 ))
82
- assert_equal( 2, storage.count( key_2 ))
83
- assert_equal( 1, storage.count( key_3 ))
111
+ assert_equal( 2, keys_values["key_1"])
112
+ assert_equal( 3, keys_values["key_2"])
113
+ assert_equal( 1, keys_values["key_3"])
114
+ assert_equal( nil, keys_values["key_4"])
84
115
  end
85
116
 
86
117
  def test_slice_start_timestamp
@@ -156,79 +187,77 @@ class StorageTest < Test::Unit::TestCase
156
187
  client = TimeWindowDropCollector::Wrapper.instance( :mock )
157
188
  storage = TimeWindowDropCollector::Storage.new( client, 600, 10 )
158
189
 
159
- key_1 = 1
160
-
161
190
  Delorean.time_travel_to( '2012-01-03 11:00' ) do
162
- storage.incr( key_1 )
191
+ storage.incr( ["key_1"] )
163
192
  end
164
193
 
165
194
  Delorean.time_travel_to( '2012-01-03 11:01' ) do
166
- storage.incr( key_1 )
195
+ storage.incr( ["key_1"] )
167
196
  end
168
197
 
169
198
  Delorean.time_travel_to( '2012-01-03 11:02' ) do
170
- storage.incr( key_1 )
199
+ storage.incr( ["key_1"] )
171
200
  end
172
201
 
173
202
  Delorean.time_travel_to( '2012-01-03 11:03' ) do
174
- storage.incr( key_1 )
203
+ storage.incr( ["key_1"] )
175
204
  end
176
205
 
177
206
  Delorean.time_travel_to( '2012-01-03 11:04' ) do
178
- storage.incr( key_1 )
207
+ storage.incr( ["key_1"] )
179
208
  end
180
209
 
181
210
  Delorean.time_travel_to( '2012-01-03 11:05' ) do
182
- storage.incr( key_1 )
211
+ storage.incr( ["key_1"] )
183
212
  end
184
213
 
185
214
  Delorean.time_travel_to( '2012-01-03 11:06' ) do
186
- storage.incr( key_1 )
215
+ storage.incr( ["key_1"] )
187
216
  end
188
217
 
189
218
  Delorean.time_travel_to( '2012-01-03 11:07' ) do
190
- storage.incr( key_1 )
219
+ storage.incr( ["key_1"] )
191
220
  end
192
221
 
193
222
  Delorean.time_travel_to( '2012-01-03 11:08' ) do
194
- storage.incr( key_1 )
223
+ storage.incr( ["key_1"] )
195
224
  end
196
225
 
197
226
  Delorean.time_travel_to( '2012-01-03 11:09' ) do
198
- storage.incr( key_1 )
227
+ storage.incr( ["key_1"] )
199
228
  end
200
229
 
201
230
  Delorean.time_travel_to( '2012-01-03 11:10' ) do
202
- storage.incr( key_1 )
231
+ storage.incr( ["key_1"] )
203
232
  end
204
233
 
205
234
  # counters
206
235
  Delorean.time_travel_to( '2012-01-03 10:59' ) do
207
- assert_equal( 0, storage.count( key_1 ))
236
+ assert_equal( nil, storage.count( ["key_1"] )["key_1"] )
208
237
  end
209
238
 
210
239
  Delorean.time_travel_to( '2012-01-03 11:00' ) do
211
- assert_equal( 1, storage.count( key_1 ))
240
+ assert_equal( 1, storage.count( ["key_1"] )["key_1"] )
212
241
  end
213
242
 
214
243
  Delorean.time_travel_to( '2012-01-03 11:05' ) do
215
- assert_equal( 6, storage.count( key_1 ))
244
+ assert_equal( 6, storage.count( ["key_1"] )["key_1"] )
216
245
  end
217
246
 
218
247
  Delorean.time_travel_to( '2012-01-03 11:10' ) do
219
- assert_equal( 10, storage.count( key_1 ))
248
+ assert_equal( 10, storage.count( ["key_1"] )["key_1"])
220
249
  end
221
250
 
222
251
  Delorean.time_travel_to( '2012-01-03 11:15' ) do
223
- assert_equal( 5, storage.count( key_1 ))
252
+ assert_equal( 5, storage.count( ["key_1"] )["key_1"] )
224
253
  end
225
254
 
226
255
  Delorean.time_travel_to( '2012-01-03 11:19' ) do
227
- assert_equal( 1, storage.count( key_1 ))
256
+ assert_equal( 1, storage.count( ["key_1"] )["key_1"] )
228
257
  end
229
258
 
230
259
  Delorean.time_travel_to( '2012-01-03 11:20' ) do
231
- assert_equal( 0, storage.count( key_1 ))
260
+ assert_equal( nil, storage.count( ["key_1"] )["key_1"] )
232
261
  end
233
262
  end
234
263
  end
@@ -2,7 +2,6 @@ require_relative "test_helper"
2
2
 
3
3
  class TimeWindowDropCollectorTest < Test::Unit::TestCase
4
4
  def setup
5
- @twdc = TimeWindowDropCollector::Logger.stubs( :log )
6
5
  end
7
6
 
8
7
  def test_initialize_with_empty_config
@@ -34,7 +33,7 @@ class TimeWindowDropCollectorTest < Test::Unit::TestCase
34
33
 
35
34
  def test_drop
36
35
  storage = mock()
37
- storage.expects( :incr ).with( "key" )
36
+ storage.expects( :incr ).with( ["key"] )
38
37
 
39
38
  twdc = TimeWindowDropCollector.new
40
39
  twdc.stubs( :storage ).returns( storage )
@@ -44,12 +43,12 @@ class TimeWindowDropCollectorTest < Test::Unit::TestCase
44
43
 
45
44
  def test_count
46
45
  storage = mock()
47
- storage.expects( :count ).with( "key" )
46
+ storage.expects( :count ).with( ["key"] ).returns( { "key" => 10 } )
48
47
 
49
48
  twdc = TimeWindowDropCollector.new
50
49
  twdc.stubs( :storage ).returns( storage )
51
50
 
52
- twdc.count( "key" )
51
+ assert_equal( 10, twdc.count( "key" ) )
53
52
  end
54
53
 
55
54
  def test_integration_new
@@ -67,4 +66,45 @@ class TimeWindowDropCollectorTest < Test::Unit::TestCase
67
66
  assert_equal( 100, twdc.storage.window )
68
67
  assert_equal( 20, twdc.storage.slices )
69
68
  end
69
+
70
+ def test_integration_drop_and_count
71
+ twdc = TimeWindowDropCollector.new { client :mock }
72
+
73
+ twdc.drop( "key_1" )
74
+ twdc.drop( "key_1" )
75
+ twdc.drop( "key_2" )
76
+ twdc.drop( "key_2" )
77
+ twdc.drop( ["key_2"] )
78
+ twdc.drop( ["key_3", "key_4", "key_5"] )
79
+
80
+ assert_equal( 2, twdc.count( "key_1" ) )
81
+ assert_equal( 3, twdc.count( "key_2" ) )
82
+ assert_equal( 1, twdc.count( "key_3" ) )
83
+ assert_equal( 1, twdc.count( "key_4" ) )
84
+ assert_equal( 1, twdc.count( "key_5" ) )
85
+ assert_equal( 0, twdc.count( "key_6" ) )
86
+
87
+ assert_equal( 2, twdc.count( ["key_1", "key_2"] )["key_1"] )
88
+ assert_equal( 3, twdc.count( ["key_1", "key_2"] )["key_2"] )
89
+ assert_equal( 0, twdc.count( ["key_6"] )["key_6"] )
90
+ end
91
+
92
+ def test_integration_drop_array_keys
93
+ twdc = TimeWindowDropCollector.new { client :mock }
94
+
95
+ twdc.drop( ["key_1", "key_2"] )
96
+
97
+ assert_equal( 1, twdc.count( "key_1" ) )
98
+ assert_equal( 1, twdc.count( "key_2" ) )
99
+ end
100
+
101
+ def test_integration_drop_and_count_with_numerical_keys
102
+ twdc = TimeWindowDropCollector.new { client :mock }
103
+
104
+ twdc.drop( 1000 )
105
+ twdc.drop( [1001])
106
+
107
+ assert_equal( 1, twdc.count( 1000 ) )
108
+ assert_equal( 1, twdc.count( 1001 ) )
109
+ end
70
110
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: time_window_drop_collector
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-01-25 00:00:00.000000000Z
13
+ date: 2012-01-26 00:00:00.000000000Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
17
- requirement: &70114503076580 !ruby/object:Gem::Requirement
17
+ requirement: &70135818124120 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - =
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 1.0.21
23
23
  type: :development
24
24
  prerelease: false
25
- version_requirements: *70114503076580
25
+ version_requirements: *70135818124120
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rake
28
- requirement: &70114503076080 !ruby/object:Gem::Requirement
28
+ requirement: &70135818123620 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - =
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: 0.9.2.2
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *70114503076080
36
+ version_requirements: *70135818123620
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: mocha
39
- requirement: &70114503075620 !ruby/object:Gem::Requirement
39
+ requirement: &70135818123160 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - =
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: 0.10.0
45
45
  type: :development
46
46
  prerelease: false
47
- version_requirements: *70114503075620
47
+ version_requirements: *70135818123160
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: delorean
50
- requirement: &70114503075160 !ruby/object:Gem::Requirement
50
+ requirement: &70135818122700 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - =
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: 1.2.0
56
56
  type: :development
57
57
  prerelease: false
58
- version_requirements: *70114503075160
58
+ version_requirements: *70135818122700
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: memcache_mock
61
- requirement: &70114503074700 !ruby/object:Gem::Requirement
61
+ requirement: &70135818122240 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - =
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: 0.0.1
67
67
  type: :development
68
68
  prerelease: false
69
- version_requirements: *70114503074700
69
+ version_requirements: *70135818122240
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: dalli
72
- requirement: &70114503074320 !ruby/object:Gem::Requirement
72
+ requirement: &70135818121860 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ! '>='
@@ -77,7 +77,7 @@ dependencies:
77
77
  version: '0'
78
78
  type: :runtime
79
79
  prerelease: false
80
- version_requirements: *70114503074320
80
+ version_requirements: *70135818121860
81
81
  description: Counter storage system for a concrete time window
82
82
  email:
83
83
  - fguillen.mail@gmail.com
@@ -95,7 +95,9 @@ files:
95
95
  - lib/time_window_drop_collector.rb
96
96
  - lib/time_window_drop_collector/config.rb
97
97
  - lib/time_window_drop_collector/logger.rb
98
+ - lib/time_window_drop_collector/results.rb
98
99
  - lib/time_window_drop_collector/storage.rb
100
+ - lib/time_window_drop_collector/utils.rb
99
101
  - lib/time_window_drop_collector/version.rb
100
102
  - lib/time_window_drop_collector/wrapper.rb
101
103
  - lib/time_window_drop_collector/wrappers/memcache.rb