120 if (mdEvents.size() <= m_bc->getSplitThreshold()) {
121 m_bc->incBoxesCounter(0);
125 Task tsk{root, mdEvents.
begin(), mdEvents.end(), m_mortonMin, m_mortonMax, m_bc->getMaxDepth() + 1, 1};
127 if (m_numWorkers == 1)
128 distributeEvents(tsk, SLAVE);
130 std::vector<std::thread> workers;
131 workers.emplace_back([
this, &tsk]() {
132 distributeEvents(tsk, MASTER);
133 m_masterFinished =
true;
134 waitAndLaunchSlave();
136 for (
auto i = 1; i < m_numWorkers; ++i)
138 for (
auto &worker : workers)
218 const size_t childBoxCount = m_bc->getNumSplit();
219 const size_t splitThreshold = m_bc->getSplitThreshold();
221 if (tsk.
maxDepth-- == 1 || std::distance(tsk.
begin, tsk.
end) <=
static_cast<int>(splitThreshold)) {
229 const MortonT childBoxWidth = thisBoxWidth / childBoxCount;
231 auto eventIt = tsk.
begin;
233 struct RecursionHelper {
234 std::pair<EventIterator, EventIterator> eventRange;
235 std::pair<MortonT, MortonT> mortonBounds;
238 std::vector<RecursionHelper> children;
239 children.reserve(childBoxCount);
242 for (
size_t i = 0; i < childBoxCount; ++i) {
246 const auto boxLower = tsk.
lowerBound + ((childBoxWidth + 1) * i);
249 const auto boxUpper = childBoxWidth + boxLower;
251 const auto boxEventStart = eventIt;
253 if (eventIt < tsk.
end) {
254 if (morton_index::morton_contains<MortonT>(boxLower, boxUpper, IndexCoordinateSwitcher::getIndex(*eventIt)))
255 eventIt = std::upper_bound(
256 boxEventStart, tsk.
end, boxUpper,
257 [](
const MortonT &
m,
const typename std::iterator_traits<EventIterator>::value_type &event) {
258 return m < IndexCoordinateSwitcher::getIndex(event);
265 std::vector<Mantid::Geometry::MDDimensionExtents<coord_t>> extents(ND);
266 auto minCoord = morton_index::indexToCoordinates<ND, IntT, MortonT>(boxLower, m_space);
267 auto maxCoord = morton_index::indexToCoordinates<ND, IntT, MortonT>(boxUpper, m_space);
268 for (
unsigned ax = 0; ax < ND; ++ax) {
269 extents[ax].setExtents(minCoord[ax], maxCoord[ax]);
273 if (std::distance(boxEventStart, eventIt) <=
static_cast<int64_t
>(splitThreshold) || tsk.
maxDepth == 1) {
274 for (
auto it = boxEventStart; it < eventIt; ++it)
275 IndexCoordinateSwitcher::convertToCoordinates(*it, m_space);
276 m_bc->incBoxesCounter(tsk.
level);
277 newBox =
new Box(m_bc.get(), tsk.
level, extents, boxEventStart, eventIt);
279 m_bc->incGridBoxesCounter(tsk.
level);
283 children.emplace_back(RecursionHelper{{boxEventStart, eventIt}, {boxLower, boxUpper}, newBox});
287 std::sort(children.begin(), children.end(), [](RecursionHelper &a, RecursionHelper &b) {
290 const auto &ac = a.box->getExtents(i).getMin();
291 const auto &bc = b.box->getExtents(i).getMin();
299 std::vector<API::IMDNode *> boxes;
300 boxes.reserve(childBoxCount);
301 std::transform(std::cbegin(children), std::cend(children), std::back_inserter(boxes),
302 [](
const auto &ch) {
return ch.box; });
303 tsk.root->setChildren(boxes, 0, boxes.size());
306 for (
auto &ch : children) {
309 ch.eventRange.second,
310 ch.mortonBounds.first,
311 ch.mortonBounds.second,
314 if (wtp == MASTER && (
size_t)std::distance(newTask.begin, newTask.end) < m_eventsThreshold)
315 pushTask(std::move(newTask));
317 distributeEvents(newTask, wtp);