top_n 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a5fc5435e211281c5d59fa26d155260a0359a216
4
- data.tar.gz: f3cd1bf16b9c9c11ad87793a7c0741e1fe7f314a
3
+ metadata.gz: cda9c5805aaeda70a3ea35e8a01314a96e071cd5
4
+ data.tar.gz: f581488f6929408afe40e98567b076fc1d09f42f
5
5
  SHA512:
6
- metadata.gz: 471670b61a3b91ff867fab94bcd414a9f766fb7367579122ea57d5f4d58e7b964e4551d77bb4ce35a4b2523df7282dce8a845791c0c8c7677ff4ec46c82b4071
7
- data.tar.gz: 24330b140e01c80493d4434720672bef428825bbb8a6133ab234443c77bf498583f4c91360e2a33524da9d4e02a20814ec450a33ed14498a3dbe1c6b435eb08b
6
+ metadata.gz: f55b87b0711b17b8fee03294baffa347c1df8fb92f010198418870ed5a337a2559358e76cd4a92ded26c424da9e9a9abfea7ef9bea9c744723a3cd3a62b8d2b4
7
+ data.tar.gz: dab46fa2befd85a4edc51c5c7bef1f4f41b43e1e57ee2aaae0ff5031cf1a0e6fb458f58261e6ca7b20dd5de288edd6bf625d57acc5f0bc942d5a06249f6e19e3
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0
1
+ 1.0.1
@@ -66,6 +66,12 @@ class TopN
66
66
  direction: :top,
67
67
  }.merge(options)
68
68
 
69
+ options.keys.each do |opt|
70
+ unless [:maxsize, :direction].include?opt
71
+ raise ArgumentError.new("invalid option #{opt}")
72
+ end
73
+ end
74
+
69
75
  @maxsize = options[:maxsize]
70
76
  @direction = options[:direction]
71
77
  @data = {}
@@ -137,20 +143,20 @@ class TopN
137
143
  def add_top(key, value)
138
144
  @threshold_key ||= key
139
145
 
140
- if @size >= @maxsize
141
- return nil if key < @threshold_key
142
- @data.delete(@threshold_key)
143
- end
144
-
145
- unless @data.has_key?key
146
- @data[key] = []
147
- @size += 1 if @size < @maxsize
146
+ if @data.has_key?key
147
+ @data[key] << value
148
+ else
149
+ if @size >= @maxsize
150
+ return nil if key < @threshold_key
151
+ @data.delete(@threshold_key)
152
+ @size -= 1
153
+ @threshold_key = @data.keys.min
154
+ end
155
+ @data[key] = [ value ]
156
+ @size += 1
157
+ @threshold_key = key if key < @threshold_key
148
158
  end
149
159
 
150
- @data[key] << value
151
-
152
- @threshold_key = key if key < @threshold_key
153
-
154
160
  @data[key]
155
161
  end
156
162
 
@@ -159,20 +165,20 @@ class TopN
159
165
  def add_bottom(key, value)
160
166
  @threshold_key ||= key
161
167
 
162
- if @size >= @maxsize
163
- return nil if key > @threshold_key
164
- @data.delete(@threshold_key)
165
- end
166
-
167
- unless @data.has_key?key
168
- @data[key] = []
169
- @size += 1 if @size < @maxsize
168
+ if @data.has_key?key
169
+ @data[key] << value
170
+ else
171
+ if @size >= @maxsize
172
+ return nil if key > @threshold_key
173
+ @data.delete(@threshold_key)
174
+ @size -= 1
175
+ @threshold_key = @data.keys.max
176
+ end
177
+ @data[key] = [ value ]
178
+ @size += 1
179
+ @threshold_key = key if key > @threshold_key
170
180
  end
171
181
 
172
- @data[key] << value
173
-
174
- @threshold_key = key if key > @threshold_key
175
-
176
182
  @data[key]
177
183
  end
178
184
  end
@@ -85,4 +85,19 @@ class TestAddingBottom < Minitest::Test
85
85
  assert_equal [2], topn.find(2)
86
86
  assert_nil topn.find(3)
87
87
  end
88
+
89
+ def test_torture
90
+ topn = TopN.new(direction: :bottom, maxsize: 10)
91
+
92
+ records = []
93
+ 300_000.times do
94
+ record = rand(4000)
95
+ records << record
96
+ topn.add(record, rand(100_000_000))
97
+ end
98
+
99
+ top_records = records.uniq.sort[0..9]
100
+ keys = topn.keys.sort
101
+ assert_equal top_records, keys
102
+ end
88
103
  end
@@ -85,4 +85,19 @@ class TestAddingTop < Minitest::Test
85
85
  assert_equal [2], topn.find(2)
86
86
  assert_equal [3], topn.find(3)
87
87
  end
88
+
89
+ def test_torture
90
+ topn = TopN.new(maxsize: 1000)
91
+
92
+ records = []
93
+ 300_000.times do
94
+ record = rand(4000)
95
+ records << record
96
+ topn.add(record, rand(100_000_000))
97
+ end
98
+
99
+ top_records = records.uniq.sort { |a, b| b <=> a }[0..999]
100
+ keys = topn.keys.sort { |a, b| b <=> a }
101
+ assert_equal top_records, keys
102
+ end
88
103
  end
@@ -44,4 +44,10 @@ class TestTopN < Minitest::Test
44
44
  TopN.new(maxsize: 'foo')
45
45
  }
46
46
  end
47
+
48
+ def test_creation_raises_assertion_for_invalid_argument_names
49
+ assert_raises(ArgumentError) {
50
+ TopN.new(flarg: 1)
51
+ }
52
+ end
47
53
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "top_n"
8
- s.version = "1.0.0"
8
+ s.version = "1.0.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Michael Graff"]
12
- s.date = "2013-12-15"
12
+ s.date = "2013-12-16"
13
13
  s.description = "Track the top (or bottom) N keys added to a list, and discard the remainder."
14
14
  s.email = "explorer@flame.org"
15
15
  s.extra_rdoc_files = [
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: top_n
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Graff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-15 00:00:00.000000000 Z
11
+ date: 2013-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest