Class: Sheap::Heap

Inherits:
Object
  • Object
show all
Includes:
Collection
Defined in:
lib/sheap.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Collection

#arrays, #bignums, #callcaches, #callinfos, #class_named, #classes, #complexes, #constcaches, #crefs, #datas, #files, #floats, #hashes, #icasses, #imemos, #instances_of, #iseqs, #matches, #ments, #modules, #of_imemo_type, #of_type, #plain_objects, #rationals, #regexps, #strings, #structs, #symbols

Constructor Details

#initialize(filename) ⇒ Heap

Returns a new instance of Heap.



425
426
427
# File 'lib/sheap.rb', line 425

def initialize(filename)
  @filename = filename
end

Instance Attribute Details

#filenameObject (readonly)

Returns the value of attribute filename.



423
424
425
# File 'lib/sheap.rb', line 423

def filename
  @filename
end

Class Method Details

.wrap(heap) ⇒ Object



529
530
531
# File 'lib/sheap.rb', line 529

def self.wrap(heap)
  self === heap ? heap : new(heap)
end

Instance Method Details

#at(addr) ⇒ Object



521
522
523
# File 'lib/sheap.rb', line 521

def at(addr)
  objects_by_addr[addr]
end

#each_objectObject



429
430
431
432
433
434
435
436
437
# File 'lib/sheap.rb', line 429

def each_object
  return enum_for(__method__) unless block_given?

  open_file do |file|
    file.each_line do |json|
      yield HeapObject.new(self, json)
    end
  end
end

#filter(&block) ⇒ Object



453
454
455
# File 'lib/sheap.rb', line 453

def filter(&block)
  objects.filter(&block)
end

#find_path(start_addresses, end_addresses = nil) ⇒ Object

finds a path from ‘start_address` through the inverse_references hash and so the end_address will be the object that’s closer to the root



489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
# File 'lib/sheap.rb', line 489

def find_path(start_addresses, end_addresses = nil)
  if end_addresses.nil?
    end_addresses = start_addresses
    start_addresses = roots
  end
  start_addresses = Array(start_addresses)
  end_addresses = Array(end_addresses)

  q = start_addresses.map{|x| [x] }

  visited = Set.new
  while !q.empty?
    current_path = q.shift
    current_address = current_path.last

    if end_addresses.include?(current_address)
      return current_path.map{|addr| addr}
    end

    if !visited.include?(current_address)
      visited.add(current_address)

      current_references = current_address.references

      current_references.each do |obj|
        q.push([*current_path, obj])
      end
    end
  end
  nil
end

#inspectObject



525
526
527
# File 'lib/sheap.rb', line 525

def inspect
  "#<#{self.class} (#{objects.size} objects)>"
end

#inverse_referencesObject



468
469
470
471
472
473
474
475
476
477
478
479
480
481
# File 'lib/sheap.rb', line 468

def inverse_references
  @inverse_references ||=
    begin
      hash = {}
      objects.each do |obj|
        obj.referenced_addrs.uniq.each do |addr|
          next if addr == obj.address
          hash[addr] ||= []
          hash[addr] << obj
        end
      end
      hash.freeze
    end
end

#objectsObject



449
450
451
# File 'lib/sheap.rb', line 449

def objects
  @objects ||= HeapObjectCollection.new(each_object.to_a, self)
end

#objects_by_addrObject



457
458
459
460
461
462
463
464
465
466
# File 'lib/sheap.rb', line 457

def objects_by_addr
  @objects_by_addr ||=
    begin
      hash = {}
      objects.each do |obj|
        hash[obj.address] = obj
      end
      hash.freeze
    end
end

#open_file(&block) ⇒ Object



439
440
441
442
443
444
445
446
447
# File 'lib/sheap.rb', line 439

def open_file(&block)
  # FIXME: look for magic header
  if filename.end_with?(".gz")
    require "zlib"
    Zlib::GzipReader.open(filename, &block)
  else
    File.open(filename, &block)
  end
end

#rootsObject



483
484
485
# File 'lib/sheap.rb', line 483

def roots
  of_type("ROOT")
end