@@ -1347,30 +1347,6 @@ namespace OrthoTree
13471347 LocationID m_childFlag;
13481348 };
13491349
1350-
1351- class ChildCheckerVariableDepth
1352- {
1353- public:
1354- inline constexpr ChildCheckerVariableDepth (depth_t examinedLevel, depth_t maxDepthNo, DepthAndLocationID const & depthAndLocation) noexcept
1355- : m_examinedDepthID(maxDepthNo - examinedLevel)
1356- , m_childID(GetLocationIDOnExaminedLevel(depthAndLocation.LocID, depthAndLocation.DepthID - m_examinedDepthID) & m_mask)
1357- {}
1358-
1359- inline constexpr ChildID GetChildID () const noexcept { return CastMortonIDToChildID (m_childID); }
1360-
1361- inline constexpr bool Test (DepthAndLocationID const & depthAndLocation) const noexcept
1362- {
1363- assert (m_examinedDepthID <= depthAndLocation.DepthID );
1364- auto const locationIDOnExaminationLevel = GetLocationIDOnExaminedLevel (depthAndLocation.LocID , depthAndLocation.DepthID - m_examinedDepthID);
1365- return (locationIDOnExaminationLevel & m_mask) == m_childID;
1366- }
1367-
1368- private:
1369- static constexpr LocationID m_mask = CHILD_NO - 1 ;
1370- depth_t m_examinedDepthID;
1371- LocationID m_childID;
1372- };
1373-
13741350 class ChildKeyGenerator
13751351 {
13761352 public:
@@ -1384,18 +1360,10 @@ namespace OrthoTree
13841360 NodeID m_parentFlag;
13851361 };
13861362
1387- class GridConverter
1363+ static inline constexpr NodeID GetHashAtDepth ( auto && location, depth_t maxDepthNo) noexcept
13881364 {
1389- public:
1390- explicit GridConverter (depth_t examinedLevel)
1391- : m_shift(examinedLevel * DIMENSION_NO)
1392- {}
1393-
1394- LocationID GetLocationID (DimArray<GridID> const & gridID) const noexcept { return Encode (gridID) >> m_shift; }
1395-
1396- private:
1397- UnderlyingInt m_shift;
1398- };
1365+ return (NodeID{ 1 } << (location.DepthID * DIMENSION_NO)) | (location.LocID >> ((maxDepthNo - location.DepthID ) * DIMENSION_NO));
1366+ }
13991367
14001368 static inline constexpr NodeID GetHash (auto && location) noexcept
14011369 {
@@ -1738,9 +1706,24 @@ namespace OrthoTree
17381706 static inline constexpr DepthAndLocationID GetDepthAndLocationID (depth_t maxDepthNo, std::array<LocationID, 2 > const & locationIDRange) noexcept
17391707 {
17401708 auto dl = DepthAndLocationID{ maxDepthNo, locationIDRange[0 ] };
1709+ if (locationIDRange[0 ] != locationIDRange[1 ])
1710+ {
1711+ depth_t levelID = 0 ;
1712+ if constexpr (false )
1713+ {
1714+ auto const differentBitNo = std::bit_width (locationIDRange[0 ] ^ locationIDRange[1 ]);
1715+ levelID = (differentBitNo + DIMENSION_NO - 1 ) / DIMENSION_NO;
1716+ }
1717+ else
1718+ {
1719+ for (auto diffLocationFlag = locationIDRange[0 ] ^ locationIDRange[1 ]; diffLocationFlag != 0 ; diffLocationFlag >>= DIMENSION_NO)
1720+ ++levelID;
1721+ }
17411722
1742- for (auto diffLocationFlag = locationIDRange[0 ] ^ locationIDRange[1 ]; IsValidKey (diffLocationFlag); diffLocationFlag >>= DIMENSION_NO, --dl.DepthID )
1743- dl.LocID = GetParentGridID (dl.LocID );
1723+ dl.DepthID -= levelID;
1724+ dl.LocID >>= levelID * DIMENSION_NO;
1725+ dl.LocID <<= levelID * DIMENSION_NO;
1726+ }
17441727
17451728 return dl;
17461729 }
@@ -1757,23 +1740,13 @@ namespace OrthoTree
17571740
17581741 static inline constexpr NodeID GetNodeID (depth_t maxDepthNo, std::array<LocationID, 2 > const & locationIDRange) noexcept
17591742 {
1760- return GetHash (GetDepthAndLocationID (maxDepthNo, locationIDRange));
1743+ return GetHashAtDepth (GetDepthAndLocationID (maxDepthNo, locationIDRange), maxDepthNo );
17611744 }
17621745
17631746 static inline constexpr auto IsLess (DepthAndLocationID const & leftLocation, DepthAndLocationID const & rightLocation) noexcept
17641747 {
1765- if (leftLocation.DepthID == rightLocation.DepthID )
1766- return leftLocation.LocID < rightLocation.LocID ;
1767- else if (leftLocation.DepthID < rightLocation.DepthID )
1768- {
1769- auto const locationIDRight = GetLocationIDOnExaminedLevel (rightLocation.LocID , rightLocation.DepthID - leftLocation.DepthID );
1770- return leftLocation.LocID <= locationIDRight;
1771- }
1772- else
1773- {
1774- auto const locationIDLeft = GetLocationIDOnExaminedLevel (leftLocation.LocID , leftLocation.DepthID - rightLocation.DepthID );
1775- return locationIDLeft < rightLocation.LocID ;
1776- }
1748+ return (leftLocation.LocID < rightLocation.LocID ) ||
1749+ ((leftLocation.LocID == rightLocation.LocID ) && (leftLocation.DepthID < rightLocation.DepthID ));
17771750 }
17781751 };
17791752 } // namespace detail
@@ -2169,22 +2142,22 @@ namespace OrthoTree
21692142 auto parentEntities = std::vector<TEntityID>{}; // Box entities could be stuck in the parent node.
21702143 for (auto const entityID : GetNodeEntities (parentNode))
21712144 {
2172- auto const [depthID, locationID] = this ->GetDepthAndLocationID (detail::at (geometryCollection, entityID));
2173- if (depthID <= parentDepth)
2145+ auto depthAndLocation = this ->GetDepthAndLocationID (detail::at (geometryCollection, entityID));
2146+ if (depthAndLocation. DepthID <= parentDepth)
21742147 {
21752148 parentEntities.emplace_back (entityID);
21762149 continue ;
21772150 }
21782151
21792152 // i-th entity should be moved to a child node
21802153
2181- auto const childID = SI::GetChildIDByDepth (parentDepth, depthID, locationID );
2154+ auto const childID = SI::GetChildIDByDepth (parentDepth, m_maxDepthNo, depthAndLocation. LocID );
21822155 auto const childNodeKey = childGenerator.GetChildNodeKey (childID);
21832156 if (parentNode.HasChild (childNodeKey))
21842157 {
2185- auto const entitiyNodeKey_ = SI::GetHash (depthID, locationID );
2158+ auto const entitiyNodeKey_ = SI::GetHashAtDepth (depthAndLocation, m_maxDepthNo );
21862159 auto const [parentNodeKey_, parentDepthID_] = FindSmallestNodeKeyWithDepth (entitiyNodeKey_);
2187- InsertWithRebalancingBase<false >(parentNodeKey_, parentDepthID_, entitiyNodeKey_, depthID , entityID, geometryCollection);
2160+ InsertWithRebalancingBase<false >(parentNodeKey_, parentDepthID_, entitiyNodeKey_, depthAndLocation. DepthID , entityID, geometryCollection);
21882161 }
21892162 else
21902163 {
@@ -2565,7 +2538,7 @@ namespace OrthoTree
25652538 template <bool HANDLE_OUT_OF_TREE_GEOMETRY = false >
25662539 MortonNodeID GetNodeID (TBox const & box) const noexcept
25672540 {
2568- return SI::GetHash (this ->GetDepthAndLocationID <HANDLE_OUT_OF_TREE_GEOMETRY>(box));
2541+ return SI::GetHashAtDepth (this ->GetDepthAndLocationID <HANDLE_OUT_OF_TREE_GEOMETRY>(box), m_maxDepthNo );
25692542 }
25702543
25712544 // Find smallest node which contains the box
@@ -2801,7 +2774,7 @@ namespace OrthoTree
28012774 return foundNodes;
28022775 }
28032776
2804- auto const rangeKey = SI::GetHash (this ->GetDepthAndLocationID <!IS_BOX_TYPE, TBoxRange>(range));
2777+ auto const rangeKey = SI::GetHashAtDepth (this ->GetDepthAndLocationID <!IS_BOX_TYPE, TBoxRange>(range), m_maxDepthNo );
28052778 auto smallestNodeKey = this ->FindSmallestNodeKey (rangeKey);
28062779 if (!SI::IsValidKey (smallestNodeKey))
28072780 {
@@ -3552,12 +3525,12 @@ namespace OrthoTree
35523525 auto const keyGenerator = typename SI::ChildKeyGenerator (parentKey);
35533526 while (beginLocationIterator != endLocationIterator)
35543527 {
3555- auto const childChecker = typename SI::ChildCheckerVariableDepth (remainingDepthNo, this -> m_maxDepthNo , beginLocationIterator->DepthAndLocation );
3528+ auto const childChecker = typename SI::ChildCheckerFixedDepth (remainingDepthNo, beginLocationIterator->DepthAndLocation . LocID );
35563529 auto const actualEndLocationIterator = std::partition_point (beginLocationIterator, endLocationIterator, [&](auto const & location) {
3557- return childChecker.Test (location.DepthAndLocation );
3530+ return childChecker.Test (location.DepthAndLocation . LocID );
35583531 });
35593532
3560- auto const childKey = keyGenerator.GetChildNodeKey (childChecker.GetChildID ());
3533+ auto const childKey = keyGenerator.GetChildNodeKey (childChecker.GetChildID (remainingDepthNo ));
35613534
35623535 parentNode.AddChild (childKey);
35633536 auto & nodeChild = this ->CreateChild (parentNode, childKey);
@@ -3595,11 +3568,10 @@ namespace OrthoTree
35953568 Base::template ConstructGridIDListRecursively<DIMENSION_NO>(gridStepNo, gridBoundaries, temporaryGridID, gridIDs);
35963569
35973570 auto const boxNo = gridIDs.size ();
3598- auto const gridGenerator = typename SI::GridConverter (remainingDepthNo);
35993571
36003572 // First element into locationID
36013573 location.DepthAndLocation .DepthID = depthID;
3602- location.DepthAndLocation .LocID = gridGenerator. GetLocationID (gridIDs[0 ]);
3574+ location.DepthAndLocation .LocID = SI::Encode (gridIDs[0 ]);
36033575 auto const entityID = location.EntityID ;
36043576
36053577 auto const additionalBoxNo = boxNo - 1 ;
@@ -3612,7 +3584,7 @@ namespace OrthoTree
36123584 auto & location = additionalLocations.at (locationNo + iBox);
36133585 location.EntityID = entityID;
36143586 location.DepthAndLocation .DepthID = depthID;
3615- location.DepthAndLocation .LocID = gridGenerator. GetLocationID (gridIDs[iBox + 1 ]);
3587+ location.DepthAndLocation .LocID = SI::Encode (gridIDs[iBox + 1 ]);
36163588 }
36173589 }
36183590
@@ -3738,7 +3710,7 @@ namespace OrthoTree
37383710
37393711 for (auto const & location : locations)
37403712 {
3741- auto const entityNodeKey = SI::GetHash (location.DepthAndLocation );
3713+ auto const entityNodeKey = SI::GetHashAtDepth (location.DepthAndLocation , this -> GetDepthMax () );
37423714 auto const parentNodeKey = this ->FindSmallestNodeKey (entityNodeKey);
37433715
37443716 if (!this ->template InsertWithRebalancingBase <SPLIT_DEPTH_INCREASEMENT == 0 >(
@@ -3765,7 +3737,7 @@ namespace OrthoTree
37653737
37663738 for (auto const & location : locations)
37673739 {
3768- auto const entityNodeKey = SI::GetHash (location.DepthAndLocation );
3740+ auto const entityNodeKey = SI::GetHashAtDepth (location.DepthAndLocation , this -> GetDepthMax () );
37693741 if (!this ->template InsertWithoutRebalancingBase <SPLIT_DEPTH_INCREASEMENT == 0 >(smallestNodeKey, entityNodeKey, newEntityID, doInsertToLeaf))
37703742 return false ;
37713743 }
0 commit comments