module Tree::Utils::TreeMergeHandler

Handles merging of two trees.

Public Instance Methods

merge(other_tree) click to toggle source

Merge two trees that share the same root node and returns a new tree.

The new tree contains the contents of the merge between other_tree and self. Duplicate nodes (coming from other_tree) will NOT be overwritten in self.

@author Darren Oakley (github.com/dazoakley)

@param [Tree::TreeNode] other_tree The other tree to merge with. @return [Tree::TreeNode] the resulting tree following the merge.

@raise [TypeError] This exception is raised if other_tree is not a

{Tree::TreeNode}.

@raise [ArgumentError] This exception is raised if other_tree does not

have the same root node as self.
# File lib/tree/utils/tree_merge_handler.rb, line 64
def merge(other_tree)
  check_merge_prerequisites(other_tree)
  merge_trees(root.dup, other_tree.root)
end
merge!(other_tree) click to toggle source

Merge in another tree (that shares the same root node) into this tree. Duplicate nodes (coming from other_tree) will NOT be overwritten in self.

@author Darren Oakley (github.com/dazoakley)

@param [Tree::TreeNode] other_tree The other tree to merge with.

@raise [TypeError] This exception is raised if other_tree is not a

{Tree::TreeNode}.

@raise [ArgumentError] This exception is raised if other_tree does not

have the same root node as self.
# File lib/tree/utils/tree_merge_handler.rb, line 82
def merge!(other_tree)
  check_merge_prerequisites(other_tree)
  merge_trees(root, other_tree.root)
end

Private Instance Methods

check_merge_prerequisites(other_tree) click to toggle source

Utility function to check that the conditions for a tree merge are met.

@author Darren Oakley (github.com/dazoakley)

@see merge @see merge!

# File lib/tree/utils/tree_merge_handler.rb, line 95
def check_merge_prerequisites(other_tree)
  raise TypeError, 'You can only merge in another instance of Tree::TreeNode' \
    unless other_tree.is_a?(Tree::TreeNode)

  raise ArgumentError, 'Unable to merge trees as they do not share the same root' \
    unless root.name == other_tree.root.name
end
merge_trees(tree1, tree2) click to toggle source

Utility function to recursively merge two subtrees.

@author Darren Oakley (github.com/dazoakley)

@param [Tree::TreeNode] tree1 The target tree to merge into. @param [Tree::TreeNode] tree2 The donor tree (that will be merged

into target).

@raise [Tree::TreeNode] The merged tree.

# File lib/tree/utils/tree_merge_handler.rb, line 111
def merge_trees(tree1, tree2)
  names1 = tree1.children? ? tree1.children.map(&:name) : []
  names2 = tree2.children? ? tree2.children.map(&:name) : []

  names_to_merge = names2 - names1
  names_to_merge.each do |name|
    tree1 << tree2[name].detached_subtree_copy
  end

  tree1.children.each do |child|
    merge_trees(child, tree2[child.name]) unless tree2[child.name].nil?
  end

  tree1
end