@@ -535,10 +535,22 @@ class sharing_mapt
535535 return lp;
536536 }
537537
538+ innert *migrate (
539+ const std::size_t i,
540+ const std::size_t key_suffix,
541+ const std::size_t bit_last,
542+ innert &inner);
543+
538544 void iterate(
539545 const innert &n,
540546 std::function<void (const key_type &k, const mapped_type &m)> f) const ;
541547
548+ void add_item_if_not_shared (
549+ const innert &container,
550+ const innert &inner,
551+ delta_viewt &delta_view,
552+ const bool only_common) const ;
553+
542554 void gather_all (const innert &n, delta_viewt &delta_view) const ;
543555
544556 bool is_singular (const leaf_listt &ll) const
@@ -592,8 +604,7 @@ ::iterate(
592604
593605 for (const auto &item : m)
594606 {
595- const innert *i = &item.second ;
596- stack.push (i);
607+ stack.push (&item.second );
597608 }
598609 }
599610 else
@@ -664,8 +675,7 @@ ::count_unmarked_nodes(
664675
665676 for (const auto &item : m)
666677 {
667- const innert *i = &item.second ;
668- stack.push (i);
678+ stack.push (&item.second );
669679 }
670680 }
671681 else
@@ -779,6 +789,73 @@ ::gather_all(const innert &n, delta_viewt &delta_view) const
779789 iterate(n, f);
780790}
781791
792+ SHARING_MAPT (void )::add_item_if_not_shared(
793+ const innert &container,
794+ const innert &inner,
795+ delta_viewt &delta_view,
796+ const bool only_common) const
797+ {
798+ SM_ASSERT (!container.empty ());
799+ SM_ASSERT (!inner.empty ());
800+
801+ std::stack<const innert *> stack;
802+ stack.push (&inner);
803+
804+ do
805+ {
806+ const innert *ip = stack.top ();
807+ stack.pop ();
808+
809+ SM_ASSERT (!ip->empty ());
810+
811+ if (ip->is_internal ())
812+ {
813+ const to_mapt &m = ip->get_to_map ();
814+ SM_ASSERT (!m.empty ());
815+
816+ for (const auto &item : m)
817+ {
818+ const innert *i = &item.second ;
819+ stack.push (i);
820+ }
821+ }
822+ else
823+ {
824+ SM_ASSERT (ip->is_container ());
825+
826+ if (ip->shares_with (container))
827+ return ;
828+
829+ const leaft &l1 = container.get_container ().front ();
830+
831+ const leaf_listt &ll = ip->get_container ();
832+ SM_ASSERT (!ll.empty ());
833+
834+ for (const auto &l : ll)
835+ {
836+ if (l1.shares_with (l))
837+ return ;
838+
839+ if (l1.get_key () == l.get_key ())
840+ {
841+ // element is in both maps and not shared
842+ delta_view.push_back (
843+ {true , l1.get_key (), l1.get_value (), l.get_value ()});
844+ return ;
845+ }
846+ }
847+ }
848+ }
849+ while (!stack.empty ());
850+
851+ // element is only in first map
852+ if (!only_common)
853+ {
854+ const leaft &l1 = container.get_container ().front ();
855+ delta_view.push_back ({false , l1.get_key (), l1.get_value (), dummy});
856+ }
857+ }
858+
782859SHARING_MAPT (void )
783860::get_delta_view(
784861 const sharing_mapt &other,
@@ -840,8 +917,10 @@ ::get_delta_view(
840917 for (const auto &item : ip1->get_to_map ())
841918 {
842919 const innert &child = item.second ;
843- SM_ASSERT (!child.shares_with (*ip2));
844- stack.push (stack_itemt (&child, ip2));
920+ if (!child.shares_with (*ip2))
921+ {
922+ stack.push (stack_itemt (&child, ip2));
923+ }
845924 }
846925
847926 continue ;
@@ -880,12 +959,7 @@ ::get_delta_view(
880959 {
881960 SM_ASSERT (is_singular (ip1->get_container ()));
882961
883- for (const auto &item : ip2->get_to_map ())
884- {
885- const innert &child = item.second ;
886- SM_ASSERT (!ip1->shares_with (child));
887- stack.push (stack_itemt (ip1, &child));
888- }
962+ add_item_if_not_shared (*ip1, *ip2, delta_view, only_common);
889963
890964 continue ;
891965 }
@@ -903,11 +977,13 @@ ::get_delta_view(
903977 {
904978 if (!l1.shares_with (*p))
905979 {
980+ SM_ASSERT (other.has_key (k1));
906981 delta_view.push_back ({k1, l1.get_value (), p->get_value ()});
907982 }
908983 }
909984 else if (!only_common)
910985 {
986+ SM_ASSERT (!other.has_key (k1));
911987 delta_view.push_back ({k1, l1.get_value ()});
912988 }
913989 }
@@ -917,21 +993,28 @@ ::get_delta_view(
917993
918994SHARING_MAPT2 (, innert *)::get_container_node(const key_type &k)
919995{
996+ SM_ASSERT (has_key (k));
997+
920998 std::size_t key = hash ()(k);
921999 innert *ip = ↦
1000+ SM_ASSERT (ip->is_internal ());
9221001
9231002 for (std::size_t i = 0 ; i < steps; i++)
9241003 {
9251004 std::size_t bit = key & mask;
9261005
9271006 ip = ip->add_child (bit);
1007+ SM_ASSERT (ip != nullptr );
1008+ SM_ASSERT (!ip->empty ());
1009+
1010+ if (ip->is_container ())
1011+ return ip;
9281012
9291013 key >>= chunk;
9301014 }
9311015
932- SM_ASSERT (ip->is_container ());
933-
934- return ip;
1016+ UNREACHABLE;
1017+ return nullptr ;
9351018}
9361019
9371020SHARING_MAPT2 (const , innert *)::get_container_node(const key_type &k) const
@@ -942,24 +1025,33 @@ SHARING_MAPT2(const, innert *)::get_container_node(const key_type &k) const
9421025 std::size_t key = hash ()(k);
9431026 const innert *ip = ↦
9441027
1028+ SM_ASSERT (ip->is_defined_internal ());
1029+
9451030 for (std::size_t i = 0 ; i < steps; i++)
9461031 {
9471032 std::size_t bit = key & mask;
9481033
9491034 ip = ip->find_child (bit);
1035+
9501036 if (ip == nullptr )
9511037 return nullptr ;
9521038
1039+ SM_ASSERT (!ip->empty ());
1040+
1041+ if (ip->is_container ())
1042+ return ip;
1043+
9531044 key >>= chunk;
9541045 }
9551046
956- SM_ASSERT (ip->is_defined_container ());
957-
958- return ip;
1047+ UNREACHABLE;
1048+ return nullptr ;
9591049}
9601050
9611051SHARING_MAPT (void )::erase(const key_type &k)
9621052{
1053+ SM_ASSERT (has_key (k));
1054+
9631055 innert *del = nullptr ;
9641056 std::size_t del_bit = 0 ;
9651057
@@ -980,6 +1072,9 @@ SHARING_MAPT(void)::erase(const key_type &k)
9801072
9811073 ip = ip->add_child (bit);
9821074
1075+ if (ip->is_defined_container ())
1076+ break ;
1077+
9831078 key >>= chunk;
9841079 }
9851080
@@ -1001,13 +1096,136 @@ SHARING_MAPT(void)::erase(const key_type &k)
10011096 num--;
10021097}
10031098
1099+ SHARING_MAPT2 (, innert *)::migrate(
1100+ const std::size_t step,
1101+ const std::size_t key_suffix,
1102+ const std::size_t bit_last,
1103+ innert &inner)
1104+ {
1105+ SM_ASSERT (step < steps - 1 );
1106+ SM_ASSERT (inner.is_defined_internal ());
1107+
1108+ const innert &child = *inner.find_child (bit_last);
1109+ SM_ASSERT (child.is_defined_container ());
1110+
1111+ const leaf_listt &ll = child.get_container ();
1112+
1113+ // Only containers at the bottom can contain more than two elements
1114+ SM_ASSERT (is_singular (ll));
1115+
1116+ const leaft &leaf = ll.front ();
1117+ std::size_t key_existing = hash ()(leaf.get_key ());
1118+
1119+ key_existing >>= chunk * step;
1120+
1121+ // Copy the container
1122+ innert container_copy (child);
1123+
1124+ // Delete existing container
1125+ inner.remove_child (bit_last);
1126+
1127+ // Add internal node
1128+ innert *ip = inner.add_child (bit_last);
1129+ SM_ASSERT (ip->empty ());
1130+
1131+ // Find place for both elements
1132+
1133+ std::size_t i = step + 1 ;
1134+ std::size_t key = key_suffix;
1135+
1136+ key_existing >>= chunk;
1137+ key >>= chunk;
1138+
1139+ SM_ASSERT (i < steps);
1140+
1141+ do
1142+ {
1143+ std::size_t bit_existing = key_existing & mask;
1144+ std::size_t bit = key & mask;
1145+
1146+ if (bit != bit_existing)
1147+ {
1148+ // Place found
1149+
1150+ innert *cp2 = ip->add_child (bit_existing);
1151+ cp2->swap (container_copy);
1152+
1153+ innert *cp1 = ip->add_child (bit);
1154+ return cp1;
1155+ }
1156+
1157+ SM_ASSERT (bit == bit_existing);
1158+ ip = ip->add_child (bit);
1159+
1160+ key >>= chunk;
1161+ key_existing >>= chunk;
1162+
1163+ i++;
1164+ } while (i < steps);
1165+
1166+ leaft leaf_copy (as_const (&container_copy)->get_container ().front ());
1167+ ip->get_container ().push_front (leaf_copy);
1168+
1169+ return ip;
1170+ }
1171+
10041172SHARING_MAPT4 (valueU, void )
10051173::insert(const key_type &k, valueU &&m)
10061174{
1007- innert *cp = get_container_node (k);
1008- SM_ASSERT (cp != nullptr );
1175+ SM_ASSERT (!has_key (k));
1176+
1177+ std::size_t key = hash ()(k);
1178+ innert *ip = ↦
1179+
1180+ // The root cannot be a container node
1181+ SM_ASSERT (ip->is_internal ());
1182+
1183+ for (std::size_t i = 0 ; i < steps; i++)
1184+ {
1185+ std::size_t bit = key & mask;
1186+
1187+ SM_ASSERT (ip != nullptr );
1188+ SM_ASSERT (ip->is_internal ());
1189+ SM_ASSERT (i == 0 || !ip->empty ());
1190+
1191+ innert *child = ip->add_child (bit);
1192+
1193+ // Place is unoccupied
1194+ if (child->empty ())
1195+ {
1196+ // Create container and insert leaf
1197+ child->place_leaf (k, std::forward<valueU>(m));
1198+
1199+ SM_ASSERT (child->is_defined_container ());
1200+
1201+ num++;
1202+
1203+ return ;
1204+ }
1205+
1206+ if (child->is_container () && i < steps - 1 )
1207+ {
1208+ // Migrate the elements downwards
1209+ innert *cp = migrate (i, key, bit, *ip);
1210+
1211+ cp->place_leaf (k, std::forward<valueU>(m));
1212+
1213+ num++;
1214+
1215+ return ;
1216+ }
1217+
1218+ SM_ASSERT (i == steps - 1 || child->is_defined_internal ());
1219+
1220+ ip = child;
1221+ key >>= chunk;
1222+ }
1223+
1224+ SM_ASSERT (ip->is_defined_container ());
1225+
1226+ // Add to the bottom container
1227+ ip->place_leaf (k, std::forward<valueU>(m));
10091228
1010- cp->place_leaf (k, std::forward<valueU>(m));
10111229 num++;
10121230}
10131231
0 commit comments