diff --git a/src/util/k_d_tree.h b/src/util/k_d_tree.h index cca54bdcc..81a6c44f9 100644 --- a/src/util/k_d_tree.h +++ b/src/util/k_d_tree.h @@ -54,6 +54,11 @@ There are plenty variations that could be explored: */ using Idx = uint16_t; // TODO unify with Id +// Use a separate, larger type for sizes than for indices +// to make sure there are no wraparounds when we approach the limit. +// This hardly affects performance or memory usage; +// the core arrays still only store indices. +using Size = uint32_t; // TODO more doc comments @@ -68,13 +73,13 @@ class Points { //! Empty Points() : n(0), coords(nullptr) {} //! Allocating constructor; leaves coords uninitialized! - Points(Idx n) : n(n), coords(new Component[Dim * static_cast(n)]) {} + Points(Size n) : n(n), coords(new Component[Dim * n]) {} //! Copying constructor - Points(Idx n, const std::array &coords) : Points(n) { + Points(Size n, const std::array &coords) : Points(n) { for (uint8_t d = 0; d < Dim; ++d) std::copy(coords[d], coords[d] + n, begin(d)); } - Idx size() const { + Size size() const { return n; } void assign(Idx start, const Points &from) { @@ -104,7 +109,7 @@ class Points { return begin(d) + n; } private: - Idx n; + Size n; std::unique_ptr coords; }; @@ -115,18 +120,18 @@ class SortedIndices { SortedIndices() : indices() {} //! uninitialized indices - static SortedIndices newUninitialized(Idx n) { + static SortedIndices newUninitialized(Size n) { return SortedIndices(Points(n)); } //! Identity permutation on all axes - SortedIndices(Idx n) : indices(n) { + SortedIndices(Size n) : indices(n) { for (uint8_t d = 0; d < Dim; ++d) for (Idx i = 0; i < n; ++i) indices.begin(d)[i] = i; } - Idx size() const { + Size size() const { return indices.size(); } @@ -205,7 +210,7 @@ class SortedPoints { } //! Sort points - SortedPoints(Idx n, const std::array ptrs) + SortedPoints(Size n, const std::array ptrs) : points(n, ptrs), indices(n) { for (uint8_t d = 0; d < Dim; ++d) { @@ -218,7 +223,7 @@ class SortedPoints { //! Merge two sets of sorted points SortedPoints(const SortedPoints &a, const SortedPoints &b) - : points(static_cast(a.size()) + b.size()) + : points(a.size() + b.size()) { const auto n = points.size(); indices = SortedIndices::newUninitialized(n); @@ -247,7 +252,7 @@ class SortedPoints { } } - Idx size() const { + Size size() const { // technically redundant with indices.size(), // but that is irrelevant return points.size(); @@ -282,7 +287,7 @@ class KdTree { } //! Build a tree - KdTree(Idx n, Id const *ids, std::array pts) + KdTree(Size n, Id const *ids, std::array pts) : items(n, pts) , ids(std::make_unique(n)) , tree(std::make_unique(n)) @@ -313,8 +318,6 @@ class KdTree { template void rangeQuery(const Point &min, const Point &max, const F &cb) const { - if (empty()) - return; rangeQuery(0, 0, min, max, cb); } @@ -331,7 +334,7 @@ class KdTree { } //! Capacity, not size, since some items may be marked as deleted - Idx cap() const { + Size cap() const { return items.size(); } @@ -431,7 +434,7 @@ class DynamicKdTrees { for (const auto &tree : trees) tree.rangeQuery(min, max, cb); } - Idx size() const { + Size size() const { return n_entries - deleted; } private: @@ -452,11 +455,11 @@ class DynamicKdTrees { // Collect all live points and corresponding IDs. const auto live_ids = std::make_unique(n_entries); Points live_points(n_entries); - Idx i = 0; + Size i = 0; for (const auto &tree : trees) { tree.foreach([&](Idx _, auto point, Id id) { assert(i < n_entries); - live_points.setPoint(i, point); + live_points.setPoint(static_cast(i), point); live_ids[i] = id; ++i; }); @@ -467,7 +470,7 @@ class DynamicKdTrees { // The "tree pattern" will effectively just be shifted down by one. auto id_ptr = live_ids.get(); std::array point_ptrs; - Idx n = 1; + Size n = 1; for (uint8_t d = 0; d < Dim; ++d) point_ptrs[d] = live_points.begin(d); for (uint8_t tree_idx = 0; tree_idx < trees.size() - 1; ++tree_idx, n *= 2) { @@ -491,6 +494,6 @@ class DynamicKdTrees { Idx in_tree; }; std::unordered_map del_entries; - Idx n_entries = 0; - Idx deleted = 0; + Size n_entries = 0; + Size deleted = 0; }; \ No newline at end of file