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,107 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ module Fairy
7
+ class Logger
8
+
9
+ LOG_FILE = CONF.LOG_FILE
10
+
11
+ FLUSH_INTERVAL = CONF.LOG_FLUSH_INTERVAL
12
+ MARK_INTERVAL = CONF.LOG_MARK_INTERVAL
13
+ LOG_ROTATE_INTERVAL = CONF.LOG_ROTATE_INTERVAL
14
+
15
+ def initialize(path = LOG_FILE)
16
+ @log_file_path = path
17
+
18
+ open_log
19
+
20
+ @mutex = Mutex.new
21
+ @buffered = false
22
+
23
+ start_flusher
24
+ end
25
+
26
+ def open_log
27
+ begin
28
+ @log_out = File.open(@log_file_path, "a+")
29
+ rescue Errno::ENOENT
30
+ ERR::Fail ERR::NoLogDir, @log_file_path
31
+ rescue
32
+ raise
33
+ end
34
+ @log_open_time = Time.now
35
+ @log_out.puts @log_open_time.strftime("%Y/%m/%d %H:%M:%S -- LOGGER START --")
36
+ @log_out.flush
37
+
38
+ @marked_time = @log_open_time
39
+ end
40
+
41
+ def start_flusher
42
+ Thread.start do
43
+ loop do
44
+ sleep FLUSH_INTERVAL
45
+ @mutex.synchronize do
46
+ if @buffered
47
+ @log_out.flush
48
+ @buffered = false
49
+ end
50
+ now = Time.now
51
+ if MARK_INTERVAL && now - @marked_time > MARK_INTERVAL
52
+ @log_out.puts now.strftime("%Y/%m/%d %H:%M:%S -- MARK --")
53
+ @log_out.flush
54
+ @marked_time = now
55
+ end
56
+ if LOG_ROTATE_INTERVAL && now - @log_open_time > LOG_ROTATE_INTERVAL
57
+ log_rotate
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ def message(message)
65
+ @mutex.synchronize do
66
+ @log_out.puts message
67
+ @buffered = true
68
+ end
69
+ nil
70
+ end
71
+
72
+ def messages(messages)
73
+ @mutex.synchronize do
74
+ messages.each do |m|
75
+ @log_out.puts m
76
+ end
77
+ @buffered = true
78
+ end
79
+ nil
80
+ end
81
+ DeepConnect.def_method_spec(self, "REF messages(DVAL)")
82
+
83
+ def log_rotate
84
+ @log_out.close
85
+ log_back = "#{@log_file_path}.BAK-$$"
86
+ File.rename(@log_file_path, log_back)
87
+ open_log
88
+
89
+ Thread.start do
90
+ files = Dir.glob("#{@log_file_path}.[0-9]*").sort{|f1, f2| f2 <=> f1}
91
+ while files.size >= CONF.LOG_ROTATE_N
92
+ File.unlink(files.shift)
93
+ end
94
+
95
+ files.each do |f|
96
+ fn = f.sub(/\.[0-9]+/){|n| n.succ}
97
+ File.rename(f, fn)
98
+ if /.*\.gz$/ !~ fn
99
+ system("gzip #{fn}")
100
+ end
101
+ end
102
+
103
+ File.rename(log_back, "#{@log_file_path}.0")
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ bjob_dir = File.dirname(__FILE__)
7
+ subdir = File.basename(File.dirname(bjob_dir))
8
+ bjob_name = File.basename(bjob_dir)
9
+ for bjob in Dir.glob("#{bjob_dir}/*.rb")
10
+ base = File.basename(bjob)
11
+ case base
12
+ when /18.rb$/
13
+ next if RUBY_VERSION >= "1.9.0"
14
+ when /19.rb$/
15
+ next unless RUBY_VERSION >= "1.9.0"
16
+ end
17
+ require [subdir, bjob_name, base].join("/")
18
+ end
19
+
20
+
@@ -0,0 +1,17 @@
1
+ # encoding: UTF-8
2
+
3
+ module Fairy
4
+
5
+ class Atom
6
+ def initialize(receiver, message, *args)
7
+ @receiver = receiver
8
+ @message = message
9
+ @args = args
10
+ end
11
+
12
+ attr_reader :receiver, :message, :args
13
+
14
+ end
15
+ end
16
+
17
+
@@ -0,0 +1,283 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "forwardable"
7
+
8
+ require "deep-connect"
9
+
10
+ require "fairy/master/c-filter"
11
+ require "fairy/master/c-inputtable"
12
+ require "fairy/master/c-io-filter"
13
+
14
+ require "fairy/share/block-source"
15
+
16
+ module Fairy
17
+ class CBarrier<CIOFilter
18
+ extend Forwardable
19
+
20
+ Controller.def_export self
21
+
22
+ # include BInputtable
23
+
24
+ DeepConnect.def_single_method_spec(self, "REF new(REF, VAL)")
25
+
26
+ def initialize(controller, opts)
27
+ super
28
+ for k, val in opts.dup
29
+ case k
30
+ when :mode
31
+ @mode = CBarrierMode.create(self, val, opts)
32
+ when :cond
33
+ @cond = CBarrierCond.create(self, val, opts)
34
+ when :buffer
35
+ @buffer = CBarrierBuffer.create(self, val, opts)
36
+ else
37
+ end
38
+ end
39
+ end
40
+
41
+ def each_assigned_filter(&block)
42
+ @mode.wait_exportable
43
+ @buffer.each_assigned_filter(&block)
44
+ end
45
+
46
+ def_delegator :@mode, :wait_export
47
+
48
+ def_delegator :@cond, :wait_cond
49
+
50
+ def_delegator :@buffer, :input=
51
+ def_delegator :@buffer, :output=
52
+
53
+ def_delegator :@buffer, :node_arrived?
54
+ def_delegator :@buffer, :data_arrived?
55
+ def_delegator :@buffer, :all_data_imported?
56
+
57
+ #
58
+ module Factory
59
+ def self.extended(mod)
60
+ mod.init_fact
61
+ end
62
+
63
+ def init_fact
64
+ @ModeName2Class = {}
65
+ end
66
+
67
+ def create(bbarrier, mode, *opts)
68
+ klass = @ModeName2Class[mode]
69
+ ERR::Raise ERR::NoSuchMode, mode unless klass
70
+
71
+ mode = klass.new(bbarrier, mode, *opts)
72
+ mode
73
+ end
74
+
75
+ def register_mode(mode, klass)
76
+ @ModeName2Class[mode] = klass
77
+ end
78
+ end
79
+
80
+ module Mode
81
+ def initialize(bbarrier, mode, *opts)
82
+ @bbarrier = bbarrier
83
+ @mode = mode
84
+ @opts = opts.last
85
+ # Log::debug self, self.class.superclass.name
86
+ begin
87
+ super(*opts)
88
+ rescue
89
+ # for ruby 1.9.1
90
+ super()
91
+ end
92
+ end
93
+ end
94
+
95
+ #
96
+ class CBarrierMode
97
+ extend Factory
98
+ include Mode
99
+
100
+ def initialize(bbarrier, mode, *opts)
101
+ super
102
+ @opts = opts
103
+ end
104
+
105
+ end
106
+
107
+ class CBarrierNodeCreationMode<CBarrierMode
108
+ CBarrierMode.register_mode(:NODE_CREATION, self)
109
+
110
+ def wait_exportable
111
+ @bbarrier.wait_cond
112
+ end
113
+
114
+ def wait_export
115
+ true
116
+ end
117
+
118
+ end
119
+
120
+ class CBarrierStreamMode<CBarrierMode
121
+ CBarrierMode.register_mode(:STREAM, self)
122
+
123
+ def wait_exportable
124
+ true
125
+ end
126
+
127
+ def wait_export
128
+ @bbarrier.wait_cond
129
+ end
130
+
131
+ end
132
+
133
+ #
134
+ class CBarrierCond
135
+ extend Factory
136
+ include Mode
137
+
138
+ def self.create(bbarrier, mode, opts=nil)
139
+ if mode.kind_of?(BlockSource)
140
+ opts[:BLOCK_SOURCE] = mode
141
+ super(bbarrier, :BLOCK_COND, opts)
142
+ else
143
+ super(bbarrier, mode, opts)
144
+ end
145
+ end
146
+
147
+ def wait_cond
148
+ ERR::Raise ERR::NoImpliment, "wait_cond"
149
+ end
150
+
151
+ end
152
+
153
+ class CBarrierNodeArrivedCond<CBarrierCond
154
+ CBarrierCond.register_mode(:NODE_ARRIVED, self)
155
+
156
+ def wait_cond
157
+ @bbarrier.node_arrived?
158
+ end
159
+
160
+ end
161
+
162
+ class CBarrierDataArrivedCond<CBarrierCond
163
+ CBarrierCond.register_mode(:DATA_ARRIVED, self)
164
+
165
+ def wait_cond
166
+ @bbarrier.data_arrived?
167
+ end
168
+
169
+ end
170
+
171
+ class CBarrierAllDataCond<CBarrierCond
172
+ CBarrierCond.register_mode(:ALL_DATA, self)
173
+
174
+ def wait_cond
175
+ @bbarrier.all_data_imported?
176
+ end
177
+ end
178
+
179
+ class CBarrierBlockCond<CBarrierCond
180
+ CBarrierCond.register_mode(:BLOCK_COND, self)
181
+
182
+ def initialize(bbarrier, mode, opts)
183
+ super(bbarrier, mode, opts)
184
+
185
+ if @opts[:BEGIN]
186
+ bs = BScript.new(@opts[:BEGIN],
187
+ @bbarrier.instance_eval{@context},
188
+ @bbarrier)
189
+ bs.evaluate
190
+ end
191
+ @block_source = @opts[:BLOCK_SOURCE]
192
+ @block = BBlock.new(@block_source,
193
+ @bbarrier.instance_eval{@context},
194
+ @bbarrier)
195
+ # @opts[:END] は未サポート
196
+ end
197
+
198
+ def wait_cond
199
+ @block.call
200
+ end
201
+ end
202
+
203
+ #
204
+ class CBarrierBuffer<CIOFilter
205
+ extend Factory
206
+ include Mode
207
+ end
208
+
209
+ class CBarrierMemoryBuffer<CBarrierBuffer
210
+ CBarrierBuffer.register_mode(:MEMORY, self)
211
+
212
+ def initialize(bbarrier, mode, opts=nil)
213
+ super(bbarrier, mode, bbarrier.instance_eval{@controller}, opts)
214
+ end
215
+
216
+ def node_arrived?
217
+ number_of_nodes
218
+ end
219
+
220
+ def data_arrived?
221
+ @nodes_status_mutex.synchronize do
222
+ while !all_node_data_arrived?
223
+ @nodes_status_cv.wait(@nodes_status_mutex)
224
+ end
225
+ end
226
+ true
227
+ end
228
+
229
+ def all_data_imported?
230
+ @nodes_status_mutex.synchronize do
231
+ while !all_node_data_imported?
232
+ @nodes_status_cv.wait(@nodes_status_mutex)
233
+ end
234
+ end
235
+ true
236
+ end
237
+
238
+ def node_class_name
239
+ "PBarrierMemoryBuffer"
240
+ end
241
+
242
+ def wait_export
243
+ @bbarrier.wait_export
244
+ end
245
+
246
+ def all_node_data_arrived?
247
+ return false unless @number_of_nodes
248
+
249
+ data_arrived = true
250
+ each_node(:exist_only) do |node|
251
+ st = @nodes_status[node]
252
+ data_arrived &&= [:ST_ACTIVATE, :ST_ALL_IMPORTED, :ST_FINISH, :ST_EXPORT_FINISH, :ST_WAIT_EXPORT_FINISH].include?(st)
253
+ end
254
+ data_arrived
255
+ end
256
+
257
+ def all_node_data_imported?
258
+ return false unless @number_of_nodes
259
+
260
+ all_data_imported = true
261
+ each_node(:exist_only) do |node|
262
+ st = @nodes_status[node]
263
+ s = [:ST_ALL_IMPORTED, :ST_FINISH, :ST_EXPORT_FINISH, :ST_WAIT_EXPORT_FINISH].include?(st)
264
+ all_data_imported &&= [:ST_ALL_IMPORTED, :ST_FINISH, :ST_EXPORT_FINISH, :ST_WAIT_EXPORT_FINISH].include?(st)
265
+ end
266
+ all_data_imported
267
+ end
268
+
269
+ end
270
+
271
+ class CBarrierFileBuffer<CBarrierBuffer
272
+ CBarrierBuffer.register_mode(:FILE, self)
273
+
274
+ def node_class_name
275
+ "PBarrier::PBarrierFileBuffer"
276
+ end
277
+ end
278
+
279
+ end
280
+ end
281
+
282
+
283
+
@@ -0,0 +1,250 @@
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 CBasicGroupBy<CIOFilter
11
+ Controller.def_export self
12
+
13
+ def initialize(controller, opts, block_source)
14
+ super
15
+ @block_source = block_source
16
+
17
+ @no_of_exports = 0
18
+
19
+ # key -> [export, ...]
20
+ @exports = {}
21
+ @exports_mutex = Mutex.new
22
+ @exports_cv = ConditionVariable.new
23
+
24
+ # @pre_exports_queue = Queue.new
25
+ @exports_queue = Queue.new
26
+
27
+ @each_export_by_thread = nil
28
+ @each_export_by_thread_mutex = Mutex.new
29
+ end
30
+
31
+ def start_create_nodes
32
+ super
33
+
34
+ start_watch_all_node_imported
35
+ end
36
+
37
+ # def each_export(&block)
38
+ # while pair = @exports_queue.pop
39
+ # block.call pair
40
+ # end
41
+ # end
42
+
43
+ # def next_filter(mapper)
44
+ # ret = super
45
+ # unless ret
46
+ # @each_export_by_thread_mutex.synchronize do
47
+ # @each_export_by_thread.join if @each_export_by_thread
48
+ # end
49
+ # end
50
+ # ret
51
+ # end
52
+
53
+ def each_assigned_filter(&block)
54
+ super
55
+
56
+ @each_export_by_thread_mutex.synchronize do
57
+ @each_export_by_thread.join if @each_export_by_thread
58
+ end
59
+ end
60
+
61
+ # def each_export_by(njob, mapper, &block)
62
+ # return if @each_export_by_thread
63
+
64
+ # begin
65
+ # while pair = @exports_queue.pop
66
+ # exp, njob = pair
67
+ # Log::debug(self, "EXPORT_BY, #{exp.key}")
68
+ # block.call exp
69
+ # end
70
+ # rescue
71
+ # Log::fatal_exception
72
+ # end
73
+ # @each_export_by_thread = true
74
+ # end
75
+
76
+ def each_export_by(njob, mapper, &block)
77
+ @each_export_by_thread_mutex.synchronize do
78
+ return if @each_export_by_thread
79
+
80
+ @each_export_by_thread = Thread.start{
81
+ # すべての njob がそろうまで待つ
82
+ # 後段が先にスケジュールされてデッドロックするのを避けるため.
83
+ number_of_nodes
84
+
85
+ begin
86
+ while pair = @exports_queue.pop
87
+ exp, njob = pair
88
+ Log::debug(self, "EXPORT_BY, #{exp.key}")
89
+ block.call exp
90
+
91
+ @exports_mutex.synchronize do
92
+ if @exports[exp.key].first == exp
93
+ @exports[exp.key][1..-1].each do |e|
94
+ e.output = exp.output
95
+ end
96
+ end
97
+ end
98
+ end
99
+ rescue
100
+ Log::fatal_exception
101
+ raise
102
+ end
103
+ }
104
+ end
105
+ end
106
+
107
+ def bind_export(exp, imp)
108
+ # do nothing
109
+ end
110
+
111
+ def add_exports(key, export, njob)
112
+ @exports_mutex.synchronize do
113
+ if exports = @exports[key]
114
+ export.output = exports.first.output if exports.first.output?
115
+ export.no = exports.first.no
116
+ exports.push export
117
+ else
118
+ export.no = @no_of_exports
119
+ @no_of_exports += 1
120
+ @exports[key] = [export]
121
+ @exports_queue.push [export, njob]
122
+ # @pre_exports_queue.push [export, njob]
123
+ end
124
+ end
125
+ end
126
+
127
+ def update_exports(key, export, njob)
128
+ add_exports(key, export, njob)
129
+ nil
130
+ end
131
+
132
+ def node_class_name
133
+ "PBasicGroupBy"
134
+ end
135
+
136
+ def njob_creation_params
137
+ [@block_source]
138
+ end
139
+
140
+ def start_watch_all_node_imported
141
+ Thread.start do
142
+ # すべての njob がそろうまで待つ
143
+ # 後段が先にスケジュールされてデッドロックするのを避けるため.
144
+ Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: S")
145
+ number_of_nodes
146
+
147
+ Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 1")
148
+
149
+
150
+ Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 2")
151
+ # すべての exports がそろうまで待つ
152
+ @nodes_status_mutex.synchronize do
153
+ while !all_node_imported?
154
+ @nodes_status_cv.wait(@nodes_status_mutex)
155
+ end
156
+ end
157
+ @exports_queue.push nil
158
+
159
+ Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 4")
160
+ for key, exports in @exports
161
+ exports.first.output_no_import = exports.size
162
+ end
163
+ Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: E")
164
+ end
165
+ nil
166
+ end
167
+
168
+ def start_watch_all_node_imported_ORG
169
+ Thread.start do
170
+ # すべての njob がそろうまで待つ
171
+ # 後段が先にスケジュールされてデッドロックするのを避けるため.
172
+ Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: S")
173
+ number_of_nodes
174
+
175
+ Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 1")
176
+ # すでに存在するexportsを下流に送る
177
+ @exports_mutex.synchronize do
178
+ Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 1.1")
179
+ @pre_exports_queue.push nil
180
+ while pair = @pre_exports_queue.pop
181
+ Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 1.2: EXP.NO: #{pair[0].no}")
182
+ @exports_queue.push pair
183
+ end
184
+ Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 1.3")
185
+ end
186
+
187
+ Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 2")
188
+ # すべての exports がそろうまで待つ
189
+ @nodes_status_mutex.synchronize do
190
+ while !all_node_imported?
191
+ @nodes_status_cv.wait(@nodes_status_mutex)
192
+ end
193
+ end
194
+
195
+ Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 3")
196
+ # 残りのexportsを下流に送る
197
+ @pre_exports_queue.push nil
198
+ while pair = @pre_exports_queue.pop
199
+ Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 3.1: EXP.NO: #{pair[0].no}")
200
+ @exports_queue.push pair
201
+ end
202
+ @exports_queue.push nil
203
+
204
+ Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: 4")
205
+ #Log::debug(self, "START: setting for EXPOTRS.SIZE")
206
+ for key, exports in @exports
207
+ # exports[1..-1].each do |exp|
208
+ # exp.output=exports.first.output
209
+ # end
210
+
211
+ #Log::debug(self, "EXPOTRS.SIZE=#{exports.size}")
212
+ exports.first.output_no_import = exports.size
213
+ end
214
+ #Log::debug(self, "END: setting for EXPOTRS.SIZE")
215
+ Log::debug(self, "START_WATCH_ALL_NODE_IMPORTED: E")
216
+ end
217
+ nil
218
+ end
219
+
220
+ def all_node_arrived?
221
+ @nodes_mutex.synchronize{@number_of_nodes}
222
+ end
223
+
224
+ def all_node_imported?
225
+ # すべてのnjobがそろったか?
226
+ return false unless @nodes_mutex.synchronize{@number_of_nodes}
227
+
228
+ each_node(:exist_only) do |node|
229
+ st = @nodes_status[node]
230
+ # こちらはNG: outputが設定されていないとまずい.
231
+ # すべてのnodeがそろったとしてもすべてのexportがそろっているとは限らない
232
+ # unless [:ST_FINISH, :ST_EXPORT_FINISH, :ST_WAIT_EXPORT_FINISH, :ST_ALL_IMPORTED].include?(st)
233
+ unless [:ST_FINISH, :ST_EXPORT_FINISH, :ST_WAIT_EXPORT_FINISH].include?(st)
234
+ return false
235
+ end
236
+ end
237
+ true
238
+ end
239
+ end
240
+
241
+ class CBasicMGroupBy<CBasicGroupBy
242
+ Controller.def_export self
243
+
244
+ def node_class_name
245
+ "PBasicMGroupBy"
246
+ end
247
+ end
248
+
249
+
250
+ end