unified-queues 0.1.0
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.
- data/.document +5 -0
- data/CHANGES.txt +3 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +32 -0
- data/LICENSE.txt +20 -0
- data/README.md +88 -0
- data/Rakefile +29 -0
- data/VERSION +1 -0
- data/debug +33 -0
- data/lib/unified-queues.rb +5 -0
- data/lib/unified-queues/multi.rb +209 -0
- data/lib/unified-queues/multi/driver.rb +176 -0
- data/lib/unified-queues/multi/driver/em-jack.rb +200 -0
- data/lib/unified-queues/multi/driver/unified-queues.rb +227 -0
- data/lib/unified-queues/single.rb +178 -0
- data/lib/unified-queues/single/driver.rb +147 -0
- data/lib/unified-queues/single/driver/algorithms.rb +100 -0
- data/lib/unified-queues/single/driver/array.rb +94 -0
- data/lib/unified-queues/single/driver/depq.rb +95 -0
- data/lib/unified-queues/single/driver/evented-queue.rb +96 -0
- data/lib/unified-queues/single/driver/priority_queue.rb +221 -0
- data/lib/unified-queues/single/driver/queue.rb +105 -0
- data/test +297 -0
- metadata +218 -0
@@ -0,0 +1,178 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
|
3
|
+
|
4
|
+
require "unified-queues/single/driver"
|
5
|
+
require "hash-utils/module"
|
6
|
+
|
7
|
+
##
|
8
|
+
# Base +Unified Queues+ module.
|
9
|
+
#
|
10
|
+
|
11
|
+
module UnifiedQueues
|
12
|
+
|
13
|
+
##
|
14
|
+
# Universal single queue interface.
|
15
|
+
#
|
16
|
+
|
17
|
+
class Single
|
18
|
+
|
19
|
+
##
|
20
|
+
# Contains assignment of classnames to drivers.
|
21
|
+
# @return [Hash]
|
22
|
+
#
|
23
|
+
|
24
|
+
DRIVERS = Hash[
|
25
|
+
:Queue => "queue",
|
26
|
+
:Array => "array",
|
27
|
+
:Depq => "depq",
|
28
|
+
:"Containers::Heap" => "algorithms",
|
29
|
+
:CPriorityQueue => "priority_queue",
|
30
|
+
:PoorPriorityQueue => "priority_queue",
|
31
|
+
:RubyPriorityQueue => "priority_queue",
|
32
|
+
:EventedQueue => "evented-queue"
|
33
|
+
]
|
34
|
+
|
35
|
+
##
|
36
|
+
# Contains driver for specific class instance.
|
37
|
+
# @return [UnifiedQueues::Single::Driver] driver instance
|
38
|
+
#
|
39
|
+
|
40
|
+
attr_accessor :driver
|
41
|
+
@driver
|
42
|
+
|
43
|
+
##
|
44
|
+
# Constructor.
|
45
|
+
#
|
46
|
+
# @param [Class|UnifiedQueues::Single::Driver] cls required class object or driver instance
|
47
|
+
# @param [Array] *args array of arguments for the queue constructor
|
48
|
+
# @param [Proc] &block block for the queue constructor
|
49
|
+
#
|
50
|
+
|
51
|
+
def initialize(cls, *args, &block)
|
52
|
+
if cls.kind_of? UnifiedQueues::Single::Driver
|
53
|
+
@driver = cls
|
54
|
+
else
|
55
|
+
self.assign_driver(cls, args, block)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
##
|
60
|
+
# Assigns driver to interface according to given class name.
|
61
|
+
#
|
62
|
+
# @param [Class] cls required class
|
63
|
+
# @param [Array] args array of arguments for the queue constructor
|
64
|
+
# @param [Proc] block block for the queue constructor
|
65
|
+
# @return [UnifiedQueues::Single::Driver] new driver instance
|
66
|
+
#
|
67
|
+
|
68
|
+
def assign_driver(cls, args, block)
|
69
|
+
_cls = cls
|
70
|
+
if not _cls.kind_of? Class
|
71
|
+
_cls = cls.class
|
72
|
+
end
|
73
|
+
|
74
|
+
driver = nil
|
75
|
+
name = nil
|
76
|
+
|
77
|
+
self.class::DRIVERS.each_pair do |_name, _driver|
|
78
|
+
begin
|
79
|
+
_module = Module::get_module(_name.to_s)
|
80
|
+
rescue NameError
|
81
|
+
next
|
82
|
+
end
|
83
|
+
|
84
|
+
if _cls <= _module
|
85
|
+
driver = _driver
|
86
|
+
name = _name
|
87
|
+
break
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
###
|
92
|
+
|
93
|
+
require "unified-queues/single/driver/" << driver
|
94
|
+
|
95
|
+
path = name.to_s.split("::")
|
96
|
+
classname = path.shift << 'Driver::' << path.join('::')
|
97
|
+
_module = Module::get_module("UnifiedQueues::Single::Driver::" << classname)
|
98
|
+
|
99
|
+
args = [cls] + args
|
100
|
+
@driver = _module::new(*args, &block)
|
101
|
+
return @driver
|
102
|
+
end
|
103
|
+
|
104
|
+
##
|
105
|
+
# Pushes the value into the queue.
|
106
|
+
#
|
107
|
+
# @param [Object] value value for push
|
108
|
+
# @param [Object] key key for priority queues
|
109
|
+
#
|
110
|
+
|
111
|
+
def push(value, key = value, &block)
|
112
|
+
@driver.push(value, key, &block)
|
113
|
+
end
|
114
|
+
|
115
|
+
alias :<< :push
|
116
|
+
|
117
|
+
##
|
118
|
+
# Pops value out of the queue.
|
119
|
+
#
|
120
|
+
# @param [Boolean|Integer] blocking +true+ or timeout if it should block, +false+ otherwise
|
121
|
+
# @param [Object] queue value
|
122
|
+
#
|
123
|
+
|
124
|
+
def pop(blocking = false, &block)
|
125
|
+
@driver.pop(blocking, &block)
|
126
|
+
end
|
127
|
+
|
128
|
+
alias :pop! :pop
|
129
|
+
|
130
|
+
##
|
131
|
+
# Indicates queue is empty.
|
132
|
+
# @param [Boolean] +true+ if it's, +false+ otherwise
|
133
|
+
#
|
134
|
+
|
135
|
+
def empty?(&block)
|
136
|
+
@driver.empty?(&block)
|
137
|
+
end
|
138
|
+
|
139
|
+
##
|
140
|
+
# Clears the queue.
|
141
|
+
#
|
142
|
+
|
143
|
+
def clear!(&block)
|
144
|
+
@driver.clear!(&block)
|
145
|
+
end
|
146
|
+
|
147
|
+
alias :clear :clear!
|
148
|
+
|
149
|
+
##
|
150
|
+
# Returns length of the queue.
|
151
|
+
# @return [Integer]
|
152
|
+
#
|
153
|
+
|
154
|
+
def length(&block)
|
155
|
+
@driver.length(&block)
|
156
|
+
end
|
157
|
+
|
158
|
+
alias :size :length
|
159
|
+
|
160
|
+
=begin
|
161
|
+
protected
|
162
|
+
|
163
|
+
##
|
164
|
+
# Returns value using yield or return according to driver settings.
|
165
|
+
#
|
166
|
+
# @return [Object] returned value
|
167
|
+
# @yield [Object] returned value
|
168
|
+
#
|
169
|
+
|
170
|
+
def __return
|
171
|
+
if @driver.linear?
|
172
|
+
|
173
|
+
end
|
174
|
+
end
|
175
|
+
=end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
@@ -0,0 +1,147 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
|
3
|
+
|
4
|
+
require "abstract"
|
5
|
+
|
6
|
+
|
7
|
+
##
|
8
|
+
# Base +Unified Queues+ module.
|
9
|
+
#
|
10
|
+
|
11
|
+
module UnifiedQueues
|
12
|
+
|
13
|
+
##
|
14
|
+
# Universal single queue interface.
|
15
|
+
#
|
16
|
+
|
17
|
+
class Single
|
18
|
+
|
19
|
+
##
|
20
|
+
# Abstract single driver class.
|
21
|
+
# @abstract
|
22
|
+
#
|
23
|
+
|
24
|
+
class Driver
|
25
|
+
|
26
|
+
##
|
27
|
+
# Holds native object.
|
28
|
+
# @return [Object]
|
29
|
+
#
|
30
|
+
|
31
|
+
attr_accessor :native
|
32
|
+
@native
|
33
|
+
|
34
|
+
##
|
35
|
+
# Constructor.
|
36
|
+
#
|
37
|
+
|
38
|
+
def initialize(cls, *args, &block)
|
39
|
+
if self.instance_of? UnifiedQueues::Single::Driver
|
40
|
+
not_implemented
|
41
|
+
end
|
42
|
+
|
43
|
+
if cls.kind_of? Class
|
44
|
+
@native = cls::new(*args, &block)
|
45
|
+
else
|
46
|
+
@native = cls
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# Pushes the value into the queue.
|
52
|
+
#
|
53
|
+
# @param [Object] value value for push
|
54
|
+
# @param [Object] key key for priority queues
|
55
|
+
# @abstract
|
56
|
+
#
|
57
|
+
|
58
|
+
def push(value, key = value, &block)
|
59
|
+
not_implemented
|
60
|
+
end
|
61
|
+
|
62
|
+
alias :<< :push
|
63
|
+
|
64
|
+
##
|
65
|
+
# Pops value out of the queue.
|
66
|
+
#
|
67
|
+
# @param [Boolean|Integer] blocking +true+ or timeout if it should block, +false+ otherwise
|
68
|
+
# @param [Object] queue value
|
69
|
+
# @abstract
|
70
|
+
#
|
71
|
+
|
72
|
+
def pop(blocking = false, &block)
|
73
|
+
not_implemented
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# Indicates queue is empty.
|
78
|
+
#
|
79
|
+
# @param [Boolean] +true+ if it's, +false+ otherwise
|
80
|
+
# @abstract
|
81
|
+
#
|
82
|
+
|
83
|
+
def empty?(&block)
|
84
|
+
not_implemented
|
85
|
+
end
|
86
|
+
|
87
|
+
##
|
88
|
+
# Clears the queue.
|
89
|
+
# @abstract
|
90
|
+
#
|
91
|
+
|
92
|
+
def clear!(&block)
|
93
|
+
while not self.pop.nil?
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
alias :clear :clear!
|
98
|
+
|
99
|
+
##
|
100
|
+
# Returns length of the queue.
|
101
|
+
#
|
102
|
+
# @return [Integer]
|
103
|
+
# @abstract
|
104
|
+
#
|
105
|
+
|
106
|
+
def length(&block)
|
107
|
+
not_implemented
|
108
|
+
end
|
109
|
+
|
110
|
+
alias :size :length
|
111
|
+
|
112
|
+
##
|
113
|
+
# Returs type of the queue. Queue can be +:linear+ which means,
|
114
|
+
# calls values are returned using +return+ or +:evented+
|
115
|
+
# which indicates necessity of callbacks.
|
116
|
+
#
|
117
|
+
# @return [:linear, :evented]
|
118
|
+
# @abstract
|
119
|
+
#
|
120
|
+
|
121
|
+
def type
|
122
|
+
not_implemented
|
123
|
+
end
|
124
|
+
|
125
|
+
##
|
126
|
+
# Indicates, driver is evented so expexts callbacks.
|
127
|
+
# @return [Boolean] +true+ if it is, +false+ otherwise
|
128
|
+
#
|
129
|
+
|
130
|
+
def evented?
|
131
|
+
self.type == :evented
|
132
|
+
end
|
133
|
+
|
134
|
+
##
|
135
|
+
# Indicates, driver is evented so expexts callbacks.
|
136
|
+
# @return [Boolean] +true+ if it is, +false+ otherwise
|
137
|
+
#
|
138
|
+
|
139
|
+
def linear?
|
140
|
+
self.type == :linear
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
|
3
|
+
|
4
|
+
require "unified-queues/single/driver"
|
5
|
+
|
6
|
+
##
|
7
|
+
# Base +Unified Queues+ module.
|
8
|
+
#
|
9
|
+
|
10
|
+
module UnifiedQueues
|
11
|
+
|
12
|
+
##
|
13
|
+
# Universal single queue interface.
|
14
|
+
#
|
15
|
+
|
16
|
+
class Single
|
17
|
+
|
18
|
+
##
|
19
|
+
# Abstract single driver class.
|
20
|
+
# @abstract
|
21
|
+
#
|
22
|
+
|
23
|
+
class Driver
|
24
|
+
|
25
|
+
##
|
26
|
+
# Wrapper according to +algorithm+ library.
|
27
|
+
#
|
28
|
+
|
29
|
+
module ContainersDriver
|
30
|
+
|
31
|
+
##
|
32
|
+
# Fibonacci heap queue driver. Uses the +Containers::Heap+
|
33
|
+
# class from +algorithms+ gem for queueing. Priority is supported.
|
34
|
+
#
|
35
|
+
|
36
|
+
class Heap < Driver
|
37
|
+
|
38
|
+
##
|
39
|
+
# Pushes the value into the queue. Priority is supported.
|
40
|
+
#
|
41
|
+
# @param [Object] value value for push
|
42
|
+
# @param [Object] key key for priority queues
|
43
|
+
#
|
44
|
+
|
45
|
+
def push(value, key = value)
|
46
|
+
@native.push(key, value)
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# Pops value out of the queue. Note, value with minimal
|
51
|
+
# priority will be popped out. Blocking isn'ŧ supported.
|
52
|
+
#
|
53
|
+
# @param [Boolean|Integer] blocking +true+ or timeout if it should block, +false+ otherwise
|
54
|
+
# @return [Object] queued value
|
55
|
+
#
|
56
|
+
|
57
|
+
def pop(blocking = false)
|
58
|
+
@native.pop
|
59
|
+
end
|
60
|
+
|
61
|
+
##
|
62
|
+
# Indicates queue is empty.
|
63
|
+
# @param [Boolean] +true+ if it's, +false+ otherwise
|
64
|
+
#
|
65
|
+
|
66
|
+
def empty?
|
67
|
+
@native.empty?
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# Clears the queue.
|
72
|
+
#
|
73
|
+
|
74
|
+
def clear!
|
75
|
+
@native.clear
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# Returns length of the queue.
|
80
|
+
# @return [Integer]
|
81
|
+
#
|
82
|
+
|
83
|
+
def length
|
84
|
+
@native.size
|
85
|
+
end
|
86
|
+
|
87
|
+
##
|
88
|
+
# Returs type of the queue.
|
89
|
+
# @return [:linear]
|
90
|
+
#
|
91
|
+
|
92
|
+
def type
|
93
|
+
:linear
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
|
3
|
+
|
4
|
+
require "unified-queues/single/driver"
|
5
|
+
|
6
|
+
##
|
7
|
+
# Base +Unified Queues+ module.
|
8
|
+
#
|
9
|
+
|
10
|
+
module UnifiedQueues
|
11
|
+
|
12
|
+
##
|
13
|
+
# Universal single queue interface.
|
14
|
+
#
|
15
|
+
|
16
|
+
class Single
|
17
|
+
|
18
|
+
##
|
19
|
+
# Abstract single driver class.
|
20
|
+
# @abstract
|
21
|
+
#
|
22
|
+
|
23
|
+
class Driver
|
24
|
+
|
25
|
+
##
|
26
|
+
# Array queue driver. Uses standard library +Array+ class
|
27
|
+
# for queueing. Priority isn't supported.
|
28
|
+
#
|
29
|
+
|
30
|
+
class ArrayDriver < Driver
|
31
|
+
|
32
|
+
##
|
33
|
+
# Pushes the value into the queue. Priority isn't supported.
|
34
|
+
#
|
35
|
+
# @param [Object] value value for push
|
36
|
+
# @param [Object] key key for priority queues
|
37
|
+
#
|
38
|
+
|
39
|
+
def push(value, key = value)
|
40
|
+
@native.push(value)
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Pops value out of the queue. Blocking isn'ŧ supported.
|
45
|
+
#
|
46
|
+
# @param [Boolean|Integer] blocking +true+ or timeout if it should block, +false+ otherwise
|
47
|
+
# @return [Object] out-queued value
|
48
|
+
#
|
49
|
+
|
50
|
+
def pop(blocking = false)
|
51
|
+
@native.shift
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Indicates queue is empty.
|
56
|
+
# @param [Boolean] +true+ if it's, +false+ otherwise
|
57
|
+
#
|
58
|
+
|
59
|
+
def empty?
|
60
|
+
@native.empty?
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Clears the queue.
|
65
|
+
#
|
66
|
+
|
67
|
+
def clear!
|
68
|
+
@native.clear
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# Returns length of the queue.
|
73
|
+
# @return [Integer]
|
74
|
+
#
|
75
|
+
|
76
|
+
def length
|
77
|
+
@native.length
|
78
|
+
end
|
79
|
+
|
80
|
+
##
|
81
|
+
# Returs type of the queue.
|
82
|
+
# @return [:linear]
|
83
|
+
#
|
84
|
+
|
85
|
+
def type
|
86
|
+
:linear
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|