#!/usr/bin/ruby $filter = ARGV $parents = {} $events = {} $has = {} $data = {} $horiz = {} $maxtime = -1 $stdin.each_line do | line | case line when /^(\d+) parent (\d+)$/ child = $1.to_i parent = $2.to_i $parents[child] = parent when /^@(\d+) (\d+) (\S*) (.*)$/ time = $1.to_i rec = $2.to_i event = $3 data = $4 if event.size > 0 $events[rec] ||= {} $events[rec][time] = event $has[rec] ||= {} $has[rec][event] = true $horiz[event] ||= "" $horiz[event] = $horiz[event].ljust(time) $horiz[event][time] = event end if data.size > 0 $data[rec] ||= "" $data[rec] += " #{event}@#{time}:" if event.size > 0 $data[rec] += " #{data}" end $maxtime = [$maxtime, time+1].max else raise "Unexpected line: #{line}" end end $hier = {} $hier_direct = {} $events.each_key do | rec | subhier = {} $hier_direct[rec] = subhier if $parents.key?(rec) $hier_direct[$parents[rec]][rec] = subhier else $hier[rec] = subhier end end $order = [] def flatten(hier) hier.each do | rec, subhier | $order << rec flatten(subhier) end end flatten($hier) rwidth = $order.map { | x | x.to_s.size }.max $horiz.keys.sort.each do | occ | $stdout.write(" " * rwidth + " #{$horiz[occ].ljust($maxtime)}") count = $horiz[occ].delete(" ").size $stdout.write(" #{($maxtime.to_f / count.to_f).round(2).to_s.rjust(5)} cyc/evt\n") end $stdout.write("\n") mwidth = 0 $order.each do | rec | estr = "" filter_match = $filter.empty? $has[rec].each_key do | event | filter_match ||= $filter.include?(event) end next unless filter_match $events[rec].keys.sort.each do | time | estr = estr.ljust(time + 1, estr.size == 0 ? " " : "-") estr[time] = $events[rec][time] if $events[rec][time].size > 0 end estr += " " * 5 estr = estr.ljust(mwidth - 1) estr = estr.ljust(estr.size + 20 - estr.size % 20) mwidth = [mwidth, estr.size].max $stdout.write(rec.to_s.rjust(rwidth) + ": #{estr}#{$data[rec]}\n") end