@@ -567,7 +567,7 @@ class sharing_mapt
567
567
// / \param only_common: flag indicating if only items are added to the delta
568
568
// / view for which the keys are in both maps
569
569
void add_item_if_not_shared (
570
- const innert &container ,
570
+ const leaft &leaf ,
571
571
const innert &inner,
572
572
const std::size_t level,
573
573
delta_viewt &delta_view,
@@ -629,9 +629,13 @@ ::iterate(
629
629
stack.push (&item.second );
630
630
}
631
631
}
632
+ else if (ip->is_leaf ())
633
+ {
634
+ f (ip->get_key (), ip->get_value ());
635
+ }
632
636
else
633
637
{
634
- SM_ASSERT (ip->is_container ());
638
+ SM_ASSERT (ip->is_defined_container ());
635
639
636
640
const leaf_listt &ll = ip->get_container ();
637
641
SM_ASSERT (!ll.empty ());
@@ -662,13 +666,15 @@ ::count_unmarked_nodes(
662
666
do
663
667
{
664
668
const innert *ip = stack.top ();
669
+ SM_ASSERT (!ip->empty ());
665
670
stack.pop ();
666
671
667
- // internal node or container node
668
672
const unsigned use_count = ip->use_count ();
669
- const void *raw_ptr = ip->is_internal ()
670
- ? (const void *)&ip->read_internal ()
671
- : (const void *)&ip->read_container ();
673
+
674
+ const void *raw_ptr =
675
+ ip->is_internal () ? (const void *)&ip->read_internal ()
676
+ : ip->is_leaf () ? (const void *)&ip->read_leaf ()
677
+ : (const void *)&ip->read_container ();
672
678
673
679
if (use_count >= 2 )
674
680
{
@@ -683,14 +689,12 @@ ::count_unmarked_nodes(
683
689
}
684
690
}
685
691
686
- if (!leafs_only)
687
- {
688
- count++;
689
- }
690
-
691
692
if (ip->is_internal ())
692
693
{
693
- SM_ASSERT (!ip->empty ());
694
+ if (!leafs_only)
695
+ {
696
+ count++;
697
+ }
694
698
695
699
const to_mapt &m = ip->get_to_map ();
696
700
SM_ASSERT (!m.empty ());
@@ -700,32 +704,25 @@ ::count_unmarked_nodes(
700
704
stack.push (&item.second );
701
705
}
702
706
}
707
+ else if (ip->is_leaf ())
708
+ {
709
+ count++;
710
+ }
703
711
else
704
712
{
705
713
SM_ASSERT (ip->is_defined_container ());
706
714
715
+ if (!leafs_only)
716
+ {
717
+ count++;
718
+ }
719
+
707
720
const leaf_listt &ll = ip->get_container ();
708
721
SM_ASSERT (!ll.empty ());
709
722
710
723
for (const auto &l : ll)
711
724
{
712
- const unsigned leaf_use_count = l.use_count ();
713
- const void *leaf_raw_ptr = &l.read_leaf ();
714
-
715
- if (leaf_use_count >= 2 )
716
- {
717
- if (marked.find (leaf_raw_ptr) != marked.end ())
718
- {
719
- continue ;
720
- }
721
-
722
- if (mark)
723
- {
724
- marked.insert (leaf_raw_ptr);
725
- }
726
- }
727
-
728
- count++;
725
+ stack.push (&l);
729
726
}
730
727
}
731
728
} while (!stack.empty ());
@@ -812,15 +809,13 @@ ::gather_all(const innert &n, delta_viewt &delta_view) const
812
809
}
813
810
814
811
SHARING_MAPT (void )::add_item_if_not_shared(
815
- const innert &container ,
812
+ const leaft &leaf ,
816
813
const innert &inner,
817
814
const std::size_t level,
818
815
delta_viewt &delta_view,
819
816
const bool only_common) const
820
817
{
821
- const leaft &l1 = container.get_container ().front ();
822
-
823
- const auto &k = l1.get_key ();
818
+ const auto &k = leaf.get_key ();
824
819
std::size_t key = hash ()(k);
825
820
826
821
key >>= level * chunk;
@@ -839,7 +834,7 @@ SHARING_MAPT(void)::add_item_if_not_shared(
839
834
{
840
835
if (!only_common)
841
836
{
842
- delta_view.push_back ({k, l1 .get_value ()});
837
+ delta_view.push_back ({k, leaf .get_value ()});
843
838
}
844
839
845
840
return ;
@@ -850,22 +845,35 @@ SHARING_MAPT(void)::add_item_if_not_shared(
850
845
// potentially in both maps
851
846
if (ip->is_container ())
852
847
{
853
- if (container.shares_with (*ip))
854
- return ;
855
-
856
848
for (const auto &l2 : ip->get_container ())
857
849
{
858
- if (l1 .shares_with (l2))
850
+ if (leaf .shares_with (l2))
859
851
return ;
860
852
861
- if (l1 .get_key () == l2.get_key ())
853
+ if (leaf .get_key () == l2.get_key ())
862
854
{
863
- delta_view.push_back ({k, l1 .get_value (), l2.get_value ()});
855
+ delta_view.push_back ({k, leaf .get_value (), l2.get_value ()});
864
856
return ;
865
857
}
866
858
}
867
859
868
- delta_view.push_back ({k, l1.get_value ()});
860
+ delta_view.push_back ({k, leaf.get_value ()});
861
+
862
+ return ;
863
+ }
864
+
865
+ if (ip->is_leaf ())
866
+ {
867
+ if (ip->shares_with (leaf))
868
+ return ;
869
+
870
+ if (equalT ()(leaf.get_key (), ip->get_key ()))
871
+ {
872
+ delta_view.push_back ({k, leaf.get_value (), ip->get_value ()});
873
+ return ;
874
+ }
875
+
876
+ delta_view.push_back ({k, leaf.get_value ()});
869
877
870
878
return ;
871
879
}
@@ -920,6 +928,8 @@ ::get_delta_view(
920
928
const innert *ip1 = si.first ;
921
929
const innert *ip2 = si.second ;
922
930
931
+ SM_ASSERT (!ip1->shares_with (*ip2));
932
+
923
933
stack.pop ();
924
934
925
935
const std::size_t level = level_stack.top ();
@@ -928,95 +938,130 @@ ::get_delta_view(
928
938
SM_ASSERT (!ip1->empty ());
929
939
SM_ASSERT (!ip2->empty ());
930
940
931
- if (ip1->is_internal () && ip2-> is_container () )
941
+ if (ip1->is_internal ())
932
942
{
933
- // The container *ip2 contains one element as only containers at the
934
- // bottom of the tree can have more than one element. This happens when
935
- // two different keys have the same hash code. It is known here that *ip2
936
- // is not at the bottom of the tree, as *ip1 (the corresponding node in
937
- // the other map) is an internal node, and internal nodes cannot be at the
938
- // bottom of the map.
939
- SM_ASSERT (is_singular (ip2->get_container ()));
940
-
941
- for (const auto &item : ip1->get_to_map ())
943
+ SM_ASSERT (!ip2->is_container ());
944
+
945
+ if (ip2->is_internal ())
942
946
{
943
- const innert &child = item.second ;
944
- if (!child.shares_with (*ip2))
947
+ for (const auto &item : ip1->get_to_map ())
945
948
{
946
- stack.push (stack_itemt (&child, ip2));
949
+ const innert &child = item.second ;
950
+
951
+ const innert *p;
952
+ p = ip2->find_child (item.first );
947
953
948
- // The level is not needed when the node of the left map is an
949
- // internal node, and the node of the right map is a container node,
950
- // hence we just push a dummy element
951
- level_stack.push (dummy_level);
954
+ if (p == nullptr )
955
+ {
956
+ if (!only_common)
957
+ {
958
+ gather_all (child, delta_view);
959
+ }
960
+ }
961
+ else if (!child.shares_with (*p))
962
+ {
963
+ stack.push (stack_itemt (&child, p));
964
+ level_stack.push (level + 1 );
965
+ }
952
966
}
953
967
}
968
+ else
969
+ {
970
+ SM_ASSERT (ip2->is_leaf ());
954
971
955
- continue ;
956
- }
972
+ for (const auto &item : ip1->get_to_map ())
973
+ {
974
+ const innert &child = item.second ;
957
975
958
- if (ip1->is_internal ())
976
+ if (!child.shares_with (*ip2))
977
+ {
978
+ stack.push (stack_itemt (&child, ip2));
979
+
980
+ // The level is not needed when the node of the left map is an
981
+ // internal node, and the node of the right map is a leaf node,
982
+ // hence we just push a dummy element
983
+ level_stack.push (dummy_level);
984
+ }
985
+ }
986
+ }
987
+ }
988
+ else if (ip1->is_leaf ())
959
989
{
960
- SM_ASSERT (ip2->is_internal ());
990
+ SM_ASSERT (! ip2->is_container ());
961
991
962
- for ( const auto &item : ip1-> get_to_map ())
992
+ if (ip2-> is_internal ())
963
993
{
964
- const innert &child = item. second ;
994
+ SM_ASSERT (level != dummy_level) ;
965
995
966
- const innert *p;
967
- p = ip2->find_child (item.first );
996
+ add_item_if_not_shared (*ip1, *ip2, level, delta_view, only_common);
997
+ }
998
+ else
999
+ {
1000
+ SM_ASSERT (ip2->is_leaf ());
968
1001
969
- if (p == nullptr )
1002
+ if (equalT ()(ip1-> get_key (), ip2-> get_key ()) )
970
1003
{
971
- if (!only_common)
972
- {
973
- gather_all (child, delta_view);
974
- }
1004
+ delta_view.push_back (
1005
+ {ip1->get_key (), ip1->get_value (), ip2->get_value ()});
975
1006
}
976
- else if (!child. shares_with (*p) )
1007
+ else if (!only_common )
977
1008
{
978
- stack.push (stack_itemt (&child, p));
979
- level_stack.push (level + 1 );
1009
+ delta_view.push_back ({ip1->get_key (), ip1->get_value ()});
980
1010
}
981
1011
}
982
-
983
- continue ;
984
1012
}
985
-
986
- SM_ASSERT (ip1->is_container ());
987
-
988
- if (ip2->is_internal ())
1013
+ else
989
1014
{
990
- SM_ASSERT (is_singular ( ip1->get_container () ));
991
- SM_ASSERT (level != dummy_level );
1015
+ SM_ASSERT (ip1->is_container ( ));
1016
+ SM_ASSERT (!ip2-> is_internal () );
992
1017
993
- add_item_if_not_shared (*ip1, *ip2, level, delta_view, only_common);
1018
+ if (ip2->is_leaf ())
1019
+ {
1020
+ for (const auto &l1 : ip1->get_container ())
1021
+ {
1022
+ if (l1.shares_with (*ip2))
1023
+ {
1024
+ continue ;
1025
+ }
994
1026
995
- continue ;
996
- }
1027
+ const key_type &k1 = l1.get_key ();
997
1028
998
- SM_ASSERT (ip2->is_container ());
1029
+ if (equalT ()(k1, ip2->get_key ()))
1030
+ {
1031
+ delta_view.push_back ({k1, l1.get_value (), ip2->get_value ()});
1032
+ }
1033
+ else if (!only_common)
1034
+ {
1035
+ delta_view.push_back ({k1, l1.get_value ()});
1036
+ }
1037
+ }
1038
+ }
1039
+ else
1040
+ {
1041
+ SM_ASSERT (ip2->is_container ());
999
1042
1000
- for (const auto &l1 : ip1->get_container ())
1001
- {
1002
- const key_type &k1 = l1.get_key ();
1003
- const leaft *p;
1043
+ for (const auto &l1 : ip1->get_container ())
1044
+ {
1045
+ const key_type &k1 = l1.get_key ();
1046
+ const leaft *p;
1004
1047
1005
- p = ip2->find_leaf (k1);
1048
+ p = ip2->find_leaf (k1);
1006
1049
1007
- if (p != nullptr )
1008
- {
1009
- if (!l1.shares_with (*p))
1010
- {
1011
- SM_ASSERT (other.has_key (k1));
1012
- delta_view.push_back ({k1, l1.get_value (), p->get_value ()});
1050
+ if (p != nullptr )
1051
+ {
1052
+ if (!l1.shares_with (*p))
1053
+ {
1054
+ SM_ASSERT (other.has_key (k1));
1055
+ delta_view.push_back ({k1, l1.get_value (), p->get_value ()});
1056
+ }
1057
+ }
1058
+ else if (!only_common)
1059
+ {
1060
+ SM_ASSERT (!other.has_key (k1));
1061
+ delta_view.push_back ({k1, l1.get_value ()});
1062
+ }
1013
1063
}
1014
1064
}
1015
- else if (!only_common)
1016
- {
1017
- SM_ASSERT (!other.has_key (k1));
1018
- delta_view.push_back ({k1, l1.get_value ()});
1019
- }
1020
1065
}
1021
1066
}
1022
1067
while (!stack.empty ());
0 commit comments