Skip to content

Commit a4e5a9e

Browse files
committed
Adapt iteration over the sharing map
Adapt get_view() and get_delta_view() for the case where a leaf node is directly attached to an internal node.
1 parent 4e28b17 commit a4e5a9e

File tree

1 file changed

+147
-102
lines changed

1 file changed

+147
-102
lines changed

src/util/sharing_map.h

Lines changed: 147 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ class sharing_mapt
567567
/// \param only_common: flag indicating if only items are added to the delta
568568
/// view for which the keys are in both maps
569569
void add_item_if_not_shared(
570-
const innert &container,
570+
const leaft &leaf,
571571
const innert &inner,
572572
const std::size_t level,
573573
delta_viewt &delta_view,
@@ -629,9 +629,13 @@ ::iterate(
629629
stack.push(&item.second);
630630
}
631631
}
632+
else if(ip->is_leaf())
633+
{
634+
f(ip->get_key(), ip->get_value());
635+
}
632636
else
633637
{
634-
SM_ASSERT(ip->is_container());
638+
SM_ASSERT(ip->is_defined_container());
635639

636640
const leaf_listt &ll = ip->get_container();
637641
SM_ASSERT(!ll.empty());
@@ -662,13 +666,15 @@ ::count_unmarked_nodes(
662666
do
663667
{
664668
const innert *ip = stack.top();
669+
SM_ASSERT(!ip->empty());
665670
stack.pop();
666671

667-
// internal node or container node
668672
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();
672678

673679
if(use_count >= 2)
674680
{
@@ -683,14 +689,12 @@ ::count_unmarked_nodes(
683689
}
684690
}
685691

686-
if(!leafs_only)
687-
{
688-
count++;
689-
}
690-
691692
if(ip->is_internal())
692693
{
693-
SM_ASSERT(!ip->empty());
694+
if(!leafs_only)
695+
{
696+
count++;
697+
}
694698

695699
const to_mapt &m = ip->get_to_map();
696700
SM_ASSERT(!m.empty());
@@ -700,32 +704,25 @@ ::count_unmarked_nodes(
700704
stack.push(&item.second);
701705
}
702706
}
707+
else if(ip->is_leaf())
708+
{
709+
count++;
710+
}
703711
else
704712
{
705713
SM_ASSERT(ip->is_defined_container());
706714

715+
if(!leafs_only)
716+
{
717+
count++;
718+
}
719+
707720
const leaf_listt &ll = ip->get_container();
708721
SM_ASSERT(!ll.empty());
709722

710723
for(const auto &l : ll)
711724
{
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);
729726
}
730727
}
731728
} while(!stack.empty());
@@ -812,15 +809,13 @@ ::gather_all(const innert &n, delta_viewt &delta_view) const
812809
}
813810

814811
SHARING_MAPT(void)::add_item_if_not_shared(
815-
const innert &container,
812+
const leaft &leaf,
816813
const innert &inner,
817814
const std::size_t level,
818815
delta_viewt &delta_view,
819816
const bool only_common) const
820817
{
821-
const leaft &l1 = container.get_container().front();
822-
823-
const auto &k = l1.get_key();
818+
const auto &k = leaf.get_key();
824819
std::size_t key = hash()(k);
825820

826821
key >>= level * chunk;
@@ -839,7 +834,7 @@ SHARING_MAPT(void)::add_item_if_not_shared(
839834
{
840835
if(!only_common)
841836
{
842-
delta_view.push_back({k, l1.get_value()});
837+
delta_view.push_back({k, leaf.get_value()});
843838
}
844839

845840
return;
@@ -850,22 +845,35 @@ SHARING_MAPT(void)::add_item_if_not_shared(
850845
// potentially in both maps
851846
if(ip->is_container())
852847
{
853-
if(container.shares_with(*ip))
854-
return;
855-
856848
for(const auto &l2 : ip->get_container())
857849
{
858-
if(l1.shares_with(l2))
850+
if(leaf.shares_with(l2))
859851
return;
860852

861-
if(l1.get_key() == l2.get_key())
853+
if(leaf.get_key() == l2.get_key())
862854
{
863-
delta_view.push_back({k, l1.get_value(), l2.get_value()});
855+
delta_view.push_back({k, leaf.get_value(), l2.get_value()});
864856
return;
865857
}
866858
}
867859

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()});
869877

870878
return;
871879
}
@@ -920,6 +928,8 @@ ::get_delta_view(
920928
const innert *ip1 = si.first;
921929
const innert *ip2 = si.second;
922930

931+
SM_ASSERT(!ip1->shares_with(*ip2));
932+
923933
stack.pop();
924934

925935
const std::size_t level = level_stack.top();
@@ -928,95 +938,130 @@ ::get_delta_view(
928938
SM_ASSERT(!ip1->empty());
929939
SM_ASSERT(!ip2->empty());
930940

931-
if(ip1->is_internal() && ip2->is_container())
941+
if(ip1->is_internal())
932942
{
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())
942946
{
943-
const innert &child = item.second;
944-
if(!child.shares_with(*ip2))
947+
for(const auto &item : ip1->get_to_map())
945948
{
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);
947953

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+
}
952966
}
953967
}
968+
else
969+
{
970+
SM_ASSERT(ip2->is_leaf());
954971

955-
continue;
956-
}
972+
for(const auto &item : ip1->get_to_map())
973+
{
974+
const innert &child = item.second;
957975

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())
959989
{
960-
SM_ASSERT(ip2->is_internal());
990+
SM_ASSERT(!ip2->is_container());
961991

962-
for(const auto &item : ip1->get_to_map())
992+
if(ip2->is_internal())
963993
{
964-
const innert &child = item.second;
994+
SM_ASSERT(level != dummy_level);
965995

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());
9681001

969-
if(p == nullptr)
1002+
if(equalT()(ip1->get_key(), ip2->get_key()))
9701003
{
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()});
9751006
}
976-
else if(!child.shares_with(*p))
1007+
else if(!only_common)
9771008
{
978-
stack.push(stack_itemt(&child, p));
979-
level_stack.push(level + 1);
1009+
delta_view.push_back({ip1->get_key(), ip1->get_value()});
9801010
}
9811011
}
982-
983-
continue;
9841012
}
985-
986-
SM_ASSERT(ip1->is_container());
987-
988-
if(ip2->is_internal())
1013+
else
9891014
{
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());
9921017

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+
}
9941026

995-
continue;
996-
}
1027+
const key_type &k1 = l1.get_key();
9971028

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());
9991042

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;
10041047

1005-
p = ip2->find_leaf(k1);
1048+
p = ip2->find_leaf(k1);
10061049

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+
}
10131063
}
10141064
}
1015-
else if(!only_common)
1016-
{
1017-
SM_ASSERT(!other.has_key(k1));
1018-
delta_view.push_back({k1, l1.get_value()});
1019-
}
10201065
}
10211066
}
10221067
while(!stack.empty());

0 commit comments

Comments
 (0)