pwrake 0.9.7 → 0.9.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/pwrake/application.rb +1 -0
- data/lib/pwrake/cache_aware_queue.rb +184 -0
- data/lib/pwrake/gfarm_feature.rb +5 -33
- data/lib/pwrake/gfwhere_pool.rb +112 -0
- data/lib/pwrake/locality_aware_queue.rb +15 -13
- data/lib/pwrake/master.rb +13 -5
- data/lib/pwrake/option.rb +14 -9
- data/lib/pwrake/report/parallelism.rb +154 -29
- data/lib/pwrake/report/report.rb +14 -6
- data/lib/pwrake/report/report_multi.rb +2 -2
- data/lib/pwrake/shell.rb +13 -17
- data/lib/pwrake/task_algorithm.rb +136 -15
- data/lib/pwrake/task_queue.rb +310 -67
- data/lib/pwrake/version.rb +1 -1
- metadata +4 -2
@@ -24,6 +24,27 @@ module Pwrake
|
|
24
24
|
a.sort{|x,y| x[0]<=>y[0]}
|
25
25
|
end
|
26
26
|
|
27
|
+
def count_start_end_from_csv_table(csvtable)
|
28
|
+
a = []
|
29
|
+
start_time = nil
|
30
|
+
|
31
|
+
csvtable.each do |row|
|
32
|
+
if row['command'] == 'pwrake_profile_start'
|
33
|
+
start_time = Time.parse(row['start_time'])
|
34
|
+
elsif row['command'] == 'pwrake_profile_end'
|
35
|
+
t = Time.parse(row['start_time']) - start_time
|
36
|
+
a << [t,0]
|
37
|
+
elsif start_time
|
38
|
+
t = Time.parse(row['start_time']) - start_time
|
39
|
+
a << [t,+1]
|
40
|
+
t = Time.parse(row['end_time']) - start_time
|
41
|
+
a << [t,-1]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
a.sort{|x,y| x[0]<=>y[0]}
|
46
|
+
end
|
47
|
+
|
27
48
|
def exec_density(a)
|
28
49
|
reso = 0.1
|
29
50
|
delta = 1/reso
|
@@ -98,51 +119,41 @@ plot '#{fpara}' w l axis x1y1 title 'parallelism'
|
|
98
119
|
end
|
99
120
|
|
100
121
|
|
101
|
-
def plot_parallelism2(
|
102
|
-
a =
|
122
|
+
def plot_parallelism2(csvtable, base)
|
123
|
+
a = count_start_end_from_csv_table(csvtable)
|
103
124
|
return if a.size < 4
|
104
125
|
|
105
126
|
density = exec_density(a)
|
106
127
|
|
107
|
-
base = file.sub(/\.csv$/,"")
|
108
|
-
fpara = base+"_para.dat"
|
109
|
-
fdens = base+'_dens.dat'
|
110
128
|
fimg = base+'.png'
|
111
129
|
|
112
|
-
File.open(fdens,"w") do |f|
|
113
|
-
density.each do |t,d|
|
114
|
-
f.puts "#{t} #{d}"
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
130
|
n = a.size
|
119
131
|
i = 0
|
120
132
|
y = 0
|
121
133
|
y_max = 0
|
122
134
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
end
|
133
|
-
y += a[i][1]
|
134
|
-
y_pre = y
|
135
|
-
y_max = y if y > y_max
|
135
|
+
para = []
|
136
|
+
begin
|
137
|
+
t = 0
|
138
|
+
y_pre = 0
|
139
|
+
n.times do |i|
|
140
|
+
if a[i][0]-t > 0.001
|
141
|
+
para.push "%.3f %d" % [t, y_pre]
|
142
|
+
t = a[i][0]
|
143
|
+
para.push "%.3f %d" % [t, y]
|
136
144
|
end
|
137
|
-
|
138
|
-
|
145
|
+
y += a[i][1]
|
146
|
+
y_pre = y
|
147
|
+
y_max = y if y > y_max
|
139
148
|
end
|
149
|
+
rescue
|
150
|
+
p a[i]
|
140
151
|
end
|
141
152
|
|
142
153
|
t_end = (a.last)[0]
|
143
154
|
|
144
155
|
IO.popen("gnuplot","r+") do |f|
|
145
|
-
f.
|
156
|
+
f.print "
|
146
157
|
set terminal png
|
147
158
|
set output '#{fimg}'
|
148
159
|
#set rmargin 10
|
@@ -156,8 +167,16 @@ set y2label 'exec/sec'
|
|
156
167
|
set arrow 1 from #{t_end},#{y_max*0.5} to #{t_end},0 linecolor rgb 'blue'
|
157
168
|
set label 1 \"#{t_end}\\nsec\" at first #{t_end},#{y_max*0.5} right front textcolor rgb 'blue'
|
158
169
|
|
159
|
-
plot '
|
170
|
+
plot '-' w l axis x1y1 title 'parallelism', '-' w l axis x1y2 title 'exec/sec'
|
160
171
|
"
|
172
|
+
para.each do |x|
|
173
|
+
f.puts x
|
174
|
+
end
|
175
|
+
f.puts "e"
|
176
|
+
|
177
|
+
density.each do |t,d|
|
178
|
+
f.puts "#{t} #{d}"
|
179
|
+
end
|
161
180
|
end
|
162
181
|
|
163
182
|
#puts "Parallelism plot: #{fimg}"
|
@@ -188,6 +207,112 @@ plot '#{fpara}' w l axis x1y1 title 'parallelism', '#{fdens}' w l axis x1y2 titl
|
|
188
207
|
a
|
189
208
|
end
|
190
209
|
|
210
|
+
|
211
|
+
def get_command_key(s, pattern)
|
212
|
+
pattern.each do |cmd,regex|
|
213
|
+
if regex =~ s
|
214
|
+
return cmd
|
215
|
+
end
|
216
|
+
end
|
217
|
+
if /\(([^()]+)\)/ =~ s
|
218
|
+
s = $1
|
219
|
+
end
|
220
|
+
a = s.split(/;/)
|
221
|
+
a.each do |x|
|
222
|
+
if /^\s*(\S+)/ =~ x
|
223
|
+
k = $1
|
224
|
+
next if k=='cd'
|
225
|
+
return k
|
226
|
+
end
|
227
|
+
end
|
228
|
+
nil
|
229
|
+
end
|
230
|
+
|
231
|
+
def count_start_end_by_pattern(csvtable, pattern)
|
232
|
+
h = Hash.new
|
233
|
+
start_time = nil
|
234
|
+
|
235
|
+
csvtable.each do |row|
|
236
|
+
command = row['command']
|
237
|
+
if command == 'pwrake_profile_start'
|
238
|
+
start_time = Time.parse(row['start_time'])
|
239
|
+
elsif command == 'pwrake_profile_end'
|
240
|
+
t = Time.parse(row['start_time']) - start_time
|
241
|
+
h.values.each do |a|
|
242
|
+
a << [t,0]
|
243
|
+
end
|
244
|
+
elsif start_time
|
245
|
+
cmd = get_command_key(command, pattern)
|
246
|
+
h[cmd] ||= []
|
247
|
+
t = Time.parse(row['start_time']) - start_time
|
248
|
+
h[cmd] << [t,+1]
|
249
|
+
t = Time.parse(row['end_time']) - start_time
|
250
|
+
h[cmd] << [t,-1]
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
h.each do |k,a|
|
255
|
+
a.sort!{|x,y| x[0]<=>y[0]}
|
256
|
+
end
|
257
|
+
h
|
258
|
+
end
|
259
|
+
|
260
|
+
def plot_parallelism_by_pattern(csvtable, base, pattern)
|
261
|
+
y_max = 0
|
262
|
+
t_end = 0
|
263
|
+
para = {}
|
264
|
+
t_pat = count_start_end_by_pattern(csvtable, pattern)
|
265
|
+
t_pat.each do |cmd,a|
|
266
|
+
n = a.size
|
267
|
+
i = 0
|
268
|
+
y = 0
|
269
|
+
para[cmd] = dat = []
|
270
|
+
begin
|
271
|
+
t = 0
|
272
|
+
y_pre = 0
|
273
|
+
n.times do |i|
|
274
|
+
if a[i][0]-t > 0.001
|
275
|
+
dat.push "%.3f %d" % [t, y_pre]
|
276
|
+
t = a[i][0]
|
277
|
+
dat.push "%.3f %d" % [t, y]
|
278
|
+
end
|
279
|
+
y += a[i][1]
|
280
|
+
y_pre = y
|
281
|
+
y_max = y if y > y_max
|
282
|
+
end
|
283
|
+
rescue
|
284
|
+
p a[i]
|
285
|
+
end
|
286
|
+
if (a.last)[0] > t_end
|
287
|
+
t_end = (a.last)[0]
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
fimg = base+'_para_cmd.png'
|
292
|
+
|
293
|
+
IO.popen("gnuplot","r+") do |f|
|
294
|
+
#begin f = $stdout
|
295
|
+
f.print "
|
296
|
+
set terminal png
|
297
|
+
set output '#{fimg}'
|
298
|
+
set title '#{base}'
|
299
|
+
set xlabel 'time (sec)'
|
300
|
+
set ylabel 'parallelism'
|
301
|
+
"
|
302
|
+
f.print "plot "
|
303
|
+
f.puts para.map{|cmd,re| "'-' w l title '#{cmd}'"}.join(",")
|
304
|
+
para.each do |cmd,dat|
|
305
|
+
dat.each do |x|
|
306
|
+
f.puts x
|
307
|
+
end
|
308
|
+
f.puts "e"
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
#puts "Parallelism plot: #{fimg}"
|
313
|
+
fimg
|
314
|
+
end
|
315
|
+
|
191
316
|
def timeline_to_grid(a)
|
192
317
|
resolution = Rational(1,10)
|
193
318
|
|
@@ -209,7 +334,7 @@ plot '#{fpara}' w l axis x1y1 title 'parallelism', '#{fdens}' w l axis x1y2 titl
|
|
209
334
|
return grid
|
210
335
|
end
|
211
336
|
|
212
|
-
def
|
337
|
+
def plot_parallelism_by_host(csvtable,base)
|
213
338
|
fpng = base+"_para_host.png"
|
214
339
|
data = read_time_by_host_from_csv(csvtable)
|
215
340
|
return fpng if data.size == 0
|
data/lib/pwrake/report/report.rb
CHANGED
@@ -50,10 +50,12 @@ EOL
|
|
50
50
|
|
51
51
|
@sh_table = CSV.read(@csv_file,:headers=>true)
|
52
52
|
h = {}
|
53
|
+
@elap_sum = 0
|
53
54
|
@sh_table.each do |row|
|
54
55
|
if host = row['host']
|
55
56
|
h[host] = true
|
56
57
|
end
|
58
|
+
@elap_sum += row['elap_time'].to_f
|
57
59
|
end
|
58
60
|
@hosts = h.keys.sort
|
59
61
|
@start_time = Time.parse(@sh_table[0]["start_time"])
|
@@ -153,7 +155,9 @@ EOL
|
|
153
155
|
html << "<table>\n"
|
154
156
|
html << "<tr><th>log file</th><td>#{@base}</td><tr>\n"
|
155
157
|
html << "<tr><th>ncore</th><td>#{@ncore}</td><tr>\n"
|
156
|
-
html << "<tr><th>elapsed time
|
158
|
+
html << "<tr><th>elapsed time</th><td>%.3f sec</td><tr>\n"%[@elap]
|
159
|
+
html << "<tr><th>cumulative process time</th><td>%.3f sec</td><tr>\n"%[@elap_sum]
|
160
|
+
html << "<tr><th>occupancy</th><td>%.3f %%</td><tr>\n"%[@elap_sum/@elap/@ncore*100]
|
157
161
|
html << "<tr><th>start time</th><td>#{@start_time}</td><tr>\n"
|
158
162
|
html << "<tr><th>end time</th><td>#{@end_time}</td><tr>\n"
|
159
163
|
html << "</table>\n"
|
@@ -164,12 +168,16 @@ EOL
|
|
164
168
|
end
|
165
169
|
html << "</table>\n"
|
166
170
|
html << "<h2>Parallelism</h2>\n"
|
167
|
-
fimg = Parallelism.plot_parallelism2(@
|
168
|
-
html << "<img src='
|
171
|
+
fimg = Parallelism.plot_parallelism2(@sh_table,@base)
|
172
|
+
html << "<img src='./#{File.basename(fimg)}' align='top'/></br>\n"
|
173
|
+
|
174
|
+
html << "<h2>Parallelism by command</h2>\n"
|
175
|
+
fimg3 = Parallelism.plot_parallelism_by_pattern(@sh_table,@base,@pattern)
|
176
|
+
html << "<img src='./#{File.basename(fimg3)}' align='top'/></br>\n"
|
169
177
|
|
170
178
|
html << "<h2>Parallelism by host</h2>\n"
|
171
|
-
fimg2 = Parallelism.
|
172
|
-
html << "<img src='
|
179
|
+
fimg2 = Parallelism.plot_parallelism_by_host(@sh_table,@base)
|
180
|
+
html << "<img src='./#{File.basename(fimg2)}' align='top'/></br>\n"
|
173
181
|
|
174
182
|
html << "<h2>Command statistics</h2>\n"
|
175
183
|
html << "<table>\n"
|
@@ -182,7 +190,7 @@ EOL
|
|
182
190
|
html << "</tr>\n"
|
183
191
|
end
|
184
192
|
html << "<table>\n"
|
185
|
-
html << "<img src='
|
193
|
+
html << "<img src='./#{File.basename(histogram_plot)}' align='top'/></br>\n"
|
186
194
|
|
187
195
|
task_locality
|
188
196
|
html << "<h2>Locality statistics</h2>\n"
|
@@ -29,7 +29,7 @@ module Pwrake
|
|
29
29
|
end
|
30
30
|
html << "</table>\n"
|
31
31
|
html << "<h2>Elapsed time</h2>\n"
|
32
|
-
html << "<img src='
|
32
|
+
html << "<img src='./#{File.basename(@elap_png)}' align='top'/></br>\n"
|
33
33
|
|
34
34
|
html << "<h2>Histogram of Execution time</h2>\n"
|
35
35
|
html << report_histogram()
|
@@ -97,7 +97,7 @@ plot #{a}/x,'-' w lp lw 2 ps 2 title 'elapsed time'
|
|
97
97
|
html << "<tr><td>#{id}</td><td>#{r.ncore}</td>" + s.html_td + "</tr>\n"
|
98
98
|
end
|
99
99
|
html << "</table>\n"
|
100
|
-
html << "<img src='./#{@images[cmd]}'/>\n"
|
100
|
+
html << "<img src='./#{File.basename(@images[cmd])}'/>\n"
|
101
101
|
end
|
102
102
|
html
|
103
103
|
end
|
data/lib/pwrake/shell.rb
CHANGED
@@ -19,9 +19,6 @@ module Pwrake
|
|
19
19
|
@@current_id = 0
|
20
20
|
@@profiler = Profiler.new
|
21
21
|
|
22
|
-
# @@global_lock = Mutex.new
|
23
|
-
# @@last_exec_time = Time.now
|
24
|
-
|
25
22
|
def self.profiler
|
26
23
|
@@profiler
|
27
24
|
end
|
@@ -35,7 +32,6 @@ module Pwrake
|
|
35
32
|
@work_dir = @option[:work_dir] || Dir.pwd
|
36
33
|
@pass_env = @option[:pass_env]
|
37
34
|
@ssh_opt = @option[:ssh_opt]
|
38
|
-
# @ssh_min_exec_interval = Pwrake.application.pwrake_options['SHELL_MIN_EXEC_INTERVAL'].to_f
|
39
35
|
@terminator = ""
|
40
36
|
TLEN.times{ @terminator << CHARS[rand(CHARS.length)] }
|
41
37
|
end
|
@@ -152,19 +148,6 @@ module Pwrake
|
|
152
148
|
raise "@io is closed" if @io.closed?
|
153
149
|
status = nil
|
154
150
|
|
155
|
-
# t0 = Time.now
|
156
|
-
# @@global_lock.synchronize do
|
157
|
-
# t = Time.now - @@last_exec_time
|
158
|
-
# if t < @ssh_min_exec_interval
|
159
|
-
# sleep @ssh_min_exec_interval-t
|
160
|
-
# end
|
161
|
-
# @@last_exec_time = Time.now
|
162
|
-
# end
|
163
|
-
# t = Time.now-t0
|
164
|
-
# #if t>0.001
|
165
|
-
# Log.info "-- locktime %.6f"%t
|
166
|
-
# #end
|
167
|
-
|
168
151
|
start_time = Time.now
|
169
152
|
begin
|
170
153
|
@io.puts @@profiler.command(cmd,@terminator)
|
@@ -187,4 +170,17 @@ module Pwrake
|
|
187
170
|
end
|
188
171
|
end
|
189
172
|
|
173
|
+
|
174
|
+
class NoActionShell < Shell
|
175
|
+
def initialize()
|
176
|
+
@host = '(noaction)'
|
177
|
+
@@current_id += 1
|
178
|
+
@id = @@current_id
|
179
|
+
end
|
180
|
+
def start
|
181
|
+
end
|
182
|
+
def finish
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
190
186
|
end # module Pwrake
|
@@ -3,6 +3,50 @@ module Pwrake
|
|
3
3
|
InvocationChain = Rake::InvocationChain
|
4
4
|
TaskArguments = Rake::TaskArguments
|
5
5
|
|
6
|
+
class RankStat
|
7
|
+
def initialize
|
8
|
+
@lock = Mutex.new
|
9
|
+
@stat = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_sample(rank,elap)
|
13
|
+
@lock.synchronize do
|
14
|
+
stat = @stat[rank]
|
15
|
+
if stat.nil?
|
16
|
+
@stat[rank] = stat = [0,0.0]
|
17
|
+
end
|
18
|
+
stat[0] += 1
|
19
|
+
stat[1] += elap
|
20
|
+
Log.debug "--- add_sample rank=#{rank} stat=#{stat.inspect} weight=#{stat[0]/stat[1]}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def rank_weight
|
25
|
+
@lock.synchronize do
|
26
|
+
sum = 0.0
|
27
|
+
count = 0
|
28
|
+
weight = @stat.map do |stat|
|
29
|
+
if stat
|
30
|
+
w = stat[0]/stat[1]
|
31
|
+
sum += w
|
32
|
+
count += 1
|
33
|
+
w
|
34
|
+
else
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
if count == 0
|
39
|
+
avg = 1.0
|
40
|
+
else
|
41
|
+
avg = sum/count
|
42
|
+
end
|
43
|
+
[weight, avg]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
RANK_STAT = RankStat.new
|
49
|
+
|
6
50
|
module TaskAlgorithm
|
7
51
|
|
8
52
|
def location
|
@@ -63,7 +107,7 @@ module Pwrake
|
|
63
107
|
timer = Timer.new("search_task")
|
64
108
|
h = application.pwrake_options['HALT_QUEUE_WHILE_SEARCH']
|
65
109
|
application.task_queue.synchronize(h) do
|
66
|
-
search_with_call_chain(
|
110
|
+
search_with_call_chain(nil, task_args, InvocationChain::EMPTY)
|
67
111
|
end
|
68
112
|
timer.finish
|
69
113
|
end
|
@@ -73,24 +117,28 @@ module Pwrake
|
|
73
117
|
if shell = Pwrake.current_shell
|
74
118
|
shell.current_task = self
|
75
119
|
end
|
76
|
-
|
77
120
|
@lock.synchronize do
|
78
121
|
return if @already_invoked
|
79
122
|
@already_invoked = true
|
80
123
|
end
|
81
124
|
pw_execute(@arg_data) if needed?
|
125
|
+
Log.debug("pw_execute: #{Time.now-time_start} sec, name=#{name}")
|
82
126
|
if kind_of?(Rake::FileTask)
|
83
|
-
|
127
|
+
t = Time.now
|
128
|
+
application.postprocess(self)
|
129
|
+
Log.debug("postprocess: #{Time.now-t} sec, name=#{name}")
|
84
130
|
if File.exist?(name)
|
131
|
+
t = Time.now
|
85
132
|
@file_stat = File::Stat.new(name)
|
133
|
+
Log.debug("File::Stat: #{Time.now-t} sec, name=#{name}")
|
86
134
|
end
|
87
135
|
end
|
88
136
|
log_task(time_start)
|
89
137
|
t = Time.now
|
90
138
|
application.finish_queue.enq(self)
|
91
139
|
shell.current_task = nil if shell
|
92
|
-
pw_enq_subsequents
|
93
|
-
Log.debug "--- pw_invoke (#{name})
|
140
|
+
pw_enq_subsequents
|
141
|
+
Log.debug "--- pw_invoke (#{name}) enq_subseq time=#{Time.now-t} sec"
|
94
142
|
end
|
95
143
|
|
96
144
|
def log_task(time_start)
|
@@ -104,10 +152,12 @@ module Pwrake
|
|
104
152
|
end
|
105
153
|
return if !application.task_logger
|
106
154
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
155
|
+
elap = time_end - time_start
|
156
|
+
if !@actions.empty? && kind_of?(Rake::FileTask)
|
157
|
+
RANK_STAT.add_sample(rank,elap)
|
158
|
+
end
|
159
|
+
|
160
|
+
row = [ @task_id, name, time_start, time_end, elap, @prerequisites.join('|') ]
|
111
161
|
|
112
162
|
if loc
|
113
163
|
row << loc.join('|')
|
@@ -190,9 +240,12 @@ module Pwrake
|
|
190
240
|
def pw_enq_subsequents
|
191
241
|
@lock.synchronize do
|
192
242
|
t = Time.now
|
193
|
-
|
194
|
-
|
195
|
-
|
243
|
+
h = application.pwrake_options['HALT_QUEUE_WHILE_SEARCH']
|
244
|
+
application.task_queue.synchronize(h) do
|
245
|
+
@subsequents.each do |t| # <<--- competition !!!
|
246
|
+
if t && t.check_prereq_finished(self.name)
|
247
|
+
application.task_queue.enq(t)
|
248
|
+
end
|
196
249
|
end
|
197
250
|
end
|
198
251
|
@already_finished = true # <<--- competition !!!
|
@@ -217,11 +270,12 @@ module Pwrake
|
|
217
270
|
|
218
271
|
return true if @already_finished # <<--- competition !!!
|
219
272
|
@subsequents ||= []
|
220
|
-
@subsequents << subseq
|
273
|
+
@subsequents << subseq if subseq # <<--- competition !!!
|
221
274
|
|
222
275
|
if ! @already_searched
|
223
276
|
@already_searched = true
|
224
277
|
@arg_data = task_args
|
278
|
+
@lock_rank = Monitor.new
|
225
279
|
if @prerequisites.empty?
|
226
280
|
@unfinished_prereq = {}
|
227
281
|
else
|
@@ -262,16 +316,56 @@ module Pwrake
|
|
262
316
|
end
|
263
317
|
private :format_search_flags
|
264
318
|
|
319
|
+
def rank
|
320
|
+
@lock_rank.synchronize do
|
321
|
+
if @rank.nil?
|
322
|
+
if @subsequents.nil? || @subsequents.empty?
|
323
|
+
@rank = 0
|
324
|
+
else
|
325
|
+
max_rank = 0
|
326
|
+
@subsequents.each do |subsq|
|
327
|
+
r = subsq.rank
|
328
|
+
if max_rank < r
|
329
|
+
max_rank = r
|
330
|
+
end
|
331
|
+
end
|
332
|
+
if @actions.empty? || !kind_of?(Rake::FileTask)
|
333
|
+
step = 0
|
334
|
+
else
|
335
|
+
step = 1
|
336
|
+
end
|
337
|
+
@rank = max_rank + step
|
338
|
+
end
|
339
|
+
Log.debug "--- Task[#{name}] rank=#{@rank.inspect}"
|
340
|
+
end
|
341
|
+
end
|
342
|
+
@rank
|
343
|
+
end
|
344
|
+
|
265
345
|
def file_size
|
266
346
|
@file_stat ? @file_stat.size : 0
|
267
347
|
end
|
268
348
|
|
269
|
-
def
|
349
|
+
def file_mtime
|
350
|
+
@file_stat ? @file_stat.mtime : Time.at(0)
|
351
|
+
end
|
352
|
+
|
353
|
+
def input_file_size
|
354
|
+
unless @input_file_size
|
355
|
+
@input_file_size = 0
|
356
|
+
@prerequisites.each do |preq|
|
357
|
+
@input_file_size += application[preq].file_size
|
358
|
+
end
|
359
|
+
end
|
360
|
+
@input_file_size
|
361
|
+
end
|
362
|
+
|
363
|
+
def has_input_file?
|
270
364
|
kind_of?(Rake::FileTask) && !@prerequisites.empty?
|
271
365
|
end
|
272
366
|
|
273
367
|
def suggest_location
|
274
|
-
if
|
368
|
+
if has_input_file? && @suggest_location.nil?
|
275
369
|
@suggest_location = []
|
276
370
|
loc_fsz = Hash.new(0)
|
277
371
|
@prerequisites.each do |preq|
|
@@ -297,6 +391,33 @@ module Pwrake
|
|
297
391
|
@suggest_location
|
298
392
|
end
|
299
393
|
|
394
|
+
def input_file_mtime
|
395
|
+
if has_input_file? && @input_file_mtime.nil?
|
396
|
+
hash = Hash.new
|
397
|
+
max_sz = 0
|
398
|
+
@prerequisites.each do |preq|
|
399
|
+
t = application[preq]
|
400
|
+
sz = t.file_size
|
401
|
+
if sz > 0
|
402
|
+
hash[t] = sz
|
403
|
+
if sz > max_sz
|
404
|
+
max_sz = sz
|
405
|
+
end
|
406
|
+
end
|
407
|
+
end
|
408
|
+
half_max_sz = max_sz / 2
|
409
|
+
hash.each do |t,sz|
|
410
|
+
if sz > half_max_sz
|
411
|
+
time = t.file_mtime
|
412
|
+
if @input_file_mtime.nil? || @input_file_mtime < time
|
413
|
+
@input_file_mtime = time
|
414
|
+
end
|
415
|
+
end
|
416
|
+
end
|
417
|
+
end
|
418
|
+
@input_file_mtime
|
419
|
+
end
|
420
|
+
|
300
421
|
def suggest_location2
|
301
422
|
if kind_of?(Rake::FileTask) && preq_name = @prerequisites[0]
|
302
423
|
application[preq_name].location
|