Skip to content

Commit 5cae85a

Browse files
committed
Simplify Box::Create()
1 parent 93ef0a6 commit 5cae85a

File tree

1 file changed

+117
-88
lines changed

1 file changed

+117
-88
lines changed

octree.h

Lines changed: 117 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -2992,53 +2992,51 @@ namespace OrthoTree
29922992
TEntityID EntityID;
29932993
MortonLocationID LocationID;
29942994
};
2995-
auto pointLocations = std::vector<Location>(pointNo);
2995+
auto locations = std::vector<Location>(pointNo);
29962996
EXEC_POL_DEF(ept); // GCC 11.3
2997-
std::transform(EXEC_POL_ADD(ept) points.begin(), points.end(), pointLocations.begin(), [&](auto const& point) {
2997+
std::transform(EXEC_POL_ADD(ept) points.begin(), points.end(), locations.begin(), [&](auto const& point) {
29982998
return Location{ detail::getKeyPart(points, point), tree.GetLocationID(detail::getValuePart(point)) };
29992999
});
30003000

30013001
if constexpr (IS_PARALLEL_EXEC)
30023002
{
30033003
EXEC_POL_DEF(eps); // GCC 11.3
3004-
std::sort(EXEC_POL_ADD(eps) pointLocations.begin(), pointLocations.end(), [&](auto const& leftLocation, auto const& rightLocation) {
3005-
return leftLocation.LocationID < rightLocation.LocationID;
3006-
});
3004+
std::sort(EXEC_POL_ADD(eps) locations.begin(), locations.end(), [&](auto const& l, auto const& r) { return l.LocationID < r.LocationID; });
30073005
}
30083006

3009-
// Build the tree in depth-first search order
3007+
// Build the tree in depth-first order
30103008

3011-
struct NodeData
3009+
struct NodeStackData
30123010
{
30133011
std::pair<MortonNodeID, Node> NodeInstance;
3014-
typename std::vector<Location>::iterator LocationEndIterator;
3012+
typename std::vector<Location>::iterator EndLocationIt;
30153013
};
3016-
std::array<NodeData, SI::MAX_THEORETICAL_DEPTH> nodeStack;
3017-
nodeStack[0] = NodeData{ *tree.m_nodes.find(SI::GetRootKey()), pointLocations.end() };
3014+
std::array<NodeStackData, SI::MAX_THEORETICAL_DEPTH> nodeStack;
3015+
nodeStack[0] = NodeStackData{ *tree.m_nodes.find(SI::GetRootKey()), locations.end() };
30183016
tree.m_nodes.clear(); // Root will be inserted again via the nodeStack, unspecified behavior
30193017

3020-
auto locationBeginIterator = pointLocations.begin();
3018+
auto beginLocationIt = locations.begin();
30213019
for (int depthID = 0; depthID >= 0;)
30223020
{
3023-
auto& [node, locationEndIterator] = nodeStack[depthID];
3024-
std::size_t const elementNo = std::distance(locationBeginIterator, locationEndIterator);
3021+
auto& [node, endLocationIt] = nodeStack[depthID];
3022+
std::size_t const elementNo = std::distance(beginLocationIt, endLocationIt);
30253023
if (elementNo == 0)
30263024
{
30273025
tree.m_nodes.emplace(std::move(node));
30283026
--depthID;
30293027
continue;
30303028
}
30313029

3032-
if (((elementNo < tree.m_maxElementNo) && !node.second.IsAnyChildExist()) || depthID == maxDepthNo)
3030+
if ((elementNo < tree.m_maxElementNo && !node.second.IsAnyChildExist()) || depthID == maxDepthNo)
30333031
{
30343032
auto& entityIDs = node.second.GetEntities();
30353033
entityIDs.resize(elementNo);
30363034

30373035
LOOPIVDEP
30383036
for (std::size_t i = 0; i < elementNo; ++i)
30393037
{
3040-
entityIDs[i] = locationBeginIterator->EntityID;
3041-
++locationBeginIterator;
3038+
entityIDs[i] = beginLocationIt->EntityID;
3039+
++beginLocationIt;
30423040
}
30433041

30443042
tree.m_nodes.emplace(std::move(node));
@@ -3049,19 +3047,18 @@ namespace OrthoTree
30493047
++depthID;
30503048
auto const examinedLevel = tree.GetDepthMax() - depthID;
30513049
auto const keyGenerator = typename SI::ChildKeyGenerator(node.first);
3052-
auto const childChecker = typename SI::ChildCheckerFixedDepth(examinedLevel, locationBeginIterator->LocationID);
3050+
auto const childChecker = typename SI::ChildCheckerFixedDepth(examinedLevel, beginLocationIt->LocationID);
30533051
auto childKey = keyGenerator.GetChildNodeKey(childChecker.GetChildID(examinedLevel));
30543052
if constexpr (IS_PARALLEL_EXEC)
30553053
{
3056-
nodeStack[depthID].LocationEndIterator = std::partition_point(locationBeginIterator, locationEndIterator, [&](auto const& location) {
3057-
return childChecker.Test(location.LocationID);
3058-
});
3054+
nodeStack[depthID].EndLocationIt =
3055+
std::partition_point(beginLocationIt, endLocationIt, [&](auto const& location) { return childChecker.Test(location.LocationID); });
30593056
node.second.AddChild(childKey);
30603057
}
30613058
else
30623059
{
3063-
nodeStack[depthID].LocationEndIterator =
3064-
std::partition(locationBeginIterator, locationEndIterator, [&](auto const& location) { return childChecker.Test(location.LocationID); });
3060+
nodeStack[depthID].EndLocationIt =
3061+
std::partition(beginLocationIt, endLocationIt, [&](auto const& location) { return childChecker.Test(location.LocationID); });
30653062
node.second.AddChildInOrder(childKey);
30663063
}
30673064

@@ -3509,68 +3506,6 @@ namespace OrthoTree
35093506
using LocationContainer = std::vector<Location>;
35103507
using LocationIterator = typename LocationContainer::iterator;
35113508

3512-
void CreateChildNodes(
3513-
Node& parentNode,
3514-
MortonNodeIDCR parentKey,
3515-
LocationIterator& beginLocationIterator,
3516-
LocationIterator const& endLocationIterator,
3517-
depth_t remainingDepthNo) noexcept
3518-
{
3519-
std::size_t const elementNo = std::distance(beginLocationIterator, endLocationIterator);
3520-
if (elementNo < this->m_maxElementNo || remainingDepthNo == 0)
3521-
{
3522-
auto& entityIDs = parentNode.GetEntities();
3523-
entityIDs.resize(elementNo);
3524-
3525-
LOOPIVDEP
3526-
for (std::size_t i = 0; i < elementNo; ++i)
3527-
{
3528-
entityIDs[i] = beginLocationIterator->EntityID;
3529-
++beginLocationIterator;
3530-
}
3531-
return;
3532-
}
3533-
3534-
depth_t currentDepthID = this->m_maxDepthNo - remainingDepthNo;
3535-
if (beginLocationIterator->DepthAndLocation.DepthID == currentDepthID)
3536-
{
3537-
auto stuckedEndLocationIterator = std::partition_point(beginLocationIterator, endLocationIterator, [&](auto const& location) {
3538-
return location.DepthAndLocation.DepthID == beginLocationIterator->DepthAndLocation.DepthID;
3539-
});
3540-
3541-
std::size_t const stuckedElementNo = std::distance(beginLocationIterator, stuckedEndLocationIterator);
3542-
3543-
auto& entityIDs = parentNode.GetEntities();
3544-
entityIDs.resize(stuckedElementNo);
3545-
3546-
LOOPIVDEP
3547-
for (std::size_t i = 0; i < stuckedElementNo; ++i)
3548-
{
3549-
entityIDs[i] = beginLocationIterator->EntityID;
3550-
++beginLocationIterator;
3551-
}
3552-
}
3553-
3554-
++currentDepthID;
3555-
--remainingDepthNo;
3556-
3557-
auto const keyGenerator = typename SI::ChildKeyGenerator(parentKey);
3558-
while (beginLocationIterator != endLocationIterator)
3559-
{
3560-
auto const childChecker = typename SI::ChildCheckerFixedDepth(remainingDepthNo, beginLocationIterator->DepthAndLocation.LocID);
3561-
auto const actualEndLocationIterator = std::partition_point(beginLocationIterator, endLocationIterator, [&](auto const& location) {
3562-
return childChecker.Test(location.DepthAndLocation.LocID);
3563-
});
3564-
3565-
auto const childKey = keyGenerator.GetChildNodeKey(childChecker.GetChildID(remainingDepthNo));
3566-
3567-
parentNode.AddChild(childKey);
3568-
auto [childNode, _] = this->m_nodes.emplace(childKey, this->CreateChild(parentNode, childKey));
3569-
this->CreateChildNodes(childNode->second, childKey, beginLocationIterator, actualEndLocationIterator, remainingDepthNo);
3570-
}
3571-
}
3572-
3573-
35743509
void SplitEntityLocation(std::array<DimArray<GridID>, 2> const& boxMinMaxGridID, Location& location, LocationContainer& additionalLocations) const noexcept
35753510
{
35763511
depth_t depthID = location.DepthAndLocation.DepthID + SPLIT_DEPTH_INCREASEMENT;
@@ -3716,11 +3651,105 @@ namespace OrthoTree
37163651
});
37173652
}
37183653

3719-
EXEC_POL_DEF(eps); // GCC 11.3
3720-
std::sort(EXEC_POL_ADD(eps) locations.begin(), locations.end());
3654+
if constexpr (IS_PARALLEL_EXEC)
3655+
{
3656+
EXEC_POL_DEF(eps); // GCC 11.3
3657+
std::sort(EXEC_POL_ADD(eps) locations.begin(), locations.end());
3658+
}
3659+
3660+
// Build the tree in depth-first order
3661+
3662+
struct NodeStackData
3663+
{
3664+
std::pair<MortonNodeID, Node> NodeInstance;
3665+
typename std::vector<Location>::iterator EndLocationIt;
3666+
};
3667+
std::array<NodeStackData, SI::MAX_THEORETICAL_DEPTH> nodeStack;
3668+
nodeStack[0] = NodeStackData{ *tree.m_nodes.find(SI::GetRootKey()), locations.end() };
3669+
tree.m_nodes.clear(); // Root will be inserted again via the nodeStack, unspecified behavior
3670+
3671+
auto beginLocationIt = locations.begin();
3672+
for (int depthID = 0; depthID >= 0;)
3673+
{
3674+
auto& [node, endLocationIt] = nodeStack[depthID];
3675+
3676+
std::size_t elementNo = std::distance(beginLocationIt, endLocationIt);
3677+
3678+
auto const hasNoChild = !node.second.IsAnyChildExist();
3679+
if ((elementNo > 0 && elementNo < tree.m_maxElementNo && hasNoChild) || depthID == maxDepthNo)
3680+
{
3681+
auto& entityIDs = node.second.GetEntities();
3682+
entityIDs.resize(elementNo);
3683+
3684+
LOOPIVDEP
3685+
for (std::size_t i = 0; i < elementNo; ++i)
3686+
{
3687+
entityIDs[i] = beginLocationIt->EntityID;
3688+
++beginLocationIt;
3689+
}
3690+
3691+
elementNo = 0;
3692+
}
3693+
else if (hasNoChild)
3694+
{
3695+
typename std::vector<Location>::iterator stuckedEndLocationIt;
3696+
if constexpr (IS_PARALLEL_EXEC)
3697+
{
3698+
stuckedEndLocationIt = std::partition_point(beginLocationIt, endLocationIt, [depthID](auto const& location) {
3699+
return location.DepthAndLocation.DepthID == depthID;
3700+
});
3701+
}
3702+
else
3703+
{
3704+
stuckedEndLocationIt =
3705+
std::partition(beginLocationIt, endLocationIt, [depthID](auto const& location) { return location.DepthAndLocation.DepthID == depthID; });
3706+
}
3707+
3708+
std::size_t const stuckedElementNo = std::distance(beginLocationIt, stuckedEndLocationIt);
3709+
3710+
auto& entityIDs = node.second.GetEntities();
3711+
entityIDs.resize(stuckedElementNo);
3712+
3713+
LOOPIVDEP
3714+
for (std::size_t i = 0; i < stuckedElementNo; ++i)
3715+
{
3716+
entityIDs[i] = beginLocationIt->EntityID;
3717+
++beginLocationIt;
3718+
}
3719+
3720+
elementNo -= stuckedElementNo;
3721+
}
3722+
3723+
if (elementNo == 0)
3724+
{
3725+
tree.m_nodes.emplace(std::move(node));
3726+
--depthID;
3727+
continue;
3728+
}
3729+
3730+
++depthID;
3731+
auto const examinedLevel = tree.GetDepthMax() - depthID;
3732+
auto const keyGenerator = typename SI::ChildKeyGenerator(node.first);
3733+
auto const childChecker = typename SI::ChildCheckerFixedDepth(examinedLevel, beginLocationIt->DepthAndLocation.LocID);
3734+
auto childKey = keyGenerator.GetChildNodeKey(childChecker.GetChildID(examinedLevel));
3735+
if constexpr (IS_PARALLEL_EXEC)
3736+
{
3737+
nodeStack[depthID].EndLocationIt = std::partition_point(beginLocationIt, endLocationIt, [&](auto const& location) {
3738+
return childChecker.Test(location.DepthAndLocation.LocID);
3739+
});
3740+
node.second.AddChild(childKey);
3741+
}
3742+
else
3743+
{
3744+
nodeStack[depthID].EndLocationIt =
3745+
std::partition(beginLocationIt, endLocationIt, [&](auto const& location) { return childChecker.Test(location.DepthAndLocation.LocID); });
3746+
node.second.AddChildInOrder(childKey);
3747+
}
3748+
3749+
nodeStack[depthID].NodeInstance.first = std::move(childKey);
3750+
nodeStack[depthID].NodeInstance.second = tree.CreateChild(node.second, childKey);
3751+
}
37213752

3722-
auto beginLocationIterator = locations.begin();
3723-
tree.CreateChildNodes(nodeRoot, rootKey, beginLocationIterator, locations.end(), maxDepthNo);
37243753
if constexpr (SPLIT_DEPTH_INCREASEMENT > 0)
37253754
{
37263755
// Eliminate duplicates. Not all sub-nodes will be created due to the maxElementNoInNode, which cause duplicates in the parent nodes.

0 commit comments

Comments
 (0)