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,71 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "fairy/client/basic-group-by"
7
+
8
+ module Fairy
9
+ class MergeGroupBy<IOFilter
10
+
11
+ module Interface
12
+ def merge_group_by(hash_block, opts = nil)
13
+ hash_block = BlockSource.new(hash_block)
14
+ merge_group_by = MergeGroupBy.new(@fairy, opts, hash_block)
15
+ merge_group_by.input = self
16
+ merge_group_by
17
+ end
18
+ end
19
+ Fairy::def_filter_interface Interface
20
+ # ::Fairy::Def_Post_Initialize{Post_Initialize}
21
+
22
+ # Unhandlemethods = [
23
+ # :Post_Mod_Group_By_Filter,
24
+ # :Post_Merge_Group_By_Filter
25
+ # ]
26
+ # Def Self.Post_Initialize
27
+ # For Interface In ::Fairy::Jobinterfaces
28
+ # For M In Interface.Instance_Methods
29
+ # M = M.Intern If M.Kind_Of?(String)
30
+ # Next If Unhandlemethods.Include?(M)
31
+
32
+ # M = M.Id2name
33
+ # Mergegroupby::Module_Eval %{
34
+ # Def #{M}(*Argv, &Block)
35
+ # Post_Merge_Group_By_Filter(@Block_Source, @Opts).#{M}(*Argv, &Block)
36
+ # End
37
+ # }
38
+ # End
39
+ # End
40
+ # End
41
+
42
+ def initialize(fairy, opts, block_source)
43
+ super
44
+ @block_source = block_source
45
+ end
46
+
47
+ def backend_class_name
48
+ "CMergeGroupBy"
49
+ end
50
+
51
+ # class PostFilter<Filter
52
+ # module Interface
53
+ # def post_merge_group_by_filterr(hash_block, opts = nil)
54
+ # post_merge_group_by_filter = PostFilter.new(@fairy, opts, hash_block)
55
+ # post_merge_group_by_filter.input = self
56
+ # post_merge_group_by_filter
57
+ # end
58
+ # Fairy::def_filter_interface Interface
59
+ # end
60
+
61
+ # def initialize(fairy, opts, block_source)
62
+ # super
63
+ # @block_source = block_source
64
+ # end
65
+
66
+ # def backend_class_name
67
+ # "BMergeGroupBy::BPostFilter"
68
+ # end
69
+ # end
70
+ end
71
+ end
@@ -0,0 +1,64 @@
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 OutputFile < Filter
11
+
12
+ def OutputFile.output(fairy, opts, vfn)
13
+ ffile = new(fairy, opts)
14
+ ffile.output(vfn)
15
+ ffile
16
+ end
17
+
18
+ def initialize(fairy, opts=nil)
19
+ super
20
+
21
+ @old_vfile = nil
22
+ @vfile = nil
23
+ end
24
+
25
+ def backend_class_name
26
+ "COutputFile"
27
+ end
28
+
29
+ def output(vfn)
30
+ if File.exists?(vfn)
31
+ @old_vfile = VFile.vfile(vfn)
32
+ end
33
+
34
+ @descripter = vfn
35
+ @vfile = VFile.new
36
+ @vfile.vfile_name = vfn
37
+ backend.output(@vfile)
38
+
39
+ # vf.create_vfile(vfn)
40
+ end
41
+
42
+ def input=(job)
43
+ @input = job
44
+ backend.input=job.backend
45
+ backend.wait_all_output_finished
46
+
47
+ if @old_vfile
48
+ rmfiles = @old_vfile.real_file_names.zip(@vfile.real_file_names).select{|n1, n2| n1 != n2}.map{|n1, n2| n1}
49
+ if !rmfiles.empty?
50
+ rm = @fairy.exec(rmfiles).map(%{|uri|
51
+ path = URI(uri).path
52
+ begin
53
+ File.unlink(path)
54
+ rescue
55
+ end
56
+ }, :BEGIN => %{require "uri"})
57
+ rm.done
58
+ end
59
+ end
60
+ @vfile.create_vfile
61
+ end
62
+ end
63
+
64
+ end
@@ -0,0 +1,60 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "fairy/client/here"
7
+
8
+ require "fairy/share/vfile"
9
+
10
+ module Fairy
11
+ class OutputLocalFile<Here
12
+
13
+ def OutputLocalFile.output(fairy, opts, filename)
14
+ ffile = new(fairy, opts)
15
+ ffile.output(filename)
16
+ ffile
17
+ end
18
+
19
+ def initialize(fairy, opts=nil)
20
+ super
21
+ @filename = nil
22
+ end
23
+
24
+ def backend_class_name
25
+ "COutputLocalFile"
26
+ end
27
+
28
+ def output(filename)
29
+ @filename = filename
30
+ # backend.output(self)
31
+ end
32
+
33
+ def input=(job)
34
+ super
35
+
36
+ File.open(@filename, "w") do |io|
37
+ each do |e|
38
+ io.puts e
39
+ end
40
+ end
41
+ end
42
+
43
+ # def input=(job)
44
+ # @input = job
45
+ # backend.input=job.backend
46
+
47
+ # File.open(@filename, "w") do |io|
48
+ # backend.each_buf do |buf|
49
+ # buf.each do |l|
50
+ # io.puts l
51
+ # # l = nil # 効果無し
52
+ # end
53
+ # # GCの問題[BUG: #135]
54
+ # buf.clear # 50/200
55
+ # buf = nil # 59/200
56
+ # end
57
+ # end
58
+ # end
59
+ end
60
+ end
@@ -0,0 +1,47 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "fairy/client/filter"
7
+ require "fairy/share/varray"
8
+
9
+ module Fairy
10
+ class OutputNull<Filter
11
+ module Interface
12
+ # Usage:
13
+ # ... .done
14
+ #
15
+ def done
16
+ output_null = OutputNull.output(@fairy, opts=nil)
17
+ output_null.input = self
18
+ output_null
19
+ end
20
+ alias do done
21
+ end
22
+ Fairy::def_filter_interface Interface
23
+
24
+ def self.output(fairy, opts)
25
+ output = new(fairy, opts)
26
+ output
27
+ end
28
+
29
+ def initialize(fairy, opts=nil)
30
+ super
31
+ end
32
+
33
+ def backend_class_name
34
+ "COutputNull"
35
+ end
36
+
37
+ def output
38
+ backend.output
39
+ end
40
+
41
+ def input=(job)
42
+ @input = job
43
+ backend.input=job.backend
44
+ backend.wait_all_output_finished
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,50 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "fairy/client/filter"
7
+ require "fairy/share/varray"
8
+
9
+ module Fairy
10
+ class OutputVArray<Filter
11
+ module Interface
12
+ # Usage:
13
+ # ... .to_va
14
+ #
15
+ def to_va
16
+ output_va = OutputVArray.output(@fairy, opts=nil)
17
+ output_va.input = self
18
+ output_va.varray
19
+ end
20
+ end
21
+ Fairy::def_filter_interface Interface
22
+
23
+ def self.output(fairy, opts)
24
+ output = new(fairy, opts)
25
+ output
26
+ end
27
+
28
+ def initialize(fairy, opts=nil)
29
+ super
30
+
31
+ @varray = backend.varray
32
+ end
33
+
34
+ attr_reader :varray
35
+
36
+ def backend_class_name
37
+ "COutputVArray"
38
+ end
39
+
40
+ def output
41
+ backend.output
42
+ end
43
+
44
+ def input=(job)
45
+ @input = job
46
+ backend.input=job.backend
47
+ # backend.wait_all_output_finished
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ module Fairy
7
+
8
+ module OutputInterface
9
+ def output(vfn, opts = nil)
10
+ if vfn.kind_of?(Class)
11
+ outputter = vfn.output(@fairy, opts)
12
+ elsif !vfn.kind_of?(String) || VFile.vfile?(vfn)
13
+ outputter = OutputFile.output(@fairy, opts, vfn)
14
+ else
15
+ outputter = OutputLocalFile.output(@fairy, opts, vfn)
16
+ end
17
+ outputter.input = self
18
+ outputter
19
+
20
+ end
21
+ end
22
+ def_filter_interface OutputInterface
23
+
24
+ end
25
+
26
+ require "fairy/client/output-file"
27
+ require "fairy/client/output-local-file"
28
+
29
+
@@ -0,0 +1,62 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "fairy/client/filter"
7
+ require "fairy/client/seg-map"
8
+
9
+ module Fairy
10
+ module RomaPutInterface
11
+
12
+ DEFAULT_SPLIT = 100
13
+
14
+ def roma_put(ap, base_key, split=DEFAULT_SPLIT, opts={})
15
+ ap = [ap] if ap.kind_of?(String)
16
+
17
+ @fairy.def_pool_variable(:__ROMA_PUT_ap, ap)
18
+ @fairy.def_pool_variable(:__ROMA_PUT_base_key, base_key)
19
+ @fairy.def_pool_variable(:__ROMA_PUT_split, split)
20
+
21
+ if opts[:nice]
22
+ @fairy.def_pool_variable(:__ROMA_PUT_nice, opts[:nice])
23
+ else
24
+ @fairy.def_pool_variable(:__ROMA_PUT_nice, 0)
25
+ end
26
+
27
+ seg_map(%{|i, block|
28
+ system('renice '+@Pool.__ROMA_PUT_nice.to_s+' '+$$.to_s) unless @Pool.__ROMA_PUT_nice.zero?
29
+
30
+ require 'roma/client/rclient'
31
+
32
+ @roma = Roma::Client::RomaClient.new(@Pool.__ROMA_PUT_ap.dc_deep_copy)
33
+ @base_key = @Pool.__ROMA_PUT_base_key + $$.to_s + '_' + __id__.to_s
34
+ @split = @Pool.__ROMA_PUT_split
35
+
36
+ buf = []
37
+ cnt = 0
38
+ put_cnt = 0
39
+ i.each{|e|
40
+ cnt += 1
41
+ buf << e
42
+ if (cnt % @split == 0)
43
+ key = @base_key + ('%03d' % put_cnt)
44
+ @roma[key] = buf.join(',')
45
+ block.call(key)
46
+ buf.clear
47
+ put_cnt += 1
48
+ end
49
+ }
50
+ if buf.size > 0
51
+ key = @base_key + ('%03d' % put_cnt)
52
+ @roma[key] = buf.join(',')
53
+ block.call(key)
54
+ buf.clear
55
+ end
56
+ })
57
+ end
58
+
59
+ Fairy::def_filter_interface RomaPutInterface
60
+
61
+ end
62
+ end
@@ -0,0 +1,156 @@
1
+ # encoding: UTF-8
2
+
3
+
4
+ module Fairy
5
+ module RomaInterface
6
+ DUMP_KEY_PREFIX = '__dump_by_fairy__'
7
+ DEFAULT_HASH_NAME = 'roma'
8
+ DEFAULT_FORMAT = [5, 7]
9
+
10
+ attr_reader :dump_id, :dump_key
11
+
12
+ #
13
+ # input data from ROMA
14
+ #
15
+ # ex)
16
+ # require 'fairy'
17
+ #
18
+ # fairy = Fairy::Fairy.new
19
+ # f0 = fairy.roma(
20
+ # 'fairy-xm01_11211',
21
+ # :format=>[5,7,1],
22
+ # :select=>%{|k,v,t| v.to_i >= 500 && v.to_i < 600},
23
+ # :map=>%{|k,v,t| [k.sub(/^key-/, ''), v, v.to_i, Time.at(t).strftime('%Y-%m-%d %H:%M:%S')]},
24
+ # :nice=>20
25
+ # )
26
+ # f1 = f0.map(%{|*ary| ary.join(",")})
27
+ # f1.output('./roma_test.out')
28
+ #
29
+ # available options are:
30
+ # :hash name of destination hash. '*' means all hashes (defalut='roma')
31
+ # :format fields of CSV. specify by Array (default=[5, 7])
32
+ # available fields:
33
+ # 0: virtual node ID
34
+ # 1: last modified time (UNIX timestamp)
35
+ # 2: logical clock
36
+ # 3: expire time
37
+ # 4: key length
38
+ # 5: key
39
+ # 6: value length
40
+ # 7: value
41
+ # :select block source to select particular records
42
+ # :map block source to apply to each records
43
+ # :nice priority of process (LOW 20 <--> -20 HIGH)
44
+ #
45
+ def roma(addr_port, opts={})
46
+ addr_port = [addr_port] if addr_port.kind_of?(String)
47
+
48
+ require 'roma/client/export/rdump'
49
+
50
+ @@roma_dump_serial_no ||= 0
51
+ @@roma_dump_serial_no += 1
52
+ @dump_id = "#{`hostname`.chomp}_#{Time.now.strftime("%y%m%d%H%M%S")}_#{$$}_#{@@roma_dump_serial_no}"
53
+ @dump_key = DUMP_KEY_PREFIX+dump_id
54
+ dumpinfo = Roma::Client::Export::RomaDump.dump(dump_key, dump_id, addr_port)
55
+
56
+ ##############################################
57
+ # structure of dumpinfo
58
+ # {
59
+ # "hostname1_port1" => "STARTED path"
60
+ # "hostname1_port2" => "STARTED path"
61
+ # "hostname2_port1" => "STARTED path"
62
+ # ...
63
+ # }
64
+ ##############################################
65
+
66
+ uris = []
67
+ dumpinfo.each{|host_port, stat_path|
68
+ m = host_port.match(/\A(.*)_\d+\z/)
69
+ host = m[1]
70
+ m2 = stat_path.match(/\A\S+\s+(.*)\z/)
71
+ path = m2[1]
72
+ uris << 'file://'+host+path
73
+ }
74
+
75
+ f0 = exec(uris)
76
+
77
+ if opts[:hash]
78
+ self.def_pool_variable(:dest_hash, opts[:hash])
79
+ else
80
+ self.def_pool_variable(:dest_hash, DEFAULT_HASH_NAME)
81
+ end
82
+
83
+ if opts[:nice]
84
+ self.def_pool_variable(:nice, opts[:nice])
85
+ else
86
+ self.def_pool_variable(:nice, 0)
87
+ end
88
+
89
+ f1 = f0.mapf(%q{|uri|
90
+ dumpfiles = Dir.glob(URI(uri).path+"/#{@dest_hash}/*.dump")
91
+ dumpfiles
92
+ }, :BEGIN => %q{
93
+ require 'uri'
94
+ @dest_hash = @Pool.dest_hash
95
+ system("renice #{@Pool.nice} #{$$}") unless @Pool.nice.zero?
96
+ })
97
+
98
+ if opts[:format]
99
+ self.def_pool_variable(:format, opts[:format])
100
+ else
101
+ self.def_pool_variable(:format, DEFAULT_FORMAT)
102
+ end
103
+
104
+ if opts[:select]
105
+ src = add_proc_src(opts[:select])
106
+ eval(src) # syntax check
107
+ self.def_pool_variable(:select, src)
108
+ else
109
+ self.def_pool_variable(:select, '')
110
+ end
111
+
112
+ if opts[:map]
113
+ src = add_proc_src(opts[:map])
114
+ eval(src) # syntax check
115
+ self.def_pool_variable(:map, src)
116
+ else
117
+ self.def_pool_variable(:map, '')
118
+ end
119
+
120
+ f2 = f1.mapf(%q{|dumpf|
121
+ records = []
122
+ File.open(dumpf, 'rb'){|io|
123
+ Roma::Client::Export::RomaDump.load(io) {|*rec|
124
+ rec_formatted = @format.inject([]){|res, idx| res << rec[idx]}
125
+ next if @select && !@select.call(*rec_formatted)
126
+ if @map
127
+ records << @map.call(rec_formatted)
128
+ else
129
+ records << rec_formatted
130
+ end
131
+ }
132
+ }
133
+ records
134
+ }, :N => 1, :BEGIN => %q{
135
+ require 'roma/client/export/rdump'
136
+ @format = @Pool.format.dc_deep_copy
137
+ @select = eval(@Pool.select) unless @Pool.select.empty?
138
+ @map = eval(@Pool.map) unless @Pool.map.empty?
139
+ })
140
+
141
+ f2
142
+ end
143
+
144
+ private
145
+ def add_proc_src(src)
146
+ if src =~ /\A{.*}\z/
147
+ 'Proc.new'+src
148
+ else
149
+ 'Proc.new{'+src+'}'
150
+ end
151
+ end
152
+ end
153
+ def_fairy_interface RomaInterface
154
+ end
155
+
156
+