class RubyProf::CallInfo
Attributes
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)
Public Class Methods
# File lib/ruby-prof/call_info.rb, line 59 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 41 def call_sequence @call_sequence ||= begin stack.map {|method| method.full_name}.join('->') end end
# File lib/ruby-prof/call_info.rb, line 22 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 51 def descendent_of(other) p = self.parent while p && p != other && p.depth > other.depth p = p.parent end p == other end
# File lib/ruby-prof/call_info.rb, line 13 def detect_recursion(visited_methods = Hash.new(0)) @recursive = (visited_methods[target] += 1) > 1 children.each do |child| child.detect_recursion(visited_methods) end visited_methods.delete(target) if (visited_methods[target] -= 1) == 0 return @recursive 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 79 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 99 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 72 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 106 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 47 def root? self.parent.nil? end
# File lib/ruby-prof/call_info.rb, line 28 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 68 def to_s "#{target.full_name} (c: #{called}, tt: #{total_time}, st: #{self_time}, ct: #{children_time})" end