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,45 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "thread"
7
+
8
+ module Fairy
9
+ class Reference
10
+ class NullValue;end
11
+ NULL_VALUE = NullValue.new
12
+
13
+ def initialize
14
+ @value = NULL_VALUE
15
+ @value_mutex = Mutex.new
16
+ @value_cv = ConditionVariable.new
17
+ end
18
+
19
+ def value
20
+ @value_mutex.synchronize do
21
+ while @value == NULL_VALUE
22
+ @value_cv.wait(@value_mutex)
23
+ end
24
+ end
25
+ @value
26
+ end
27
+
28
+ def value=(v)
29
+ @value_mutex.synchronize do
30
+ @value = v
31
+ @value_cv.broadcast
32
+ end
33
+ end
34
+
35
+ def arrived?
36
+ @value_mutex.synchronize do
37
+ @value != NULL_VALUE
38
+ end
39
+ end
40
+
41
+ def wait_arrived
42
+ value
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,56 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "thread"
7
+
8
+ module Fairy
9
+
10
+ class Stdout
11
+ def initialize(peer)
12
+ @local_stdout = $stdout
13
+ @peer = peer
14
+ @threads = {}
15
+
16
+ @mutex = Mutex.new
17
+
18
+ end
19
+
20
+ attr_reader :local_stdout
21
+
22
+ def write(str)
23
+ @mutex.synchronize do
24
+ if @threads[Thread.current]
25
+ @peer.stdout_write(str)
26
+ else
27
+ @local_stdout.write(str)
28
+ end
29
+ end
30
+ end
31
+
32
+ def replace_stdout(&block)
33
+ @mutex.synchronize do
34
+ @threads[Thread.current] = 0 unless @threads[Thread.current]
35
+ @threads[Thread.current] += 1
36
+ end
37
+ begin
38
+ yield
39
+ ensure
40
+ @mutex.synchronize do
41
+ @threads[Thread.current] -= 1
42
+ @threads.delete(Thread.current) if @threads[Thread.current] == 0
43
+ end
44
+ end
45
+ end
46
+
47
+ def flush
48
+ # do nothing
49
+ end
50
+ end
51
+ end
52
+
53
+ #def puts(str)
54
+ # $stdout.write(str+"\n")
55
+ #end
56
+
@@ -0,0 +1,16 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "tracer"
7
+ Tracer.add_filter do |event, file, line, id, binding, klass|
8
+ file =~ /^\./ && file !~ /deep-connect/
9
+ end
10
+
11
+ Tracer.display_process_id = true
12
+ Tracer.display_thread_id = true
13
+ Tracer.display_c_call = false
14
+
15
+ Tracer.on
16
+
@@ -0,0 +1,147 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ module Fairy
7
+ class VArray
8
+ include Enumerable
9
+
10
+ def self.output(fairy, opts)
11
+ OutputVArray.output(fairy, opts)
12
+ end
13
+
14
+ # size がまだ決まっていないときには nil を指定する
15
+ def initialize(arrays_size)
16
+ @arrays = []
17
+ @arrays_size = arrays_size
18
+ @arrays_mutex = Mutex.new
19
+ @arrays_cv = ConditionVariable.new
20
+ end
21
+
22
+ def size
23
+ size = 0
24
+ arrays_each do |array|
25
+ size += array.size
26
+ end
27
+ size
28
+ end
29
+
30
+ def [](idx)
31
+ case idx
32
+ when Integer
33
+ ary_idx, idx = index_on_arrays(idx)
34
+ return @arrays[ary_idx][idx]
35
+ when Range
36
+ ERR::Raise ERR::NoSupportClass, idx
37
+ else
38
+ ERR::Raise ERR::NoSupportClass, idx
39
+ end
40
+ end
41
+
42
+ def []=(idx, val)
43
+ case idx
44
+ when Integer
45
+ ary_idx, idx = index_on_arrays(idx)
46
+ return @arrays[ary_idx][idx]=val
47
+ else
48
+ ERR::Raise ERR::NoSupportClass, idx
49
+ end
50
+ end
51
+
52
+ def each(&block)
53
+ # set_arrayされるまでまっている.
54
+ arrays_size.times do |idx|
55
+ ary = nil
56
+ @arrays_mutex.synchronize do
57
+ while @arrays[idx].nil?
58
+ @arrays_cv.wait(@arrays_mutex)
59
+ end
60
+ ary = @arrays[idx]
61
+ end
62
+ ary.each(&block)
63
+ end
64
+ end
65
+
66
+ # arrays 操作
67
+ def arrays_size
68
+ @arrays_mutex.synchronize do
69
+ while @arrays_size.nil?
70
+ @arrays_cv.wait(@arrays_mutex)
71
+ end
72
+ @arrays_size
73
+ end
74
+ end
75
+
76
+ def arrays_size=(arrays_size)
77
+ @arrays_mutex.synchronize do
78
+ @arrays_size = arrays_size
79
+ @arrays_cv.broadcast
80
+ end
81
+ end
82
+
83
+ # def arrays
84
+ # @arrays_mutex.synchronize do
85
+ # while @arrays_size.nil?
86
+ # @arrays_cv.wait(@arrays_mutex)
87
+ # end
88
+ # @arrays
89
+ # end
90
+ # end
91
+
92
+ # def set_arrays(array)
93
+ # @arrays_mutex.synchronize do
94
+ # @arrays = array
95
+ # @arrays_cv.broadcast
96
+ # end
97
+ # end
98
+
99
+ def arrays_put(idx, array)
100
+ @arrays_mutex.synchronize do
101
+ @arrays[idx] = array
102
+ @arrays_cv.broadcast
103
+ end
104
+ end
105
+
106
+ def arrays_at(idx)
107
+ @arrays_mutex.synchronize do
108
+ while @arrays[idx].nil?
109
+ @arrays_cv.wait(@arrays_mutex)
110
+ end
111
+ @arrays[idx]
112
+ end
113
+ end
114
+
115
+ def index_on_arrays(idx)
116
+ # array_size=されるまでまっている.
117
+ arrays_size.times do |ary_idx|
118
+ ary = nil
119
+ @arrays_mutex.synchronize do
120
+ while !(ary = @arrays[ary_idx])
121
+ @arrays_cv.wait(@arrays_mutex)
122
+ end
123
+ end
124
+ ary_size = ary.size
125
+ if idx < ary_size
126
+ return ary_idx, idx
127
+ end
128
+ idx -= ary_size
129
+ end
130
+ end
131
+
132
+ def arrays_each(&block)
133
+ # array_size=されるまでまっている.
134
+ arrays_size.times do |idx|
135
+ ary = nil
136
+ @arrays_mutex.synchronize do
137
+ while @arrays[idx].nil?
138
+ @arrays_cv.wait(@arrays_mutex)
139
+ end
140
+ ary = @arrays[idx]
141
+ end
142
+ yield ary
143
+ end
144
+ end
145
+ end
146
+ end
147
+
@@ -0,0 +1,183 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (C) 2007-2010 Rakuten, Inc.
4
+ #
5
+
6
+ require "e2mmap"
7
+
8
+ require "fairy/share/conf.rb"
9
+
10
+ module Fairy
11
+ class VFile
12
+ VFILE_EXT = ".vf"
13
+ VFILE_HEADER = "#!fairy vfile"
14
+ VFILE_MAGIC = /^#{Regexp.escape(VFILE_HEADER)}/
15
+
16
+ def VFile.vfile?(path)
17
+ if File.extname(path) == VFILE_EXT
18
+ return true
19
+ end
20
+ if !File.exist?(path)
21
+ return false
22
+ end
23
+
24
+ File.open(path) do |io|
25
+ l = io.gets
26
+ begin
27
+ return VFILE_MAGIC =~ l
28
+ rescue ArgumentError
29
+ return false
30
+ end
31
+ end
32
+ end
33
+
34
+ def VFile.vfile(path)
35
+ vfile = new
36
+ vfile.vfile(path)
37
+ vfile
38
+ end
39
+
40
+ def VFile.real_files(real_files)
41
+ vfile = new
42
+ vfile.real_file_names = real_files
43
+ vfile
44
+ end
45
+
46
+ def initialize
47
+ @vfile_name = nil
48
+
49
+ @real_file_names = []
50
+ @real_file_names_mutex = Mutex.new
51
+ @real_file_names_cv = ConditionVariable.new
52
+
53
+ @base_name = nil
54
+
55
+ @BASE_NAME_CONVERTER = nil
56
+ if CONF.VF_BASE_NAME_CONVERTER
57
+ @BASE_NAME_CONVERTER = eval(CONF.VF_BASE_NAME_CONVERTER)
58
+ end
59
+ end
60
+
61
+ attr_reader :vfile_name
62
+ attr_reader :base_name
63
+
64
+ def vfile_name=(path)
65
+ @vfile_name = path
66
+ #@base_name = File.dirname(path)+"/"+File.basename(path, VFILE_EXT)
67
+ @base_name = File.expand_path(File.dirname(path))+"/"+File.basename(path, VFILE_EXT)
68
+
69
+ if @BASE_NAME_CONVERTER
70
+ @base_name = @BASE_NAME_CONVERTER.call(@base_name)
71
+ end
72
+
73
+ # 絶対パスの場合/を取る(取りあえずの処置)
74
+ while @base_name.sub!(/^\//, ""); end
75
+
76
+ # .. があったときの処理
77
+ while @base_name.sub!(%r{/[^/]*/\.\./?}, ""); end
78
+ while @base_name.sub!(/^\.\./, ""); end
79
+ end
80
+
81
+ def real_file_names
82
+ @real_file_names_mutex.synchronize do
83
+ @real_file_names
84
+ end
85
+ end
86
+
87
+
88
+ def real_file_names=(val)
89
+ @real_file_names_mutex.synchronize do
90
+ @real_file_names=val
91
+ end
92
+ end
93
+
94
+ def vfile(path)
95
+ File.open(path) do |io|
96
+ l = io.gets
97
+ unless VFILE_MAGIC =~ l
98
+ ERR::Raise NoVFile, path
99
+ end
100
+
101
+ files = []
102
+ for l in io
103
+ l.chomp!
104
+ next if l =~ /^\s*$/
105
+ next if l =~ /^\s*#.*$/
106
+ files.push l
107
+ end
108
+
109
+ @real_file_names_mutex.synchronize do
110
+ @real_file_names = files
111
+ end
112
+ end
113
+ end
114
+
115
+ def each_real_file_name(&block)
116
+ real_file_names.dup.each &block
117
+ end
118
+ alias each each_real_file_name
119
+
120
+ def create_vfile
121
+ File.open(@vfile_name, "w") do |io|
122
+ io.puts VFILE_HEADER
123
+ io.puts
124
+ @real_file_names_mutex.synchronize do
125
+ @real_file_names.each do |fn|
126
+ io.puts fn
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ # VF_PREFIX = CONF.VF_PREFIX
133
+ # IPADDR_REGEXP = /::ffff:([0-9]+\.){3}[0-9]+|[0-9a-f]+:([0-9a-f]*:)[0-9a-f]*/
134
+
135
+ # # file name: #{base}-NNN
136
+ # def gen_real_file_name(host, root, no)
137
+
138
+ # if IPADDR_REGEXP =~ host
139
+ # begin
140
+ # host = Resolv.getname(host)
141
+ # rescue
142
+ # # ホスト名が分からない場合 は そのまま ipv6 アドレスにする
143
+ # host = "[#{host}]"
144
+ # end
145
+ # end
146
+
147
+ # base = "file://#{host}#{root}/#{VF_PREFIX}/#{@base_name}"
148
+
149
+ # base_regexp = /^#{Regexp.escape(base)}/
150
+ # fn = nil
151
+ # @real_file_names_mutex.synchronize do
152
+ # ary = @real_file_names.select{|e| base_regexp =~ e}.sort
153
+ # if ary.empty?
154
+ # fn = "#{base}-000"
155
+ # else
156
+ # fn = ary.last.succ
157
+ # end
158
+ # @real_file_names.push fn
159
+ # end
160
+ # fn
161
+ # end
162
+
163
+ def set_real_file(no, url)
164
+ @real_file_names_mutex.synchronize do
165
+ @real_file_names[no] = url
166
+ end
167
+ end
168
+
169
+ # Ruby 1.9 mershal 対応
170
+ # - Ruby 1.9 では mutex を dump できない
171
+ def marshal_dump
172
+ [@vfile_name, @real_file_names]
173
+ end
174
+
175
+ def marshal_load(ary)
176
+ @vfile_name = ary[0]
177
+ @real_file_names = ary[1]
178
+ @real_file_names_mutex = Mutex.new
179
+ @real_file_names_cv = ConditionVariable.new
180
+ end
181
+
182
+ end
183
+ end