fairy 0.6.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.
Files changed (186) hide show
  1. data/LICENSE +674 -0
  2. data/Makefile +116 -0
  3. data/README +15 -0
  4. data/bin/fairy +582 -0
  5. data/bin/fairy-cat +74 -0
  6. data/bin/fairy-cp +128 -0
  7. data/bin/fairy-rm +122 -0
  8. data/bin/subcmd/controller +41 -0
  9. data/bin/subcmd/inspector +81 -0
  10. data/bin/subcmd/master +43 -0
  11. data/bin/subcmd/node +47 -0
  12. data/bin/subcmd/processor +54 -0
  13. data/doc/programming-interface.html +240 -0
  14. data/doc/programming-interface.rd +300 -0
  15. data/etc/fairy.conf.tmpl +118 -0
  16. data/ext/simple_hash/extconf.rb +4 -0
  17. data/ext/simple_hash/simple_hash.c +42 -0
  18. data/fairy.gemspec +60 -0
  19. data/lib/fairy/client/addins.rb +20 -0
  20. data/lib/fairy/client/barrier.rb +29 -0
  21. data/lib/fairy/client/basic-group-by.rb +52 -0
  22. data/lib/fairy/client/cat.rb +41 -0
  23. data/lib/fairy/client/direct-product.rb +51 -0
  24. data/lib/fairy/client/equijoin.rb +79 -0
  25. data/lib/fairy/client/exec.rb +54 -0
  26. data/lib/fairy/client/filter.rb +62 -0
  27. data/lib/fairy/client/find.rb +35 -0
  28. data/lib/fairy/client/group-by.rb +194 -0
  29. data/lib/fairy/client/here.rb +84 -0
  30. data/lib/fairy/client/inject.rb +70 -0
  31. data/lib/fairy/client/input-file.rb +53 -0
  32. data/lib/fairy/client/input-iota.rb +49 -0
  33. data/lib/fairy/client/input-local-file.rb +188 -0
  34. data/lib/fairy/client/input-varray.rb +30 -0
  35. data/lib/fairy/client/input.rb +42 -0
  36. data/lib/fairy/client/io-filter.rb +26 -0
  37. data/lib/fairy/client/junction.rb +31 -0
  38. data/lib/fairy/client/map.rb +34 -0
  39. data/lib/fairy/client/merge-group-by.rb +71 -0
  40. data/lib/fairy/client/output-file.rb +64 -0
  41. data/lib/fairy/client/output-local-file.rb +60 -0
  42. data/lib/fairy/client/output-null.rb +47 -0
  43. data/lib/fairy/client/output-varray.rb +50 -0
  44. data/lib/fairy/client/output.rb +29 -0
  45. data/lib/fairy/client/roma-put.rb +62 -0
  46. data/lib/fairy/client/roma.rb +156 -0
  47. data/lib/fairy/client/seg-join.rb +61 -0
  48. data/lib/fairy/client/seg-map.rb +78 -0
  49. data/lib/fairy/client/seg-shuffle.rb +35 -0
  50. data/lib/fairy/client/seg-split.rb +27 -0
  51. data/lib/fairy/client/seg-zip.rb +60 -0
  52. data/lib/fairy/client/select.rb +38 -0
  53. data/lib/fairy/client/sort.rb +48 -0
  54. data/lib/fairy/client/sort18.rb +56 -0
  55. data/lib/fairy/client/sort19.rb +61 -0
  56. data/lib/fairy/client/there.rb +47 -0
  57. data/lib/fairy/client/top_n_into_roma.rb +34 -0
  58. data/lib/fairy/client/wc.rb +92 -0
  59. data/lib/fairy/controller.rb +1103 -0
  60. data/lib/fairy/logger.rb +107 -0
  61. data/lib/fairy/master/addins.rb +20 -0
  62. data/lib/fairy/master/atom.rb +17 -0
  63. data/lib/fairy/master/c-barrier.rb +283 -0
  64. data/lib/fairy/master/c-basic-group-by.rb +250 -0
  65. data/lib/fairy/master/c-cat.rb +159 -0
  66. data/lib/fairy/master/c-direct-product.rb +203 -0
  67. data/lib/fairy/master/c-exec.rb +68 -0
  68. data/lib/fairy/master/c-filter.rb +422 -0
  69. data/lib/fairy/master/c-find.rb +138 -0
  70. data/lib/fairy/master/c-group-by.rb +64 -0
  71. data/lib/fairy/master/c-here.rb +80 -0
  72. data/lib/fairy/master/c-inject.rb +119 -0
  73. data/lib/fairy/master/c-input-file.rb +46 -0
  74. data/lib/fairy/master/c-input-iota.rb +66 -0
  75. data/lib/fairy/master/c-input-local-file.rb +117 -0
  76. data/lib/fairy/master/c-input-varray.rb +53 -0
  77. data/lib/fairy/master/c-input.rb +24 -0
  78. data/lib/fairy/master/c-inputtable.rb +31 -0
  79. data/lib/fairy/master/c-inputtable18.rb +36 -0
  80. data/lib/fairy/master/c-inputtable19.rb +35 -0
  81. data/lib/fairy/master/c-io-filter.rb +28 -0
  82. data/lib/fairy/master/c-junction.rb +54 -0
  83. data/lib/fairy/master/c-map.rb +27 -0
  84. data/lib/fairy/master/c-merge-group-by.rb +241 -0
  85. data/lib/fairy/master/c-output-file.rb +84 -0
  86. data/lib/fairy/master/c-output-local-file.rb +19 -0
  87. data/lib/fairy/master/c-output-null.rb +45 -0
  88. data/lib/fairy/master/c-output-varray.rb +57 -0
  89. data/lib/fairy/master/c-output.rb +20 -0
  90. data/lib/fairy/master/c-seg-join.rb +141 -0
  91. data/lib/fairy/master/c-seg-map.rb +26 -0
  92. data/lib/fairy/master/c-seg-shuffle.rb +87 -0
  93. data/lib/fairy/master/c-seg-split.rb +110 -0
  94. data/lib/fairy/master/c-seg-zip.rb +132 -0
  95. data/lib/fairy/master/c-select.rb +27 -0
  96. data/lib/fairy/master/c-sort.rb +108 -0
  97. data/lib/fairy/master/c-there.rb +57 -0
  98. data/lib/fairy/master/c-wc.rb +232 -0
  99. data/lib/fairy/master/job-interpriter.rb +19 -0
  100. data/lib/fairy/master/scheduler.rb +24 -0
  101. data/lib/fairy/master.rb +329 -0
  102. data/lib/fairy/node/addins.rb +19 -0
  103. data/lib/fairy/node/p-barrier.rb +95 -0
  104. data/lib/fairy/node/p-basic-group-by.rb +252 -0
  105. data/lib/fairy/node/p-direct-product.rb +153 -0
  106. data/lib/fairy/node/p-exec.rb +30 -0
  107. data/lib/fairy/node/p-filter.rb +363 -0
  108. data/lib/fairy/node/p-find.rb +111 -0
  109. data/lib/fairy/node/p-group-by.rb +1534 -0
  110. data/lib/fairy/node/p-here.rb +21 -0
  111. data/lib/fairy/node/p-identity.rb +24 -0
  112. data/lib/fairy/node/p-inject.rb +127 -0
  113. data/lib/fairy/node/p-input-file.rb +108 -0
  114. data/lib/fairy/node/p-input-iota.rb +39 -0
  115. data/lib/fairy/node/p-input-local-file.rb +61 -0
  116. data/lib/fairy/node/p-input-varray.rb +26 -0
  117. data/lib/fairy/node/p-io-filter.rb +28 -0
  118. data/lib/fairy/node/p-map.rb +40 -0
  119. data/lib/fairy/node/p-merger-group-by.rb +48 -0
  120. data/lib/fairy/node/p-output-file.rb +104 -0
  121. data/lib/fairy/node/p-output-local-file.rb +14 -0
  122. data/lib/fairy/node/p-output-null.rb +32 -0
  123. data/lib/fairy/node/p-output-varray.rb +41 -0
  124. data/lib/fairy/node/p-seg-join.rb +82 -0
  125. data/lib/fairy/node/p-seg-map.rb +34 -0
  126. data/lib/fairy/node/p-seg-split.rb +61 -0
  127. data/lib/fairy/node/p-seg-zip.rb +79 -0
  128. data/lib/fairy/node/p-select.rb +40 -0
  129. data/lib/fairy/node/p-single-exportable.rb +90 -0
  130. data/lib/fairy/node/p-sort.rb +195 -0
  131. data/lib/fairy/node/p-task.rb +113 -0
  132. data/lib/fairy/node/p-there.rb +44 -0
  133. data/lib/fairy/node/p-wc.rb +266 -0
  134. data/lib/fairy/node.rb +187 -0
  135. data/lib/fairy/processor.rb +510 -0
  136. data/lib/fairy/share/base-app.rb +114 -0
  137. data/lib/fairy/share/block-source.rb +234 -0
  138. data/lib/fairy/share/conf.rb +396 -0
  139. data/lib/fairy/share/debug.rb +21 -0
  140. data/lib/fairy/share/encoding.rb +17 -0
  141. data/lib/fairy/share/fast-tempfile.rb +93 -0
  142. data/lib/fairy/share/file-place.rb +176 -0
  143. data/lib/fairy/share/hash-1.rb +20 -0
  144. data/lib/fairy/share/hash-md5.rb +28 -0
  145. data/lib/fairy/share/hash-murmur.rb +69 -0
  146. data/lib/fairy/share/hash-rb18.rb +20 -0
  147. data/lib/fairy/share/hash-simple-hash.rb +28 -0
  148. data/lib/fairy/share/inspector.rb +16 -0
  149. data/lib/fairy/share/lc/exceptions.rb +82 -0
  150. data/lib/fairy/share/lc/ja/exceptions.rb +81 -0
  151. data/lib/fairy/share/locale.rb +17 -0
  152. data/lib/fairy/share/log.rb +215 -0
  153. data/lib/fairy/share/pool-dictionary.rb +53 -0
  154. data/lib/fairy/share/port-marshaled-queue.rb +347 -0
  155. data/lib/fairy/share/port.rb +1697 -0
  156. data/lib/fairy/share/reference.rb +45 -0
  157. data/lib/fairy/share/stdout.rb +56 -0
  158. data/lib/fairy/share/tr.rb +16 -0
  159. data/lib/fairy/share/varray.rb +147 -0
  160. data/lib/fairy/share/vfile.rb +183 -0
  161. data/lib/fairy/version.rb +8 -0
  162. data/lib/fairy.rb +206 -0
  163. data/sample/grep.rb +46 -0
  164. data/sample/ping.rb +19 -0
  165. data/sample/sort.rb +102 -0
  166. data/sample/wordcount.rb +61 -0
  167. data/spec/README +12 -0
  168. data/spec/fairy1_spec.rb +31 -0
  169. data/spec/fairy2_spec.rb +42 -0
  170. data/spec/fairy3_spec.rb +126 -0
  171. data/spec/fairy4_spec.rb +63 -0
  172. data/spec/fairy5_spec.rb +45 -0
  173. data/spec/fairy6_spec.rb +52 -0
  174. data/spec/fairy7_spec.rb +58 -0
  175. data/spec/fairy8_spec.rb +48 -0
  176. data/spec/mkdat.rb +148 -0
  177. data/spec/run_all.sh +65 -0
  178. data/test/testc.rb +7111 -0
  179. data/tools/cap_recipe/Capfile +144 -0
  180. data/tools/cap_recipe/cluster.yml.sample +14 -0
  181. data/tools/fairy_perf_graph.rb +444 -0
  182. data/tools/git-tag +44 -0
  183. data/tools/log-analysis.rb +62 -0
  184. data/tools/svn-ls-diff +38 -0
  185. data/tools/svn-tags +37 -0
  186. metadata +298 -0
