Skip to content

Commit d69b9bb

Browse files
committed
Make get_delta_view() of sharing map independent of tree depth
1 parent 945587a commit d69b9bb

File tree

1 file changed

+68
-34
lines changed

1 file changed

+68
-34
lines changed

src/util/sharing_map.h

Lines changed: 68 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,100 @@ ::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+
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+
}
816832

817-
const to_mapt &m = ip1->get_to_map();
833+
continue;
834+
}
818835

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

844+
const innert *p;
823845
p = ip2->find_child(item.first);
824-
if(p==nullptr)
846+
847+
if(p == nullptr)
825848
{
826849
if(!only_common)
827850
{
828-
gather_all(item.second, delta_view);
851+
gather_all(child, delta_view);
829852
}
830853
}
831-
else if(!item.second.shares_with(*p))
854+
else if(!child.shares_with(*p))
832855
{
833-
stack.push(stack_itemt(depth + 1, &item.second, p));
856+
stack.push(stack_itemt(&child, p));
834857
}
835858
}
859+
860+
continue;
836861
}
837-
else // container
838-
{
839-
SM_ASSERT(depth == steps);
840862

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

844-
const leaf_listt &ll1 = cp1->get_container();
865+
if(ip2->is_internal())
866+
{
867+
SM_ASSERT(is_singular(ip1->get_container()));
845868

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

851-
p = cp2->find_leaf(k1);
876+
continue;
877+
}
852878

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))
861891
{
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()});
863893
}
864894
}
895+
else if(!only_common)
896+
{
897+
delta_view.push_back({false, l1.get_key(), l1.get_value(), dummy});
898+
}
865899
}
866900
}
867901
while(!stack.empty());

0 commit comments

Comments
 (0)