Use static variables for Node#previous/#next

Instead of calculating the previous/next node on the fly this data is
now set automatically whenever a node is stored in a NodeSet with an
owner. While this introduces some overhead and complexity when adding or
removing nodes from a NodeSet, it greatly reduces the runtime overhead
of calling Node#previous or Node#next.
This commit is contained in:
Yorick Peterse committed 2016-09-04 21:07:35 +02:00
1 parent dd138981f6
commit 5a58b14137
3 files changed
+179 -26

No files matched your search

+8 -19
View File
@@ -10,6 +10,12 @@ module Oga
# @return [Oga::XML::NodeSet]
attr_reader :node_set
# @return [Oga::XML::Node]
attr_accessor :previous
# @return [Oga::XML::Node]
attr_accessor :next
# @param [Hash] options
#
# @option options [Oga::XML::NodeSet] :node_set The node set that this
@@ -27,6 +33,8 @@ module Oga
@node_set = set
@root_node = nil
@html_p = nil
@previous = nil
@next = nil
end
# Returns the child nodes of the current node.
@@ -55,25 +63,6 @@ module Oga
node_set ? node_set.owner : nil
end
# Returns the preceding node, or nil if there is none.
#
# @return [Oga::XML::Node]
def previous
index = node_set.index(self) - 1
index >= 0 ? node_set[index] : nil
end
# Returns the following node, or nil if there is none.
#
# @return [Oga::XML::Node]
def next
index = node_set.index(self) + 1
length = node_set.length
index < length ? node_set[index] : nil
end
# Returns the previous element node or nil if there is none.
#
# @return [Oga::XML::Element]
+28 -7
View File
@@ -42,10 +42,10 @@ module Oga
@owner = owner
@existing = {}
@nodes.each do |node|
@nodes.each_with_index do |node, index|
mark_existing(node)
take_ownership(node) if @owner
take_ownership(node, index) if @owner
end
end
@@ -98,7 +98,7 @@ module Oga
mark_existing(node)
take_ownership(node) if @owner
take_ownership(node, length - 1) if @owner
end
alias_method :<<, :push
@@ -113,7 +113,7 @@ module Oga
mark_existing(node)
take_ownership(node) if @owner
take_ownership(node, 0) if @owner
end
# Shifts a node from the start of the set.
@@ -157,7 +157,7 @@ module Oga
mark_existing(node)
take_ownership(node) if @owner
take_ownership(node, index) if @owner
end
# Returns the node for the given index.
@@ -224,6 +224,8 @@ module Oga
sets << node.node_set
node.node_set = nil
node.next = nil
node.previous = nil
end
end
@@ -291,15 +293,34 @@ module Oga
# set has an owner.
#
# @param [Oga::XML::Node] node
def take_ownership(node)
# @param [Fixnum] index
def take_ownership(node, index)
node.node_set = self
node.previous = index > 0 ? @nodes[index - 1] : nil
node.next = index + 1 < @nodes.length ? @nodes[index + 1] : nil
node.previous.next = node if node.previous
node.next.previous = node if node.next
end
# Removes ownership of the node if it belongs to the current set.
#
# @param [Oga::XML::Node] node
def remove_ownership(node)
node.node_set = nil if node.node_set == self
return unless node.node_set == self
if previous_node = node.previous
previous_node.next = node.next
end
if next_node = node.next
next_node.previous = node.previous
end
node.node_set = nil
node.previous = nil
node.next = nil
end
# @param [Oga::XML::Node|Oga::XML::Attribute] node