@@ -54,6 +54,7 @@ Node size is not stored within the nodes. It will be calculated ad-hoc everytime
54
54
#include < queue>
55
55
#include < set>
56
56
#include < span>
57
+ #include < stack>
57
58
#include < stdexcept>
58
59
#include < tuple>
59
60
#include < type_traits>
@@ -2205,9 +2206,9 @@ namespace OrthoTree
2205
2206
}
2206
2207
2207
2208
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
2209
2210
{
2210
- if (entityNodeKey == parentNodeKey )
2211
+ if (entityNodeKey == existingParentNodeKey )
2211
2212
{
2212
2213
detail::at (this ->m_nodes , entityNodeKey).AddEntity (entityID);
2213
2214
if constexpr (DO_UNIQUENESS_CHECK_TO_INDICIES)
@@ -2217,33 +2218,36 @@ namespace OrthoTree
2217
2218
2218
2219
if (doInsertToLeaf)
2219
2220
{
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 ()))
2228
2224
{
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);
2238
2242
}
2239
2243
else
2240
2244
{
2241
- auto & parentNode = detail::at (this ->m_nodes , parentNodeKey );
2245
+ auto & parentNode = detail::at (this ->m_nodes , existingParentNodeKey );
2242
2246
if (parentNode.IsAnyChildExist ())
2243
2247
{
2244
- auto const parentDepth = SI::GetDepthID (parentNodeKey );
2248
+ auto const parentDepth = SI::GetDepthID (existingParentNodeKey );
2245
2249
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 );
2247
2251
auto const childNodeKey = childGenerator.GetChildNodeKey (childID);
2248
2252
2249
2253
parentNode.AddChildInOrder (childNodeKey);
0 commit comments