@@ -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,100 @@ ::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
+ SM_ASSERT (is_singular (ip2->get_container ()));
825
+
826
+ for (const auto &item : ip1->get_to_map ())
827
+ {
828
+ const innert &child = item.second ;
829
+ SM_ASSERT (!child.shares_with (*ip2));
830
+ stack.push (stack_itemt (&child, ip2));
831
+ }
816
832
817
- const to_mapt &m = ip1->get_to_map ();
833
+ continue ;
834
+ }
818
835
819
- for (const auto &item : m)
836
+ if (ip1->is_internal ())
837
+ {
838
+ SM_ASSERT (ip2->is_internal ());
839
+
840
+ for (const auto &item : ip1->get_to_map ())
820
841
{
821
- const innert *p ;
842
+ const innert &child = item. second ;
822
843
844
+ const innert *p;
823
845
p = ip2->find_child (item.first );
824
- if (p==nullptr )
846
+
847
+ if (p == nullptr )
825
848
{
826
849
if (!only_common)
827
850
{
828
- gather_all (item. second , delta_view);
851
+ gather_all (child , delta_view);
829
852
}
830
853
}
831
- else if (!item. second .shares_with (*p))
854
+ else if (!child .shares_with (*p))
832
855
{
833
- stack.push (stack_itemt (depth + 1 , &item. second , p));
856
+ stack.push (stack_itemt (&child , p));
834
857
}
835
858
}
859
+
860
+ continue ;
836
861
}
837
- else // container
838
- {
839
- SM_ASSERT (depth == steps);
840
862
841
- const innert *cp1 = static_cast <const innert *>(bp1);
842
- const innert *cp2 = static_cast <const innert *>(bp2);
863
+ SM_ASSERT (ip1->is_container ());
843
864
844
- const leaf_listt &ll1 = cp1->get_container ();
865
+ if (ip2->is_internal ())
866
+ {
867
+ SM_ASSERT (is_singular (ip1->get_container ()));
845
868
846
- for (const auto &l1 : ll1 )
869
+ for (const auto &item : ip2-> get_to_map () )
847
870
{
848
- const key_type &k1=l1.get_key ();
849
- const leaft *p;
871
+ const innert &child = item.second ;
872
+ SM_ASSERT (!ip1->shares_with (child));
873
+ stack.push (stack_itemt (ip1, &child));
874
+ }
850
875
851
- p = cp2->find_leaf (k1);
876
+ continue ;
877
+ }
852
878
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)
879
+ SM_ASSERT (ip2->is_container ());
880
+
881
+ for (const auto &l1 : ip1->get_container ())
882
+ {
883
+ const key_type &k1 = l1.get_key ();
884
+ const leaft *p;
885
+
886
+ p = ip2->find_leaf (k1);
887
+
888
+ if (p != nullptr )
889
+ {
890
+ if (!l1.shares_with (*p))
861
891
{
862
- delta_view.push_back ({false , l1. get_key () , l1.get_value (), dummy });
892
+ delta_view.push_back ({true , k1 , l1.get_value (), p-> get_value () });
863
893
}
864
894
}
895
+ else if (!only_common)
896
+ {
897
+ delta_view.push_back ({false , l1.get_key (), l1.get_value (), dummy});
898
+ }
865
899
}
866
900
}
867
901
while (!stack.empty ());
0 commit comments