Example #1
0
        internal bool TryAdd(TNode node1, TNode node2)
        {
            Debug.Assert(_comparer.TreesEqual(node1, _root1));
            Debug.Assert(_comparer.TreesEqual(node2, _root2));

            if (_oneToTwo.ContainsKey(node1) || _twoToOne.ContainsKey(node2))
            {
                return(false);
            }

            _oneToTwo.Add(node1, node2);
            _twoToOne.Add(node2, node1);
            return(true);
        }
Example #2
0
        internal Match(TNode root1, TNode root2, TreeComparer <TNode> comparer, IEnumerable <KeyValuePair <TNode, TNode> > knownMatches)
        {
            _root1    = root1;
            _root2    = root2;
            _comparer = comparer;

            int labelCount = comparer.LabelCount;

            CategorizeNodesByLabels(comparer, root1, labelCount, out var nodes1, out var count1);
            CategorizeNodesByLabels(comparer, root2, labelCount, out var nodes2, out var count2);

            _oneToTwo = new Dictionary <TNode, TNode>();
            _twoToOne = new Dictionary <TNode, TNode>();

            // Root nodes always match. Add them before adding known matches to make sure we always have root mapping.
            TryAdd(root1, root2);

            if (knownMatches != null)
            {
                foreach (var knownMatch in knownMatches)
                {
                    if (comparer.GetLabel(knownMatch.Key) != comparer.GetLabel(knownMatch.Value))
                    {
                        throw new ArgumentException(string.Format(WorkspacesResources.Matching_nodes_0_and_1_must_have_the_same_label, knownMatch.Key, knownMatch.Value), nameof(knownMatches));
                    }

                    if (!comparer.TreesEqual(knownMatch.Key, root1))
                    {
                        throw new ArgumentException(string.Format(WorkspacesResources.Node_0_must_be_contained_in_the_old_tree, knownMatch.Key), nameof(knownMatches));
                    }

                    if (!comparer.TreesEqual(knownMatch.Value, root2))
                    {
                        throw new ArgumentException(string.Format(WorkspacesResources.Node_0_must_be_contained_in_the_new_tree, knownMatch.Value), nameof(knownMatches));
                    }

                    // skip pairs whose key or value is already mapped:
                    TryAdd(knownMatch.Key, knownMatch.Value);
                }
            }

            ComputeMatch(nodes1, nodes2);
        }