class RubyProf::CallInfo
Public Class Methods
# File lib/ruby-prof/call_info.rb, line 48 def self.roots_of(call_infos) roots = [] sorted = call_infos.sort_by(&:depth).reverse while call_info = sorted.shift roots << call_info unless sorted.any?{|p| call_info.descendent_of(p)} end roots end
Public Instance Methods
# File lib/ruby-prof/call_info.rb, line 30 def call_sequence @call_sequence ||= begin stack.map {|method| method.full_name}.join('->') end end
part of this class is defined in C code. it provides the following attributes pertaining to tree structure: depth: tree level (0 == root) parent: parent call info (can be nil) children: array of call info children (can be empty) target: method info (containing an array of call infos)
# File lib/ruby-prof/call_info.rb, line 11 def children_time children.inject(0) do |sum, call_info| sum += call_info.total_time end end
# File lib/ruby-prof/call_info.rb, line 40 def descendent_of(other) p = self.parent while p && p != other && p.depth > other.depth p = p.parent end p == other end
eliminate call info from the call tree. adds self and wait time to parent and attaches called methods to parent. merges call trees for methods called from both praent end self.
# File lib/ruby-prof/call_info.rb, line 68 def eliminate! # puts "eliminating #{self}" return unless parent parent.add_self_time(self) parent.add_wait_time(self) children.each do |kid| if call = parent.find_call(kid) call.merge_call_tree(kid) else parent.children << kid # $stderr.puts "setting parent of #{kid}\nto #{parent}" kid.parent = parent end end parent.children.delete(self) end
find a specific call in list of children. returns nil if not found. note: there can't be more than one child with a given target method. in other words: x.children.grep{|y|y.target==m}.size <= 1 for all method infos m and call infos x
# File lib/ruby-prof/call_info.rb, line 88 def find_call(other) matching = children.select { |kid| kid.target == other.target } raise "inconsistent call tree" unless matching.size <= 1 matching.first end
# File lib/ruby-prof/call_info.rb, line 61 def inspect super + "(#{target.full_name}, d: #{depth}, c: #{called}, tt: #{total_time}, st: #{self_time}, ct: #{children_time})" end
merge two call trees. adds self, wait, and total time of other to self and merges children of other into children of self.
# File lib/ruby-prof/call_info.rb, line 95 def merge_call_tree(other) # $stderr.puts "merging #{self}\nand #{other}" self.called += other.called add_self_time(other) add_wait_time(other) add_total_time(other) other.children.each do |other_kid| if kid = find_call(other_kid) # $stderr.puts "merging kids" kid.merge_call_tree(other_kid) else other_kid.parent = self children << other_kid end end other.children.clear other.target.call_infos.delete(other) end
# File lib/ruby-prof/call_info.rb, line 36 def root? self.parent.nil? end
# File lib/ruby-prof/call_info.rb, line 17 def stack @stack ||= begin methods = Array.new call_info = self while call_info methods << call_info.target call_info = call_info.parent end methods.reverse end end
# File lib/ruby-prof/call_info.rb, line 57 def to_s "#{target.full_name} (c: #{called}, tt: #{total_time}, st: #{self_time}, ct: #{children_time})" end