SpiecsEngine
 
Loading...
Searching...
No Matches

◆ insert_recursive_async()

template<uint32_t K>
void scl::kd_tree< K >::insert_recursive_async ( Node *& node,
std::shared_ptr< std::vector< item > > points,
Spices::ThreadPool * threadPool,
int depth )
inlineprivate

Recursive function to insert a point into the kd_tree async.

Parameters
[in]noderecursive node.
[in]pointsInserted points in k d.
[in]threadPoolThreadPool.
[in]depthrecursive depth.

Return if there is no point needs to insert.

Calculate current dimension (cd).

Sort points in cd.

Get Center iterator.

Base case: If node is null, create a new node.

Insert in left.

Insert in right.

Definition at line 320 of file KDTree.h.

326 {
327 constexpr int nPointsWithoutSplitTask = 30000;
328
329 if (points->size() <= nPointsWithoutSplitTask)
330 {
331 const auto in = std::chrono::high_resolution_clock::now();
332 insert_recursive(node, points, depth);
333 const auto out = std::chrono::high_resolution_clock::now();
334 std::cout << " Cost: " << std::chrono::duration_cast<std::chrono::milliseconds>(out - in).count() << " " << points->size() << std::endl;
335 return;
336 }
337
341 if (points->size() == 0) return;
342
346 int cd = depth % K;
347
351 std::multimap<float, uint32_t> sorted;
352 if (points->size() <= 512)
353 {
354 for (int i = 0; i < points->size(); i++)
355 {
356 sorted.emplace((*points)[i][cd], i);
357 }
358 }
359 else
360 {
361 for (int i = 0; i < 512; i++)
362 {
363 uint32_t index = static_cast<uint32_t>((points->size() - 1) * std::rand() / float(RAND_MAX));
364 sorted.emplace((*points)[index][cd], index);
365 }
366 }
367
371 auto centerit = sorted.begin();
372 for(int i = 0; i < std::floor(sorted.size() * 0.5); i++) ++centerit;
373
377 if (node == nullptr)
378 {
379 node = new Node((*points)[centerit->second]);
380 ++m_Size;
381 }
382 else
383 {
384 SPICES_CORE_ERROR("Cannot insert a KDTree Node which is not empty.");
385 }
386
390 threadPool->SubmitPoolTask([this, cd, points, node, threadPool, depth](float centerVal, uint32_t centerIndex) {
391 std::shared_ptr<std::vector<item>> leftPoints = std::make_shared<std::vector<item>>();
392 for (int i = 0; i < points->size(); i++)
393 {
394 if (i == centerIndex) continue;
395 else if ((*points)[i][cd] <= centerVal)
396 {
397 leftPoints->push_back((*points)[i]);
398 }
399 }
400 insert_recursive_async(node->m_Left, leftPoints, threadPool, depth + 1);
401 }, centerit->first, centerit->second);
402
406 threadPool->SubmitPoolTask([this, cd, points, node, threadPool, depth](float centerVal, uint32_t centerIndex) {
407 std::shared_ptr<std::vector<item>> rightPoints = std::make_shared<std::vector<item>>();
408 for (int i = 0; i < points->size(); i++)
409 {
410 if (i == centerIndex) continue;
411 else if ((*points)[i][cd] > centerVal)
412 {
413 rightPoints->push_back((*points)[i]);
414 }
415 }
416 insert_recursive_async(node->m_Right, rightPoints, threadPool, depth + 1);
417 }, centerit->first, centerit->second);
418 }
auto SubmitPoolTask(Func &&func, Args &&... args) -> std::future< decltype(func(std::forward< Args >(args)...))>
Submit a task to task queue, and wait for a idle thread to execute it.
void insert_recursive_async(Node *&node, std::shared_ptr< std::vector< item > > points, Spices::ThreadPool *threadPool, int depth)
Recursive function to insert a point into the kd_tree async.
Definition KDTree.h:320
void insert_recursive(Node *&node, std::shared_ptr< std::vector< item > > points, int depth)
Recursive function to insert a point into the kd_tree.
Definition KDTree.h:241
std::atomic_size_t m_Size
Sizes of this kd tree.
Definition KDTree.h:81