time_window_drop_collector 0.0.11 → 0.1.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.
@@ -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