Class: TestProf::MemoryProf::Tracker::LinkedList

Inherits:
Object
  • Object
show all
Defined in:
lib/test_prof/memory_prof/tracker/linked_list.rb

Overview

LinkedList is a linked list that track memory usage for individual examples/groups. A list node (‘LinkedListNode`) represents an example/group and its memory usage info:

  • memory_at_start - the amount of memory at the start of an example/group

  • memory_at_finish - the amount of memory at the end of an example/group

  • nested_memory - the amount of memory allocated by examples/groups defined inside a group

  • previous - a link to the previous node

Each node has a link to its previous node, and the head node points to the current example/group. If we picture a linked list as a tree with root being the top level group and leaves being current examples/groups, then the head node will always point to a leaf in that tree.

For example, if we have the following spec:

describe Question do
  decribe "#publish" do
    context "when not published" do
      it "makes the question visible" do
        ...
      end
    end
  end
end

At the moment when rspec is executing the example, the list has the following structure (^ denotes the head node):

^"makes the question visible" ->  "when not published" -> "#publish" -> Question

LinkedList supports two method for working with it:

* add_node – adds a node to the beginig of the list. At this point an example or group
  has started and we track how much memory has already been used.
* remove_node – removes and returns the head node from the list. It means that the node
  example/group has finished and it is time to calculate its memory usage.

When we remove a node we add its total_memory to the previous node.nested_memory, thus gradually tracking the amount of memory used by nested examples inside a group.

In the example above, after we remove the node “makes the question visible”, we add its total memory usage to nested_memory of the “when not published” node. If the “when not published” group contains other examples or sub-groups, their total_memory will also be added to “when not published” nested_memory. So when the group finishes we will have the total amount of memory used by its nested examples/groups, and thus we will be able to calculate the memory used by hooks and other code inside a group by subtracting nested_memory from total_memory.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(memory_at_start) ⇒ LinkedList

Returns a new instance of LinkedList.



54
55
56
# File 'lib/test_prof/memory_prof/tracker/linked_list.rb', line 54

def initialize(memory_at_start)
  add_node(:total, memory_at_start)
end

Instance Attribute Details

#headObject (readonly)

Returns the value of attribute head.



52
53
54
# File 'lib/test_prof/memory_prof/tracker/linked_list.rb', line 52

def head
  @head
end

Instance Method Details

#add_node(item, memory_at_start) ⇒ Object



58
59
60
61
62
63
64
# File 'lib/test_prof/memory_prof/tracker/linked_list.rb', line 58

def add_node(item, memory_at_start)
  @head = LinkedListNode.new(
    item: item,
    previous: head,
    memory_at_start: memory_at_start
  )
end

#remove_node(item, memory_at_finish) ⇒ Object



66
67
68
69
70
71
72
73
74
# File 'lib/test_prof/memory_prof/tracker/linked_list.rb', line 66

def remove_node(item, memory_at_finish)
  return if head.item != item
  head.finish(memory_at_finish)

  current = head
  @head = head.previous

  current
end