@@ -530,6 +530,11 @@ class sharing_mapt
530
530
531
531
void gather_all (const innert &n, delta_viewt &delta_view) const ;
532
532
533
+ bool is_singular (const leaf_listt &ll) const
534
+ {
535
+ return !ll.empty () && std::next (ll.begin ()) == ll.end ();
536
+ }
537
+
533
538
std::size_t count_unmarked_nodes (
534
539
bool leafs_only,
535
540
std::set<const void *> &marked,
@@ -787,7 +792,7 @@ ::get_delta_view(
787
792
return ;
788
793
}
789
794
790
- typedef std::tuple< unsigned , const baset *, const baset *> stack_itemt;
795
+ typedef std::pair< const innert *, const innert *> stack_itemt;
791
796
std::stack<stack_itemt> stack;
792
797
793
798
// We do a DFS "in lockstep" simultaneously on both maps. For
@@ -797,71 +802,106 @@ ::get_delta_view(
797
802
// The stack contains the children of already visited nodes that we
798
803
// still have to visit during the traversal.
799
804
800
- stack.push (stack_itemt (0 , &map, &other.map ));
805
+ if (map.shares_with (other.map ))
806
+ return ;
807
+
808
+ stack.push (stack_itemt (&map, &other.map ));
801
809
802
810
do
803
811
{
804
812
const stack_itemt &si = stack.top ();
805
813
806
- const unsigned depth = std::get<0 >(si);
807
- const baset *bp1 = std::get<1 >(si);
808
- const baset *bp2 = std::get<2 >(si);
814
+ const innert *ip1 = si.first ;
815
+ const innert *ip2 = si.second ;
809
816
810
817
stack.pop ();
811
818
812
- if (depth < steps) // internal
819
+ SM_ASSERT (!ip1->empty ());
820
+ SM_ASSERT (!ip2->empty ());
821
+
822
+ if (ip1->is_internal () && ip2->is_container ())
813
823
{
814
- const innert *ip1 = static_cast <const innert *>(bp1);
815
- const innert *ip2 = static_cast <const innert *>(bp2);
824
+ // The container *ip2 contains one element as only containers at the
825
+ // bottom of the tree can have more than one element. This happens when
826
+ // two different keys have the same hash code. It is known here that *ip2
827
+ // is not at the bottom of the tree, as *ip1 (the corresponding node in
828
+ // the other map) is an internal node, and internal nodes cannot be at the
829
+ // bottom of the map.
830
+ SM_ASSERT (is_singular (ip2->get_container ()));
831
+
832
+ for (const auto &item : ip1->get_to_map ())
833
+ {
834
+ const innert &child = item.second ;
835
+ SM_ASSERT (!child.shares_with (*ip2));
836
+ stack.push (stack_itemt (&child, ip2));
837
+ }
816
838
817
- const to_mapt &m = ip1->get_to_map ();
839
+ continue ;
840
+ }
818
841
819
- for (const auto &item : m)
842
+ if (ip1->is_internal ())
843
+ {
844
+ SM_ASSERT (ip2->is_internal ());
845
+
846
+ for (const auto &item : ip1->get_to_map ())
820
847
{
821
- const innert *p ;
848
+ const innert &child = item. second ;
822
849
850
+ const innert *p;
823
851
p = ip2->find_child (item.first );
824
- if (p==nullptr )
852
+
853
+ if (p == nullptr )
825
854
{
826
855
if (!only_common)
827
856
{
828
- gather_all (item. second , delta_view);
857
+ gather_all (child , delta_view);
829
858
}
830
859
}
831
- else if (!item. second .shares_with (*p))
860
+ else if (!child .shares_with (*p))
832
861
{
833
- stack.push (stack_itemt (depth + 1 , &item. second , p));
862
+ stack.push (stack_itemt (&child , p));
834
863
}
835
864
}
865
+
866
+ continue ;
836
867
}
837
- else // container
838
- {
839
- SM_ASSERT (depth == steps);
840
868
841
- const innert *cp1 = static_cast <const innert *>(bp1);
842
- const innert *cp2 = static_cast <const innert *>(bp2);
869
+ SM_ASSERT (ip1->is_container ());
843
870
844
- const leaf_listt &ll1 = cp1->get_container ();
871
+ if (ip2->is_internal ())
872
+ {
873
+ SM_ASSERT (is_singular (ip1->get_container ()));
845
874
846
- for (const auto &l1 : ll1 )
875
+ for (const auto &item : ip2-> get_to_map () )
847
876
{
848
- const key_type &k1=l1.get_key ();
849
- const leaft *p;
877
+ const innert &child = item.second ;
878
+ SM_ASSERT (!ip1->shares_with (child));
879
+ stack.push (stack_itemt (ip1, &child));
880
+ }
850
881
851
- p = cp2->find_leaf (k1);
882
+ continue ;
883
+ }
852
884
853
- if (p != nullptr )
854
- {
855
- if (!l1.shares_with (*p))
856
- {
857
- delta_view.push_back ({true , k1, l1.get_value (), p->get_value ()});
858
- }
859
- }
860
- else if (!only_common)
885
+ SM_ASSERT (ip2->is_container ());
886
+
887
+ for (const auto &l1 : ip1->get_container ())
888
+ {
889
+ const key_type &k1 = l1.get_key ();
890
+ const leaft *p;
891
+
892
+ p = ip2->find_leaf (k1);
893
+
894
+ if (p != nullptr )
895
+ {
896
+ if (!l1.shares_with (*p))
861
897
{
862
- delta_view.push_back ({false , l1. get_key () , l1.get_value (), dummy });
898
+ delta_view.push_back ({true , k1 , l1.get_value (), p-> get_value () });
863
899
}
864
900
}
901
+ else if (!only_common)
902
+ {
903
+ delta_view.push_back ({false , l1.get_key (), l1.get_value (), dummy});
904
+ }
865
905
}
866
906
}
867
907
while (!stack.empty ());
0 commit comments