Skip to content

Commit 16dae89

Browse files
committed
Make get_delta_view() of sharing map independent of tree depth
1 parent 59995bb commit 16dae89

File tree

1 file changed

+74
-34
lines changed

1 file changed

+74
-34
lines changed

src/util/sharing_map.h

Lines changed: 74 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,11 @@ class sharing_mapt
530530

531531
void gather_all(const innert &n, delta_viewt &delta_view) const;
532532

533+
bool is_singular(const leaf_listt &ll) const
534+
{
535+
return !ll.empty() && std::next(ll.begin()) == ll.end();
536+
}
537+
533538
std::size_t count_unmarked_nodes(
534539
bool leafs_only,
535540
std::set<const void *> &marked,
@@ -787,7 +792,7 @@ ::get_delta_view(
787792
return;
788793
}
789794

790-
typedef std::tuple<unsigned, const baset *, const baset *> stack_itemt;
795+
typedef std::pair<const innert *, const innert *> stack_itemt;
791796
std::stack<stack_itemt> stack;
792797

793798
// We do a DFS "in lockstep" simultaneously on both maps. For
@@ -797,71 +802,106 @@ ::get_delta_view(
797802
// The stack contains the children of already visited nodes that we
798803
// still have to visit during the traversal.
799804

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));
801809

802810
do
803811
{
804812
const stack_itemt &si = stack.top();
805813

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

810817
stack.pop();
811818

812-
if(depth < steps) // internal
819+
SM_ASSERT(!ip1->empty());
820+
SM_ASSERT(!ip2->empty());
821+
822+
if(ip1->is_internal() && ip2->is_container())
813823
{
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+
}
816838

817-
const to_mapt &m = ip1->get_to_map();
839+
continue;
840+
}
818841

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())
820847
{
821-
const innert *p;
848+
const innert &child = item.second;
822849

850+
const innert *p;
823851
p = ip2->find_child(item.first);
824-
if(p==nullptr)
852+
853+
if(p == nullptr)
825854
{
826855
if(!only_common)
827856
{
828-
gather_all(item.second, delta_view);
857+
gather_all(child, delta_view);
829858
}
830859
}
831-
else if(!item.second.shares_with(*p))
860+
else if(!child.shares_with(*p))
832861
{
833-
stack.push(stack_itemt(depth + 1, &item.second, p));
862+
stack.push(stack_itemt(&child, p));
834863
}
835864
}
865+
866+
continue;
836867
}
837-
else // container
838-
{
839-
SM_ASSERT(depth == steps);
840868

841-
const innert *cp1 = static_cast<const innert *>(bp1);
842-
const innert *cp2 = static_cast<const innert *>(bp2);
869+
SM_ASSERT(ip1->is_container());
843870

844-
const leaf_listt &ll1 = cp1->get_container();
871+
if(ip2->is_internal())
872+
{
873+
SM_ASSERT(is_singular(ip1->get_container()));
845874

846-
for(const auto &l1 : ll1)
875+
for(const auto &item : ip2->get_to_map())
847876
{
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+
}
850881

851-
p = cp2->find_leaf(k1);
882+
continue;
883+
}
852884

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))
861897
{
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()});
863899
}
864900
}
901+
else if(!only_common)
902+
{
903+
delta_view.push_back({false, l1.get_key(), l1.get_value(), dummy});
904+
}
865905
}
866906
}
867907
while(!stack.empty());

0 commit comments

Comments
 (0)