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,54 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "fairy/client/filter"
7
+ require "fairy/share/vfile"
8
+
9
+ module Fairy
10
+ class Exec < Filter
11
+ module Interface
12
+
13
+ # Usage:
14
+ # fairy.exec(vnode-spec)....
15
+ #
16
+ def exec(vnode_spec, opts={})
17
+ Exec.exec(self, opts, vnode_spec)
18
+ end
19
+ end
20
+ Fairy::def_fairy_interface Interface
21
+
22
+ def Exec.exec(fairy, opts, vnode_spec)
23
+ exec = new(fairy, opts)
24
+ exec.start(vnode_spec)
25
+ exec
26
+ end
27
+
28
+
29
+ def backend_class_name
30
+ "CExec"
31
+ end
32
+
33
+ def start(vnode_spec)
34
+ @vnode_spec = vnode_spec
35
+ case @vnode_spec
36
+ when Array
37
+ vf = VFile.real_files(@vnode_spec)
38
+ when VFile
39
+ vf = @vnode_spec
40
+ when String
41
+ if VFile.vfile?(@vnode_spec)
42
+ vf = VFile.vfile(@vnode_spec)
43
+ else
44
+ vf = VFile.real_files([@vnode_spec])
45
+ end
46
+ else
47
+ ERR::Raise ERR::IllegalVFile
48
+ end
49
+
50
+ backend.start(vf)
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,62 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ module Fairy
7
+
8
+ FilterInterfaces = []
9
+
10
+ def self.def_filter_interface(mod)
11
+ FilterInterfaces.push mod
12
+ Filter.instance_eval{include mod}
13
+ end
14
+
15
+ def Fairy.def_filter_interface(mod)
16
+ ::Fairy.def_filter_interface(mod)
17
+ end
18
+
19
+ @PostInitializers = []
20
+ def self.def_post_initialize(&block)
21
+ @PostInitializers.push block
22
+ end
23
+
24
+ def self.post_initialize
25
+ @PostInitializers.each{|proc| proc.call}
26
+ end
27
+
28
+ class Filter
29
+ def initialize(fairy, opts, *rests)
30
+ @fairy = fairy
31
+ @opts = opts
32
+ @opts = {} unless @opts
33
+ if @opts[:BEGIN]
34
+ @opts[:BEGIN] = BlockSource.new(@opts[:BEGIN])
35
+ end
36
+ if @opts[:END]
37
+ @opts[:END] = BlockSource.new(@opts[:END])
38
+ end
39
+ @ref = backend_class.new(fairy.controller, opts, *rests)
40
+ end
41
+
42
+ def backend_class
43
+ unless klass = @fairy.name2backend_class(backend_class_name)
44
+ ERR::Raise ERR::INTERNAL::NoRegisterService, backend_class_name
45
+ end
46
+ klass
47
+ end
48
+
49
+ def backend
50
+ @ref
51
+ end
52
+
53
+ def backend=(v)
54
+ @ref=v
55
+ end
56
+
57
+ def def_pool_variable(vname, value = nil)
58
+ backend.def_pool_variable(vname, value)
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,35 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "fairy/client/io-filter"
7
+
8
+ module Fairy
9
+ class Find<IOFilter
10
+
11
+ module Interface
12
+ # filter.find(%{...})
13
+ def find(block_source, opts = nil)
14
+ block_source = BlockSource.new(block_source)
15
+ find = Find.new(@fairy, opts, block_source)
16
+ find.input = self
17
+ find
18
+ end
19
+ end
20
+ Fairy::def_filter_interface Interface
21
+
22
+ def initialize(fairy, opts, block_source)
23
+ super
24
+ @block_source = block_source
25
+ end
26
+
27
+ def backend_class_name
28
+ "CFind"
29
+ end
30
+
31
+ def value
32
+ backend.value
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,194 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "fairy/client/basic-group-by"
7
+ require "fairy/client/merge-group-by"
8
+
9
+ module Fairy
10
+ class GroupBy<IOFilter
11
+
12
+ module Interface
13
+ def group_by(hash_block, opts = nil)
14
+ hash_block = BlockSource.new(hash_block)
15
+ mod_group_by = GroupBy.new(@fairy, opts, hash_block)
16
+ mod_group_by.input = self
17
+ mod_group_by
18
+ end
19
+ end
20
+ Fairy::def_filter_interface Interface
21
+ ::Fairy::def_post_initialize{post_initialize}
22
+
23
+ UnhandleMethods = [
24
+ :post_mod_group_by_filter,
25
+ :post_merge_group_by_filter
26
+ ]
27
+ def self.post_initialize
28
+ for interface in ::Fairy::FilterInterfaces
29
+ for m in interface.instance_methods
30
+ m = m.intern if m.kind_of?(String)
31
+ next if UnhandleMethods.include?(m)
32
+
33
+ m = m.id2name
34
+ GroupBy::module_eval %{
35
+ def #{m}(*argv, &block)
36
+ post_mod_group_by_filter(@block_source, @opts).#{m}(*argv, &block)
37
+ end
38
+ }
39
+ end
40
+ end
41
+ end
42
+
43
+ def initialize(fairy, opts, block_source)
44
+ super
45
+ @block_source = block_source
46
+ end
47
+
48
+ def backend_class_name
49
+ "CGroupBy"
50
+ end
51
+
52
+ class PostFilter<IOFilter
53
+ module Interface
54
+ def post_mod_group_by_filter(hash_block, opts = nil)
55
+ post_mod_group_by_filter = PostFilter.new(@fairy, opts, hash_block)
56
+ post_mod_group_by_filter.input = self
57
+ post_mod_group_by_filter
58
+ end
59
+ Fairy::def_filter_interface Interface
60
+ end
61
+
62
+ def initialize(fairy, opts, block_source)
63
+ super
64
+ @block_source = block_source
65
+ end
66
+
67
+ def backend_class_name
68
+ "CGroupBy::CPostFilter"
69
+ end
70
+ end
71
+
72
+ # class PostAfterModFilter<Filter
73
+ # module Interface
74
+ # def post_after_mod_filter(hash_block, opts = nil)
75
+ # post_after_mod_filter = PostAfterModFilter.new(@fairy, opts, hash_block)
76
+ # post_after_mod_filter.input = self
77
+ # post_after_mod_filter
78
+ # end
79
+ # end
80
+ # Fairy::def_filter_interface Interface
81
+
82
+ # def initialize(fairy, opts, block_source)
83
+ # super
84
+ # @block_source = block_source
85
+ # end
86
+
87
+ # def backend_class_name
88
+ # "BPostAfterModFilter"
89
+ # end
90
+ # end
91
+
92
+ end
93
+ end
94
+
95
+
96
+ Fairy.def_filter(:mod_group_by2) do |fairy, input, block_source, opts = {}|
97
+ my_begin = %{
98
+ require CONF.GROUP_BY_HASH_MODULE
99
+ hash = Fairy::HValueGenerator.new(@Pool.HASH_SEED)
100
+ mod = CONF.GROUP_BY_NO_SEGMENT
101
+ }
102
+ if opts[:BEGIN]
103
+ opts[:BEGIN].cat my_begin
104
+ else
105
+ opts[:BEGIN] = my_begin
106
+ end
107
+ if opts[:postqueuing_policy]
108
+ if !opts[:postqueuing_policy][:sort_by]
109
+ opts[:postqueuing_policy][:sort_by] = block_source
110
+ end
111
+ else
112
+ opts[:postqueuing_policy] = {
113
+ :queuing_class => :SortedQueue,
114
+ :sort_by => block_source
115
+ }
116
+ end
117
+
118
+ pre = input.merge_group_by(%{|e| hash.value(proc{#{block_source}}.call(e)) % mod},
119
+ opts)
120
+ post = pre.seg_map(%{|i, block|
121
+ sort_proc = proc{#{block_source}}
122
+
123
+ key = nil
124
+ ary = []
125
+ buf = i.map{|st| [st, st.pop.dc_deep_copy]}.select{|st, v|!v.nil?}.sort_by{|st, v| sort_proc.call(v)}
126
+ while st_min = buf.shift
127
+ st, min = st_min
128
+ if key == sort_proc.call(min)
129
+ ary.push min
130
+ else
131
+ block.call ary unless ary.empty?
132
+ key = sort_proc.call(min)
133
+ ary = [min]
134
+ end
135
+ next unless v = st.pop.dc_deep_copy # 取りあえずの対応
136
+ buf.push [st, v]
137
+ buf = buf.sort_by{|st0, v0| sort_proc.call(v0)}
138
+ end
139
+ if !ary.empty?
140
+ block.call [key, ary]
141
+ end
142
+ })
143
+ end
144
+
145
+ Fairy.def_filter(:mod_group_by3) do |fairy, input, block_source, opts = {}|
146
+
147
+ my_begin = %{
148
+ require CONF.GROUP_BY_HASH_MODULE
149
+ hash = Fairy::HValueGenerator.new(@Pool.HASH_SEED)
150
+ mod = CONF.GROUP_BY_NO_SEGMENT
151
+ }
152
+ if opts[:BEGIN]
153
+ opts[:BEGIN].cat my_begin
154
+ else
155
+ opts[:BEGIN] = my_begin
156
+ end
157
+ if opts[:postqueuing_policy]
158
+ if !opts[:postqueuing_policy][:sort_by]
159
+ opts[:postqueuing_policy][:sort_by] = %{|k, v| k}
160
+ end
161
+ else
162
+ opts[:postqueuing_policy] = {
163
+ :queuing_class => :SortedQueue,
164
+ :sort_by => %{|k, v| k}
165
+ }
166
+ end
167
+
168
+ key_pair = input.map(%{|v| [proc{#{block_source}}.call(v), v]})
169
+ pre = key_pair.merge_group_by(%{|k, v| hash.value(k) % mod}, opts)
170
+ post = pre.smap2(%{|i, block|
171
+ key = nil
172
+ ary = []
173
+ buf = i.map{|st| [st, st.pop.dc_deep_copy]}.select{|st, pair|!pair.nil?}.sort_by{|st, pair| pair.first}
174
+ while st_min = buf.shift
175
+ st, min_pair = st_min
176
+ if key == min_pair.first
177
+ ary.push min_pair.last
178
+ else
179
+ block.call [key, ary] unless ary.empty?
180
+ key = min_pair.first
181
+ ary = [min_pair.last]
182
+ end
183
+ next unless v = st.pop.dc_deep_copy # 取りあえずの対応
184
+ buf.push [st, v]
185
+ buf = buf.sort_by{|st0, v0| v0.first}
186
+ end
187
+ if !ary.empty?
188
+ block.call ary
189
+ end
190
+ },
191
+ :postqueuing_policy => {:queuing_class => :OnMemoryQueue}
192
+ )
193
+
194
+ end
@@ -0,0 +1,84 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "fairy/client/io-filter"
7
+ require "fairy/share/port"
8
+
9
+ module Fairy
10
+ class Here<IOFilter
11
+ include Enumerable
12
+
13
+ module Interface
14
+ def here(opts = nil)
15
+ here = Here.new(@fairy, opts)
16
+ here.input= self
17
+ here
18
+ end
19
+ end
20
+ Fairy::def_filter_interface Interface
21
+
22
+ def initialize(fairy, opts = nil)
23
+ super
24
+ end
25
+
26
+ def backend_class_name
27
+ "CHere"
28
+ end
29
+
30
+ # def each(&block)
31
+ # backend.each{|e| block.call e}
32
+ # end
33
+
34
+ def each(&block)
35
+ policy = @opts[:prequeuing_policy]
36
+
37
+ imports = Queue.new
38
+
39
+ parent_thread = Thread.current
40
+
41
+ Thread.start do
42
+ begin
43
+ backend.each_node do |node|
44
+ node.start_export
45
+ import = Import.new(policy)
46
+ import.set_log_callback do |n, key|
47
+ Log::verbose(self, "IMPORT POP key=#{key}: #{n}")
48
+ end
49
+ import.no_import = 1
50
+ node.export.output = import
51
+ imports.push import
52
+ nil # 消すな!!(BUG#250対応)
53
+ end
54
+ imports.push nil
55
+ rescue Exception
56
+ parent_thread.raise $!
57
+ end
58
+ end
59
+
60
+ while imp = imports.pop
61
+ imp.each do |e|
62
+ block.call e
63
+ end
64
+ end
65
+ end
66
+
67
+ def each_with_bjobeach(&block)
68
+ backend.each_buf do |buf|
69
+ buf.each &block
70
+ # GCの問題
71
+ buf = nil
72
+ end
73
+ end
74
+
75
+ def to_a
76
+ ary = []
77
+ backend.each{|e| ary.push e}
78
+ ary
79
+ end
80
+
81
+ end
82
+
83
+ # class BHere;end
84
+ end
@@ -0,0 +1,70 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "fairy/client/io-filter"
7
+
8
+ module Fairy
9
+ class Inject<IOFilter
10
+
11
+ module Interface
12
+ # filter.inject(%{...}, :init_value = val)
13
+ def inject(block_source, opts = nil)
14
+ block_source = BlockSource.new(block_source)
15
+ inject = Inject.new(@fairy, opts, block_source)
16
+ inject.input = self
17
+ #DeepConnect::future{inject.value}
18
+ inject
19
+ end
20
+
21
+ def min(block_source=nil, opts = nil)
22
+ unless block_source
23
+ block_source = %{|e1, e2| e1 <=> e2}
24
+ end
25
+
26
+ inject(%{|r, v| (proc{#{block_source}}.call(r, v) < 0) ? r : v})
27
+ end
28
+
29
+ def min_by(block_source, opts = nil)
30
+ pair = map(%{|v| [proc{#{block_source}}.call(v), v]})
31
+ min_by = pair.inject(%{|r, v| ((r[0] <=> v[0]) < 0) ? r : v})
32
+ def min_by.value
33
+ super[1]
34
+ end
35
+ min_by
36
+ end
37
+
38
+ def max(block_source=nil, opts = nil)
39
+ unless block_source
40
+ block_source = %{|e1, e2| e1 <=> e2}
41
+ end
42
+
43
+ inject(%{|r, v| (proc{#{block_source}}.call(r, v) < 0) ? v : r})
44
+ end
45
+
46
+ def max_by(block_source, opts = nil)
47
+ pair = map(%{|v| [proc{#{block_source}}.call(v), v]})
48
+ max_by = pair.inject(%{|r, v| ((r[0] <=> v[0]) < 0) ? v : r})
49
+ def max_by.value
50
+ super[1]
51
+ end
52
+ max_by
53
+ end
54
+ end
55
+ Fairy::def_filter_interface Interface
56
+
57
+ def initialize(fairy, opts, block_source)
58
+ super
59
+ @block_source = block_source
60
+ end
61
+
62
+ def backend_class_name
63
+ "CInject"
64
+ end
65
+
66
+ def value
67
+ backend.value
68
+ end
69
+ end
70
+ end