uv-priority-queue 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ce2839b2762f789c1ae3f558340d78f26385f31d
4
+ data.tar.gz: 75ebd539b5be58167c80b6b9cc8d1be0bef1f4d7
5
+ SHA512:
6
+ metadata.gz: c5f1cfffa15a6ab557fd6809bd3c5bf995a7c0a2f42df8b0fd26682bc664cbb8db2565e7a4b19076186c43a77138387107bb52a3cd24e645d169011f7e771eab
7
+ data.tar.gz: 3dc35beeaadab01635c0284250dd8f52fc862c2654bb51967afa3ac0c2c99197dd90b004bbc083fd55f3f4121b364f60b206edc74d8019698d2250f7bdc50169
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 CoTag Media
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,139 @@
1
+ Libuv Priority Queue
2
+ =============
3
+
4
+ [![Build Status](https://secure.travis-ci.org/cotag/uv-priority-queue.png)](http://travis-ci.org/cotag/uv-priority-queue)
5
+
6
+
7
+ ##Install
8
+ [sudo] gem install uv-priority-queue
9
+
10
+ ##Usage
11
+
12
+ **Basic**
13
+
14
+ @q = UV::PriorityQueue.new
15
+
16
+ responses = []
17
+ loop = Libuv::Loop.default
18
+ loop.run do
19
+
20
+
21
+ @q.push("Mike", 20)
22
+ @q.push("Alex", 21)
23
+ @q.push("Bob", 22)
24
+ @q.push("Tim", 18)
25
+
26
+ 4.times do
27
+ @q.pop do |e|
28
+ responses << e
29
+ loop.stop if responses.size == 4
30
+ end
31
+ end
32
+ end
33
+
34
+ responses[0] # Bob
35
+ responses[1] # Alex
36
+ responses[2] # Mike
37
+ responses[3] # Tim
38
+
39
+ **Custom Priority**
40
+
41
+ @q = UV::PriorityQueue.new {|x,y| x < y}
42
+
43
+ responses = []
44
+ loop = Libuv::Loop.default
45
+ loop.run do
46
+
47
+ @q.push("Mike", 20)
48
+ @q.push("Alex", 21)
49
+ @q.push("Bob", 22)
50
+ @q.push("Tim", 18)
51
+
52
+ 4.times do
53
+ @q.pop do |e|
54
+ responses << e
55
+ loop.stop if responses.size == 4
56
+ end
57
+ end
58
+ end
59
+
60
+ responses[0] # Tim
61
+ responses[1] # Mike
62
+ responses[2] # Alex
63
+ responses[3] # Bob
64
+
65
+
66
+ **FIFO (first in, first out)**
67
+
68
+ When values have the same priority, you may want to use FIFO to prioritize even more. This way, em-priority-queue will pop the items in the order that they were pushed.
69
+
70
+ @q = UV::PriorityQueue.new(:fifo => true)
71
+
72
+ responses = []
73
+ loop = Libuv::Loop.default
74
+ loop.run do
75
+ @q.push("Mike", 20)
76
+ @q.push("Alex", 21)
77
+ @q.push("Bob", 20)
78
+ @q.push("Tim", 18)
79
+ @q.push("Carol", 20)
80
+
81
+ 5.times do
82
+ @q.pop do |e|
83
+ responses << e
84
+ loop.stop if responses.size == 5
85
+ end
86
+ end
87
+ end
88
+
89
+ responses[0] # Alex
90
+ responses[1] # Mike
91
+ responses[2] # Bob
92
+ responses[3] # Carol
93
+ responses[4] # Tim
94
+
95
+ **FIFO with custom priority**
96
+
97
+ @q = UV::PriorityQueue.new(:fifo => true) {|x,y| x < y}
98
+
99
+ responses = []
100
+ loop = Libuv::Loop.default
101
+ loop.run do
102
+
103
+
104
+ @q.push("Mike", 20)
105
+ @q.push("Alex", 21)
106
+ @q.push("Bob", 20)
107
+ @q.push("Tim", 18)
108
+ @q.push("Carol", 20)
109
+
110
+ 5.times do
111
+ @q.pop do |e|
112
+ responses << e
113
+ loop.stop if responses.size == 5
114
+ end
115
+ end
116
+ end
117
+
118
+ responses[0] # Tim
119
+ responses[1] # Mike
120
+ responses[2] # Bob
121
+ responses[3] # Carol
122
+ responses[4] # Alex
123
+
124
+
125
+
126
+
127
+
128
+ To see all examples/cases, see the spec file.
129
+
130
+
131
+ ##License
132
+
133
+ Copyright (c) 2011 Mike Lewis
134
+
135
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
136
+
137
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
138
+
139
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,9 @@
1
+ require 'bundler'
2
+ include Rake::DSL
3
+ Bundler::GemHelper.install_tasks
4
+
5
+ require 'rspec/core/rake_task'
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task :default => :spec
9
+ task :test => :spec
@@ -0,0 +1,4 @@
1
+ require 'libuv'
2
+ require 'algorithms'
3
+
4
+ require 'uv-priority-queue/priority_queue'
@@ -0,0 +1,68 @@
1
+ module UV
2
+ class PriorityQueue
3
+ include Enumerable
4
+
5
+ def initialize(opts = {}, loop = ::Libuv::Loop.current, &blk)
6
+ blk ||= lambda { |x, y| (x <=> y) == 1 }
7
+ fifo_blk = nil
8
+ @fifo = !!opts[:fifo]
9
+ if @fifo
10
+ fifo_blk = lambda do |x,y|
11
+ if x[0] == y[0]
12
+ x[1] < y[1]
13
+ else
14
+ blk.call(x[0], y[0])
15
+ end
16
+ end
17
+ end
18
+ @heap = Containers::Heap.new(&(fifo_blk || blk))
19
+ @callbacks = []
20
+ @loop = loop || ::Libuv::Loop.default
21
+ end
22
+
23
+ def size
24
+ @heap.size
25
+ end
26
+
27
+ def push(obj, pri)
28
+ pri = [pri, Time.now.to_i] if @fifo
29
+ @loop.schedule do
30
+ @heap.push(pri, obj)
31
+ @callbacks.shift.call(@heap.pop) until @heap.empty? || @callbacks.empty?
32
+ end
33
+ end
34
+
35
+ def clear
36
+ @heap.clear
37
+ end
38
+
39
+ def empty?
40
+ @heap.empty?
41
+ end
42
+
43
+ def has_priority?(priority)
44
+ @heap.has_key?(priority)
45
+ end
46
+
47
+ def next
48
+ @heap.next
49
+ end
50
+
51
+ def pop(callback = nil, &blk)
52
+ callback ||= blk
53
+ @loop.schedule do
54
+ if @heap.empty?
55
+ @callbacks << callback
56
+ else
57
+ callback.call @heap.pop
58
+ end
59
+ end
60
+ nil
61
+ end
62
+
63
+ def delete(pri)
64
+ @heap.delete(pri)
65
+ end
66
+
67
+ end
68
+ end
@@ -0,0 +1,5 @@
1
+ module UV
2
+ class PriorityQueue
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ $:.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'uv-priority-queue'
3
+ require 'delorean'
4
+
5
+ RSpec.configure do |config|
6
+ config.include Delorean
7
+ config.after(:each) { back_to_the_present }
8
+
9
+ end
@@ -0,0 +1,267 @@
1
+ require 'spec_helper'
2
+
3
+ describe UV::PriorityQueue do
4
+
5
+ before do
6
+ @q = UV::PriorityQueue.new
7
+ end
8
+
9
+ context "Reg. Queue" do
10
+ it "should return 0 for size and be empty" do
11
+ @q.size.should == 0
12
+ @q.empty?.should == true
13
+ end
14
+
15
+ it "should should push things onto the queue" do
16
+ loop = Libuv::Loop.default
17
+ loop.run do
18
+ 5.times do |i|
19
+ @q.push(i, 1)
20
+ end
21
+ loop.stop
22
+ end
23
+
24
+ @q.size.should == 5
25
+ end
26
+
27
+ it "should pop elements after adding them" do
28
+ responses = []
29
+ loop = Libuv::Loop.default
30
+ loop.run do
31
+ 5.times do |i|
32
+ @q.push(i, 1)
33
+ end
34
+
35
+ 5.times do
36
+ @q.pop do |e|
37
+ responses << e
38
+ loop.stop if @q.empty?
39
+ end
40
+ end
41
+ end
42
+
43
+ responses.length.should == 5
44
+ [0,1,2,3,4].each do |n|
45
+ responses.should include(n)
46
+ end
47
+ end
48
+
49
+ it "should pop elements if there are callbacks waiting for pushes" do
50
+ responses = []
51
+ loop = Libuv::Loop.default
52
+ loop.run do
53
+ 3.times do
54
+ @q.pop do |e|
55
+ responses << e
56
+ loop.stop if responses.size == 3
57
+ end
58
+ end
59
+
60
+ 5.times do |n|
61
+ @q.push(n, 1)
62
+ end
63
+ end
64
+ responses.length.should == 3
65
+ [0,1,2].each do |n|
66
+ responses.should include(n)
67
+ end
68
+ end
69
+ end
70
+
71
+ context "Priority Queue" do
72
+ it "should give elements in the order of their priority" do
73
+ responses = []
74
+ loop = Libuv::Loop.default
75
+ loop.run do
76
+
77
+
78
+ @q.push("Mike", 20)
79
+ @q.push("Alex", 21)
80
+ @q.push("Bob", 22)
81
+ @q.push("Tim", 18)
82
+
83
+ 4.times do
84
+ @q.pop do |e|
85
+ responses << e
86
+ loop.stop if responses.size == 4
87
+ end
88
+ end
89
+ end
90
+
91
+ responses[0].should == "Bob"
92
+ responses[1].should == "Alex"
93
+ responses[2].should == "Mike"
94
+ responses[3].should == "Tim"
95
+
96
+ end
97
+
98
+ it "should create a fifo priority queue if specified" do
99
+ fifo_queue = UV::PriorityQueue.new(:fifo => true)
100
+ responses = []
101
+ loop = Libuv::Loop.default
102
+ loop.run do
103
+ fifo_queue.push("Checking1", 20)
104
+ Delorean.jump 30
105
+ fifo_queue.push("Other1", 16)
106
+ Delorean.jump 30
107
+ fifo_queue.push("Other2", 18)
108
+ Delorean.jump 30
109
+ fifo_queue.push("Checking2", 20)
110
+ Delorean.jump 30
111
+ fifo_queue.push("Checking3", 20)
112
+ Delorean.jump 30
113
+ fifo_queue.push("Checking4", 20)
114
+ Delorean.jump 30
115
+ fifo_queue.push("Checking5", 20)
116
+ Delorean.jump 30
117
+ fifo_queue.push("Checking6", 20)
118
+ Delorean.jump 30
119
+ fifo_queue.push("Other3", 33)
120
+ Delorean.jump 30
121
+ fifo_queue.push("Checking7", 20)
122
+ Delorean.jump 30
123
+ fifo_queue.push("Checking8", 20)
124
+ Delorean.jump 30
125
+
126
+ 11.times do
127
+ fifo_queue.pop do |e|
128
+ responses << e
129
+ loop.stop if responses.size == 4
130
+ end
131
+ end
132
+
133
+ end
134
+
135
+ responses.first(5).should == ["Other3", "Checking1", "Checking2", "Checking3", "Checking4"]
136
+
137
+ end
138
+ it "should create a fifo priority queue if specified - custom ordering schema" do
139
+ fifo_queue = UV::PriorityQueue.new(:fifo => true) {|x,y| x < y}
140
+ responses = []
141
+ loop = Libuv::Loop.default
142
+ loop.run do
143
+ fifo_queue.push("Checking1", 20)
144
+ Delorean.jump 30
145
+ fifo_queue.push("Other1", 16)
146
+ Delorean.jump 30
147
+ fifo_queue.push("Other2", 18)
148
+ Delorean.jump 30
149
+ fifo_queue.push("Checking2", 20)
150
+ Delorean.jump 30
151
+ fifo_queue.push("Checking3", 20)
152
+ Delorean.jump 30
153
+ fifo_queue.push("Checking4", 20)
154
+ Delorean.jump 30
155
+ fifo_queue.push("Checking5", 20)
156
+ Delorean.jump 30
157
+ fifo_queue.push("Checking6", 20)
158
+ Delorean.jump 30
159
+ fifo_queue.push("Other3", 33)
160
+ Delorean.jump 30
161
+ fifo_queue.push("Checking7", 20)
162
+ Delorean.jump 30
163
+ fifo_queue.push("Checking8", 20)
164
+ Delorean.jump 30
165
+
166
+ 11.times do
167
+ fifo_queue.pop do |e|
168
+ responses << e
169
+ loop.stop if responses.size == 4
170
+ end
171
+ end
172
+
173
+ end
174
+
175
+ responses.first(5).should == ["Other1", "Other2", "Checking1", "Checking2", "Checking3"]
176
+
177
+ end
178
+
179
+
180
+ it "should give elements in the order of their priority - custom ordering schema" do
181
+ @q = UV::PriorityQueue.new {|x,y| x < y}
182
+ responses = []
183
+ loop = Libuv::Loop.default
184
+ loop.run do
185
+
186
+
187
+ @q.push("Mike", 20)
188
+ @q.push("Alex", 21)
189
+ @q.push("Bob", 22)
190
+ @q.push("Tim", 18)
191
+
192
+ 4.times do
193
+ @q.pop do |e|
194
+ responses << e
195
+ loop.stop if responses.size == 4
196
+ end
197
+ end
198
+ end
199
+
200
+ responses[0].should == "Tim"
201
+ responses[1].should == "Mike"
202
+ responses[2].should == "Alex"
203
+ responses[3].should == "Bob"
204
+ end
205
+ end
206
+
207
+ context "README demos" do
208
+ it "should run the first fifo example" do
209
+ @q = UV::PriorityQueue.new(:fifo => true)
210
+
211
+ responses = []
212
+ loop = Libuv::Loop.default
213
+ loop.run do
214
+
215
+
216
+ @q.push("Mike", 20)
217
+ @q.push("Alex", 21)
218
+ @q.push("Bob", 20)
219
+ @q.push("Tim", 18)
220
+ @q.push("Carol", 20)
221
+
222
+ 5.times do
223
+ @q.pop do |e|
224
+ responses << e
225
+ loop.stop if responses.size == 5
226
+ end
227
+ end
228
+ end
229
+
230
+ responses[0].should == "Alex"
231
+ responses[1].should == "Mike"
232
+ responses[2].should == "Bob"
233
+ responses[3].should == "Carol"
234
+ responses[4].should == "Tim"
235
+ end
236
+
237
+ it "should run the second fifo example" do
238
+ @q = UV::PriorityQueue.new(:fifo => true) {|x,y| x < y}
239
+
240
+ responses = []
241
+ loop = Libuv::Loop.default
242
+ loop.run do
243
+
244
+
245
+ @q.push("Mike", 20)
246
+ @q.push("Alex", 21)
247
+ @q.push("Bob", 20)
248
+ @q.push("Tim", 18)
249
+ @q.push("Carol", 20)
250
+
251
+ 5.times do
252
+ @q.pop do |e|
253
+ responses << e
254
+ loop.stop if responses.size == 5
255
+ end
256
+ end
257
+ end
258
+
259
+ responses[0].should == "Tim" # Tim
260
+ responses[1].should == "Mike" # Mike
261
+ responses[2].should == "Bob" # Bob
262
+ responses[3].should == "Carol" # Carol
263
+ responses[4].should == "Alex" # Alex
264
+
265
+ end
266
+ end
267
+ end
@@ -0,0 +1,27 @@
1
+
2
+ require File.expand_path("../lib/uv-priority-queue/version", __FILE__)
3
+
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "uv-priority-queue"
7
+ s.version = UV::PriorityQueue::VERSION
8
+ s.license = 'MIT'
9
+ s.authors = ["Stephen von Takach", "Mike Lewis"]
10
+ s.email = ["steve@cotag.me", "ft.mikelewis@gmail.com"]
11
+ s.homepage = "https://github.com/cotag/uv-priority-queue"
12
+ s.summary = %q{Libuv Priority Queue}
13
+ s.description = %q{Asynchronous Priority Queue for use with Libuv}
14
+
15
+ s.files = Dir["lib/**/*"] + %w(Rakefile uv-priority-queue.gemspec README.md LICENSE)
16
+ s.test_files = Dir["spec/**/*"]
17
+ s.require_paths = ["lib"]
18
+
19
+
20
+ s.add_runtime_dependency "libuv"
21
+ s.add_runtime_dependency "algorithms"
22
+
23
+
24
+ s.add_development_dependency 'rake'
25
+ s.add_development_dependency 'rspec'
26
+ s.add_development_dependency "delorean", ">= 1.1.1"
27
+ end
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: uv-priority-queue
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Stephen von Takach
8
+ - Mike Lewis
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-01-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: libuv
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: algorithms
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: delorean
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: 1.1.1
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: 1.1.1
84
+ description: Asynchronous Priority Queue for use with Libuv
85
+ email:
86
+ - steve@cotag.me
87
+ - ft.mikelewis@gmail.com
88
+ executables: []
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - lib/uv-priority-queue/priority_queue.rb
93
+ - lib/uv-priority-queue/version.rb
94
+ - lib/uv-priority-queue.rb
95
+ - Rakefile
96
+ - uv-priority-queue.gemspec
97
+ - README.md
98
+ - LICENSE
99
+ - spec/spec_helper.rb
100
+ - spec/uv-priority-queue_spec.rb
101
+ homepage: https://github.com/cotag/uv-priority-queue
102
+ licenses:
103
+ - MIT
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubyforge_project:
121
+ rubygems_version: 2.0.3
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: Libuv Priority Queue
125
+ test_files:
126
+ - spec/spec_helper.rb
127
+ - spec/uv-priority-queue_spec.rb
128
+ has_rdoc: