8 class FileAccesses(object):
13 def append(self
, start_time
, elapsed
, offset
, count
, optype
):
14 self
.data
.append((start_time
, elapsed
, offset
, count
, optype
))
15 if self
.max_offset
< offset
+ count
:
16 self
.max_offset
= offset
+ count
19 return iter(self
.data
)
21 class AllAccesses(object):
24 self
.total_io_time
= 0
25 self
.start_time
= None
28 def append(self
, filename
, start_time
, elapsed
, offset
, count
, optype
):
29 if self
.start_time
is None:
30 self
.start_time
= start_time
31 start_time
-= self
.start_time
33 fileaccesses
= self
.data
.get(filename
, None)
34 if fileaccesses
is None:
35 fileaccesses
= FileAccesses()
36 self
.data
[filename
] = fileaccesses
38 fileaccesses
.append(start_time
, elapsed
, offset
, count
, optype
)
39 self
.total_time
= max(self
.total_time
, start_time
+ elapsed
)
40 self
.total_io_time
+= elapsed
42 def files_count(self
):
45 def sum_max_offset(self
):
46 return sum(x
.max_offset
for x
in self
.data
.itervalues())
49 keys
= self
.data
.keys()
52 yield key
, self
.data
[key
]
57 class DrawPanel(wx
.Panel
):
58 """draw a line on a panel's wx.PaintDC surface/canvas"""
59 def __init__(self
, parent
, data
):
60 wx
.Panel
.__init
__(self
, parent
, -1)
61 # bind the panel to the paint event
62 wx
.EVT_PAINT(self
, self
.onPaint
)
66 def onPaint(self
, event
=None):
67 # this is the wx drawing surface/canvas
71 wid
, hgt
= self
.GetClientSizeTuple()
79 xscale
= float(wid
- left
- right
) / self
.data
.total_time
80 yscale
= float(hgt
- top
- bot
- titlehgt
* len(self
.data
)) / self
.data
.sum_max_offset()
83 print "Drawing: green=read<1ms, red=read>1ms, blue=write, lightblue=sync"
84 dc
.SetPen(wx
.Pen("grey", 1))
85 dc
.SetBrush(wx
.Brush("#eeeeee"))
86 dc
.DrawRectangle(0, 0, wid
, hgt
)
90 for num
, (filename
, data
) in enumerate(self
.data
):
91 base_y
= int(math
.floor(num
* titlehgt
+ (bot
+ yscale
* maxoffset_sum
)))
92 top_y
= int(math
.ceil(base_y
+ (yscale
* data
.max_offset
)))
94 dc
.SetPen(wx
.Pen("grey", 1))
95 dc
.SetBrush(wx
.Brush("white"))
96 dc
.DrawRectangle(left
- 1, hgt
- (top_y
+ 1), wid
+ 2 - right
- left
, top_y
- base_y
+ 2)
97 twid
, thgt
= dc
.GetTextExtent(filename
)
98 dc
.DrawText(filename
, 0, hgt
- (top_y
+ thgt
))
100 maxoffset_sum
+= data
.max_offset
102 for starttime
, elapsed
, offset
, count
, optype
in data
:
103 xpos
= left
+ xscale
* starttime
104 pointwid
= xscale
* elapsed
105 if pointwid
< 1: pointwid
= 1
108 dc
.SetPen(wx
.Pen("blue", 1))
110 y
= base_y
+ (yscale
* offset
)
111 dc
.DrawLine(xpos
, hgt
- y
, xpos
+ pointwid
, hgt
- y
)
115 dc
.SetPen(wx
.Pen("dark green", 1))
118 dc
.SetPen(wx
.Pen("red", 1))
120 y
= base_y
+ (yscale
* offset
)
121 dc
.DrawLine(xpos
, hgt
- y
, xpos
+ pointwid
, hgt
- y
)
124 dc
.SetPen(wx
.Pen("light blue", 1))
125 dc
.DrawLine(xpos
, hgt
- base_y
, xpos
, hgt
- top_y
)
127 print "Drawn: [green, red, blue] =", counts
129 print "blue/red =", float(counts
[0]) / counts
[1]
131 def show_data(app
, data
, title
):
132 frame
= wx
.Frame(None, -1, title
, size
=(1500, 1000))
133 dp
= DrawPanel(frame
, data
)
136 def read_data(filename
):
145 fdnum
, start
, elapsed
, line
= line
[1:].split(',', 3)
148 elapsed
= int(elapsed
)
152 fds
[fdnum
] = filename
155 filename
= fds
.get(fdnum
, str(fdnum
))
158 offset
, count
= map(int, line
.split(',', 1))
159 data
.append(filename
, start
, elapsed
, offset
, count
, optype
)
163 offset
, count
= map(int, line
.split(',', 1))
164 data
.append(filename
, start
, elapsed
, offset
, count
, optype
)
168 data
.append(filename
, start
, elapsed
, 0, 0, optype
)
175 if __name__
== '__main__':
177 # data file should be produced by strace -T
178 filename
= sys
.argv
[1]
179 data
= read_data(filename
)
180 print "Total IO time = %fs" % (float(data
.total_io_time
) / 1000000.0)
181 print "Total time = %fs" % (float(data
.total_time
) / 1000000.0)
182 show_data(app
, data
, "%d io calls, from %s" % (len(data
), filename
))