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:
3 files changed
+179
-26
No files matched your search
+8
-19
@@ -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
@@ -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
|
||||
|
||||
Reference in new issue
Block a user