Find the k nearest entities to a point.
273{
274#ifdef MAYAFLUX_PLATFORM_MACOS
275 auto [snap, slot] = acquire_snapshot();
276 if (!snap || snap->positions.empty()) {
277 if (snap)
278 release_snapshot(slot);
279 return {};
280 }
281#else
282 auto snap_ptr =
m_snapshot.load(std::memory_order_acquire);
283 if (!snap_ptr || snap_ptr->positions.empty()) {
284 return {};
285 }
286 const auto* snap = snap_ptr.get();
287#endif
288
289 k = std::min(k, static_cast<uint32_t>(snap->positions.size()));
290
291 auto cmp = [](
const QueryResult&
a,
const QueryResult&
b) {
292 return a.distance_sq <
b.distance_sq;
293 };
294 std::priority_queue<QueryResult, std::vector<QueryResult>, decltype(cmp)> heap(cmp);
295
296 for (uint32_t i = 0; i < static_cast<uint32_t>(snap->positions.size()); ++i) {
298 if (heap.size() < k) {
299 heap.push({ snap->slot_to_id[i], d_sq });
300 } else if (d_sq < heap.top().distance_sq) {
301 heap.pop();
302 heap.push({ snap->slot_to_id[i], d_sq });
303 }
304 }
305
306 std::vector<QueryResult> results;
307 results.reserve(heap.size());
308 while (!heap.empty()) {
309 results.push_back(heap.top());
310 heap.pop();
311 }
312 std::ranges::reverse(results);
313
314#ifdef MAYAFLUX_PLATFORM_MACOS
315 release_snapshot(slot);
316#endif
317
318 return results;
319}
std::atomic< std::shared_ptr< const SpatialSnapshot< PointT > > > m_snapshot