@@ -0,0 +1,66 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "fairy/master/c-input"
7
+
8
+ module Fairy
9
+
10
+ class CInputIota<CInput
11
+ Controller.def_export self
12
+
13
+ DeepConnect.def_single_method_spec(self, "REF new(REF, VAL, VAL)")
14
+
15
+ def initialize(controller, opts, last)
16
+ super
17
+ @last = last - 1
18
+ end
19
+
20
+ def node_class_name
21
+ "PInputIota"
22
+ end
23
+
24
+ def start
25
+ offset = 0
26
+ offset = @opts[:offset] if @opts[:offset]
27
+ split_no = @opts[:SPLIT_NO]
28
+
29
+ @ciota_place = CIotaPlace.new(@last, offset, split_no)
30
+ start_create_nodes
31
+ end
32
+
33
+ def input
34
+ @ciota_place
35
+ end
36
+
37
+ # def create_and_start_nodes
38
+ # begin
39
+ # offset = 0
40
+ # offset = @opts[:offset] if @opts[:offset]
41
+ # split_no = @opts[:SPLIT_NO]
42
+
43
+ # first = offset
44
+ # no = 0
45
+ # split_no.times do
46
+ # @create_node_mutex.synchronize do
47
+ # no += 1
48
+ # Log::debug self, "NO: #{no}"
49
+ # last = [first + @last.div(split_no), @last].min
50
+ # @controller.assign_processor(self, :NEW_PROCESSOR) do |processor|
51
+ # njob = create_node(processor, first, last)
52
+ # njob.start
53
+ # first = last + 1
54
+ # end
55
+ # end
56
+ # sleep 0.1
57
+ # end
58
+ # rescue BreakCreateNode
59
+ # # do nothing
60
+ # Log::debug self, "BREAK CREATE NODE: #{self}"
61
+ # ensure
62
+ # self.number_of_nodes = no
63
+ # end
64
+ # end
65
+ end
66
+ end
@@ -0,0 +1,117 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "uri"
7
+
8
+ require "fairy/master/c-input"
9
+ require "fairy/share/vfile"
10
+ require "fairy/share/file-place"
11
+
12
+ module Fairy
13
+ class CInputLocalFile<CInput
14
+ Controller.def_export self
15
+
16
+ # DeepConnect.def_single_method_spec(self, "REF new(REF, VAL)")
17
+
18
+ def CInputLocalFile.open(controller, opts = nil)
19
+ blfileinput = CInputLocalFile.new(controller, opts)
20
+ blfileinput.open(descripter)
21
+ blfileinput
22
+ end
23
+
24
+ def initialize(controller, opts = nil)
25
+ super
26
+ end
27
+
28
+ def node_class_name
29
+ "PInputLocalFile"
30
+ end
31
+
32
+ def start(job)
33
+ @cio_place = CLocalIOPlace.new(job)
34
+ start_create_nodes
35
+ end
36
+
37
+ def input
38
+ @cio_place
39
+ end
40
+
41
+ # def create_and_start_nodes
42
+ # if @opts[:split_size]
43
+ # create_and_start_nodes_split
44
+ # else
45
+ # create_and_start_nodes1
46
+ # end
47
+ # end
48
+
49
+ # def create_and_start_nodes1
50
+ # begin
51
+ # no = 0
52
+ # @create_node_mutex.synchronize do
53
+ # nlfileinput = nil
54
+ # @controller.assign_new_processor(self) do |processor|
55
+ # nlfileinput = create_node(processor)
56
+ # end
57
+ # no = 1
58
+ # Thread.start do
59
+ # @job.open do |io|
60
+ # nlfileinput.open(io)
61
+ # wait_input_finished(nlfileinput)
62
+ # end
63
+ # end
64
+ # end
65
+ # rescue BreakCreateNode
66
+ # # do nothing
67
+ # Log::debug self, "BREAK CREATE NODE: #{self}"
68
+ # ensure
69
+ # self.number_of_nodes = no
70
+ # end
71
+ # nil
72
+ # end
73
+
74
+ # def create_and_start_nodes_split
75
+ # begin
76
+ # no_nodes = 0
77
+ # @job.split_opens(@opts[:split_size]) do |io|
78
+ # @create_node_mutex.synchronize do
79
+ # no_nodes += 1
80
+ # nlfileinput = nil
81
+ # @controller.assign_new_processor(self) do |processor|
82
+ # nlfileinput = create_node(processor)
83
+ # end
84
+ # Thread.start(nlfileinput) do |nlfi|
85
+ # begin
86
+ # nlfi.open(io)
87
+ # wait_input_finished(nlfi)
88
+ # ensure
89
+ # io.close
90
+ # end
91
+ # end
92
+ # end
93
+ # end
94
+ # rescue BreakCreateNode
95
+ # # do nothing
96
+ # Log::debug self, "BREAK CREATE NODE: #{self}"
97
+ # ensure
98
+ # self.number_of_nodes = no_nodes
99
+ # end
100
+ # end
101
+
102
+ def wait_input_finished(njob)
103
+ while !njob_input_finished?(njob)
104
+ @nodes_status_mutex.synchronize do
105
+ @nodes_status_cv.wait(@nodes_status_mutex)
106
+ end
107
+ end
108
+ end
109
+
110
+ def njob_input_finished?(njob)
111
+ return false
112
+ st = @nodes_status[njob]
113
+ [:ST_WAIT_EXPORT_FINISH, :ST_EXPORT_FINISH, :ST_FINISH, :ST_OUTPUT_FINISH].include?(st)
114
+ end
115
+
116
+ end
117
+ end
@@ -0,0 +1,53 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "fairy/master/c-input"
7
+
8
+ module Fairy
9
+
10
+ class CInputVArray<CInput
11
+ Controller.def_export self
12
+
13
+ def initialize(controller, opts, varray)
14
+ super
15
+ @varray = varray
16
+ end
17
+
18
+ def node_class_name
19
+ "PInputVArray"
20
+ end
21
+
22
+ def start
23
+ @cvarray_place = CVarrayPlace.new(@varray)
24
+ start_create_nodes
25
+ end
26
+
27
+ def input
28
+ @cvarray_place
29
+ end
30
+
31
+ # def create_and_start_nodes
32
+ # begin
33
+ # no = 0
34
+ # @varray.arrays_size.times do
35
+ # @create_node_mutex.synchronize do
36
+ # subarray = @varray.arrays_at(no)
37
+ # @controller.assign_processor(self,
38
+ # :SAME_PROCESSOR_OBJ,
39
+ # subarray) do |processor|
40
+ # njob = create_node(processor, subarray)
41
+ # njob.start
42
+ # no +=1
43
+ # end
44
+ # end
45
+ # end
46
+ # rescue BreakCreateNode
47
+ # # do nothing
48
+ # Log::debug self, "BREAK CREATE NODE: #{self}"
49
+ # ensure
50
+ # self.number_of_nodes = no
51
+ # end
52
+ end
53
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "fairy/master/c-filter"
7
+
8
+ module Fairy
9
+ class CInput<CFilter
10
+ def initialize(*rests)
11
+ super
12
+ end
13
+
14
+ def output=(output)
15
+ @output = output
16
+ end
17
+
18
+ # def start
19
+ # @create_node_thread = Thread.start {
20
+ # create_and_start_nodes
21
+ # }
22
+ # end
23
+ end
24
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ module Fairy
7
+ module CInputtable
8
+
9
+ def initialize(*rests)
10
+ super
11
+ @input = nil
12
+ end
13
+
14
+ def input=(input)
15
+ @input = input
16
+
17
+ start_create_nodes
18
+ end
19
+
20
+ attr_reader :input
21
+
22
+ def inputtable?
23
+ true
24
+ end
25
+
26
+ def break_running(njob = nil)
27
+ super
28
+ Thread.start{@input.break_running}
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "fairy/master/c-inputtable"
7
+
8
+ module Fairy
9
+ module CInputtable
10
+ # def create_nodes(opts = {})
11
+ # begin
12
+ # no = 0
13
+ # @input.each_export do |export, node, opts|
14
+ # opts = {} if opts.nil?
15
+ # @create_node_mutex.synchronize do
16
+ # new_n = create_and_add_node(export, node)
17
+ # no += 1
18
+ # if opts[:init_njob]
19
+ # opts[:init_njob].call(new_n)
20
+ # end
21
+ # end
22
+ # end
23
+
24
+ # rescue BreakCreateNode
25
+ # # do nothing
26
+ # Log::debug self, "CAUGHT EXCEPTION: BreakCreateNode: #{self}"
27
+ # rescue Exception
28
+ # Log::debug_exception(self)
29
+ # raise
30
+ # ensure
31
+ # Log::debug self, "CREATE_NODES: #{self}.number_of_nodes=#{no}"
32
+ # self.number_of_nodes = no
33
+ # end
34
+ # end
35
+ end
36
+ end
@@ -0,0 +1,35 @@
1
+ # encoding: UTF-8
2
+
3
+ require "fairy/master/c-inputtable"
4
+
5
+ module Fairy
6
+ module CInputtable
7
+
8
+ # create_nodes init_njob: {|node| initialize of node}
9
+ # def create_nodes(opts = {})
10
+ # begin
11
+ # no = 0
12
+ # # @input.each_export do |export, node, opts|
13
+ # @input.each_export do |export, node, opts={}|
14
+ # @create_node_mutex.synchronize do
15
+ # new_n = create_and_add_node(export, node)
16
+ # no += 1
17
+ # if opts[:init_njob]
18
+ # opts[:init_njob].call(new_n)
19
+ # end
20
+ # end
21
+ # end
22
+
23
+ # rescue BreakCreateNode
24
+ # # do nothing
25
+ # Log::debug self, "CAUGHT EXCEPTION: BreakCreateNode: #{self}"
26
+ # rescue Exception
27
+ # Log::debug_exception(self)
28
+ # raise
29
+ # ensure
30
+ # Log::debug self, "CREATE_NODES: #{self}.number_of_nodes=#{no}"
31
+ # self.number_of_nodes = no
32
+ # end
33
+ # end
34
+ end
35
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "fairy/master/c-filter"
7
+ require "fairy/master/c-inputtable"
8
+
9
+ module Fairy
10
+ class CIOFilter<CFilter
11
+ include CInputtable
12
+
13
+ def node_class
14
+ ERR::Raise ERR::INTERNAL::UndefinedNodeClass
15
+ end
16
+
17
+ def input=(input)
18
+ input.output = @input
19
+ super
20
+ end
21
+ attr_reader :input
22
+
23
+ def output=(output)
24
+ @output = output
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,54 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "fairy/master/c-io-filter"
7
+ require "fairy/master/c-inputtable"
8
+
9
+ module Fairy
10
+ class CJunction<CIOFilter
11
+ Controller.def_export self
12
+
13
+ def initialize(controller, opts)
14
+ super
15
+ @port_queue = PortQueue.new
16
+ end
17
+
18
+ def input=(input)
19
+ @input = input
20
+ start
21
+ end
22
+
23
+ def start
24
+ Log::debug self, "START CONNECTING: #{self}"
25
+ Thread.start do
26
+ @input.each_assigned_filter do |input_filter|
27
+ @port_queue.push input_filter
28
+ end
29
+ @port_queue.push nil
30
+ end
31
+ end
32
+
33
+ def each_assigned_filter(&block)
34
+ for input_filter in @port_queue
35
+ #Log::debugf(self, "%s %s", exp.to_s, node.to_s)
36
+ block.call input_filter
37
+ end
38
+ end
39
+
40
+ class PortQueue<DelegateClass(Queue)
41
+ include Enumerable
42
+
43
+ def initialize
44
+ super(Queue.new)
45
+ end
46
+
47
+ def each
48
+ while e = pop
49
+ yield e
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end