@@ -54,6 +54,7 @@ Node size is not stored within the nodes. It will be calculated ad-hoc everytime
5454#include < queue>
5555#include < set>
5656#include < span>
57+ #include < stack>
5758#include < stdexcept>
5859#include < tuple>
5960#include < type_traits>
@@ -2205,9 +2206,9 @@ namespace OrthoTree
22052206 }
22062207
22072208 template <bool DO_UNIQUENESS_CHECK_TO_INDICIES>
2208- bool InsertWithoutRebalancingBase (MortonNodeIDCR parentNodeKey , MortonNodeIDCR entityNodeKey, TEntityID entityID, bool doInsertToLeaf) noexcept
2209+ bool InsertWithoutRebalancingBase (MortonNodeIDCR existingParentNodeKey , MortonNodeIDCR entityNodeKey, TEntityID entityID, bool doInsertToLeaf) noexcept
22092210 {
2210- if (entityNodeKey == parentNodeKey )
2211+ if (entityNodeKey == existingParentNodeKey )
22112212 {
22122213 detail::at (this ->m_nodes , entityNodeKey).AddEntity (entityID);
22132214 if constexpr (DO_UNIQUENESS_CHECK_TO_INDICIES)
@@ -2217,33 +2218,36 @@ namespace OrthoTree
22172218
22182219 if (doInsertToLeaf)
22192220 {
2220- auto & newNode = this ->m_nodes [entityNodeKey];
2221- newNode.AddEntity (entityID);
2222- #ifndef ORTHOTREE__DISABLED_NODECENTER
2223- newNode.SetCenter (this ->CalculateNodeCenter (entityNodeKey));
2224- #endif
2225- // Create all child between the new (entityNodeKey) and the smallest existing one (parentNodeKey)
2226- auto newParentNodeKey = entityNodeKey;
2227- do
2221+ auto nonExistingNodeStack = std::stack<MortonNodeID, std::vector<MortonNodeID>>{};
2222+ auto parentNodeKey = entityNodeKey;
2223+ for (; parentNodeKey != existingParentNodeKey; parentNodeKey = SI::GetParentKey (nonExistingNodeStack.top ()))
22282224 {
2229- auto childNodeKey = newParentNodeKey;
2230- newParentNodeKey = SI::GetParentKey (newParentNodeKey);
2231- assert (SI::IsValidKey (parentNodeKey));
2232- auto & newParentNode = this ->m_nodes [newParentNodeKey];
2233- newParentNode.AddChildInOrder (childNodeKey);
2234- #ifndef ORTHOTREE__DISABLED_NODECENTER
2235- newParentNode.SetCenter (this ->CalculateNodeCenter (newParentNodeKey));
2236- #endif
2237- } while (newParentNodeKey != parentNodeKey);
2225+ if (this ->m_nodes .contains (parentNodeKey))
2226+ break ;
2227+
2228+ nonExistingNodeStack.push (parentNodeKey);
2229+ }
2230+
2231+ auto parentNodeIt = this ->m_nodes .find (parentNodeKey);
2232+ for (; !nonExistingNodeStack.empty (); nonExistingNodeStack.pop ())
2233+ {
2234+ MortonNodeIDCR newParentNodeKey = nonExistingNodeStack.top ();
2235+
2236+ [[maybe_unused]] bool isSuccessful = false ;
2237+ parentNodeIt->second .AddChildInOrder (newParentNodeKey);
2238+ std::tie (parentNodeIt, isSuccessful) = this ->m_nodes .emplace (newParentNodeKey, this ->CreateChild (parentNodeIt->second , newParentNodeKey));
2239+ assert (isSuccessful);
2240+ }
2241+ parentNodeIt->second .AddEntity (entityID);
22382242 }
22392243 else
22402244 {
2241- auto & parentNode = detail::at (this ->m_nodes , parentNodeKey );
2245+ auto & parentNode = detail::at (this ->m_nodes , existingParentNodeKey );
22422246 if (parentNode.IsAnyChildExist ())
22432247 {
2244- auto const parentDepth = SI::GetDepthID (parentNodeKey );
2248+ auto const parentDepth = SI::GetDepthID (existingParentNodeKey );
22452249 auto const childID = SI::GetChildIDByDepth (parentDepth, SI::GetDepthID (entityNodeKey), entityNodeKey);
2246- auto const childGenerator = typename SI::ChildKeyGenerator (parentNodeKey );
2250+ auto const childGenerator = typename SI::ChildKeyGenerator (existingParentNodeKey );
22472251 auto const childNodeKey = childGenerator.GetChildNodeKey (childID);
22482252
22492253 parentNode.AddChildInOrder (childNodeKey);
0 commit comments