Use separate type for sizes

This commit is contained in:
Lars Mueller 2024-05-20 03:09:02 +02:00
parent bffba43644
commit 267dc09f8b

@ -54,6 +54,11 @@ There are plenty variations that could be explored:
*/ */
using Idx = uint16_t; // TODO unify with Id 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 // TODO more doc comments
@ -68,13 +73,13 @@ class Points {
//! Empty //! Empty
Points() : n(0), coords(nullptr) {} Points() : n(0), coords(nullptr) {}
//! Allocating constructor; leaves coords uninitialized! //! Allocating constructor; leaves coords uninitialized!
Points(Idx n) : n(n), coords(new Component[Dim * static_cast<std::size_t>(n)]) {} Points(Size n) : n(n), coords(new Component[Dim * n]) {}
//! Copying constructor //! Copying constructor
Points(Idx n, const std::array<Component const *, Dim> &coords) : Points(n) { Points(Size n, const std::array<Component const *, Dim> &coords) : Points(n) {
for (uint8_t d = 0; d < Dim; ++d) for (uint8_t d = 0; d < Dim; ++d)
std::copy(coords[d], coords[d] + n, begin(d)); std::copy(coords[d], coords[d] + n, begin(d));
} }
Idx size() const { Size size() const {
return n; return n;
} }
void assign(Idx start, const Points &from) { void assign(Idx start, const Points &from) {
@ -104,7 +109,7 @@ class Points {
return begin(d) + n; return begin(d) + n;
} }
private: private:
Idx n; Size n;
std::unique_ptr<Component[]> coords; std::unique_ptr<Component[]> coords;
}; };
@ -115,18 +120,18 @@ class SortedIndices {
SortedIndices() : indices() {} SortedIndices() : indices() {}
//! uninitialized indices //! uninitialized indices
static SortedIndices newUninitialized(Idx n) { static SortedIndices newUninitialized(Size n) {
return SortedIndices(Points<Dim, Idx>(n)); return SortedIndices(Points<Dim, Idx>(n));
} }
//! Identity permutation on all axes //! Identity permutation on all axes
SortedIndices(Idx n) : indices(n) { SortedIndices(Size n) : indices(n) {
for (uint8_t d = 0; d < Dim; ++d) for (uint8_t d = 0; d < Dim; ++d)
for (Idx i = 0; i < n; ++i) for (Idx i = 0; i < n; ++i)
indices.begin(d)[i] = i; indices.begin(d)[i] = i;
} }
Idx size() const { Size size() const {
return indices.size(); return indices.size();
} }
@ -205,7 +210,7 @@ class SortedPoints {
} }
//! Sort points //! Sort points
SortedPoints(Idx n, const std::array<Component const *, Dim> ptrs) SortedPoints(Size n, const std::array<Component const *, Dim> ptrs)
: points(n, ptrs), indices(n) : points(n, ptrs), indices(n)
{ {
for (uint8_t d = 0; d < Dim; ++d) { for (uint8_t d = 0; d < Dim; ++d) {
@ -218,7 +223,7 @@ class SortedPoints {
//! Merge two sets of sorted points //! Merge two sets of sorted points
SortedPoints(const SortedPoints &a, const SortedPoints &b) SortedPoints(const SortedPoints &a, const SortedPoints &b)
: points(static_cast<std::size_t>(a.size()) + b.size()) : points(a.size() + b.size())
{ {
const auto n = points.size(); const auto n = points.size();
indices = SortedIndices<Dim>::newUninitialized(n); indices = SortedIndices<Dim>::newUninitialized(n);
@ -247,7 +252,7 @@ class SortedPoints {
} }
} }
Idx size() const { Size size() const {
// technically redundant with indices.size(), // technically redundant with indices.size(),
// but that is irrelevant // but that is irrelevant
return points.size(); return points.size();
@ -282,7 +287,7 @@ class KdTree {
} }
//! Build a tree //! Build a tree
KdTree(Idx n, Id const *ids, std::array<Component const *, Dim> pts) KdTree(Size n, Id const *ids, std::array<Component const *, Dim> pts)
: items(n, pts) : items(n, pts)
, ids(std::make_unique<Id[]>(n)) , ids(std::make_unique<Id[]>(n))
, tree(std::make_unique<Idx[]>(n)) , tree(std::make_unique<Idx[]>(n))
@ -313,8 +318,6 @@ class KdTree {
template<typename F> template<typename F>
void rangeQuery(const Point &min, const Point &max, void rangeQuery(const Point &min, const Point &max,
const F &cb) const { const F &cb) const {
if (empty())
return;
rangeQuery(0, 0, min, max, cb); rangeQuery(0, 0, min, max, cb);
} }
@ -331,7 +334,7 @@ class KdTree {
} }
//! Capacity, not size, since some items may be marked as deleted //! Capacity, not size, since some items may be marked as deleted
Idx cap() const { Size cap() const {
return items.size(); return items.size();
} }
@ -431,7 +434,7 @@ class DynamicKdTrees {
for (const auto &tree : trees) for (const auto &tree : trees)
tree.rangeQuery(min, max, cb); tree.rangeQuery(min, max, cb);
} }
Idx size() const { Size size() const {
return n_entries - deleted; return n_entries - deleted;
} }
private: private:
@ -452,11 +455,11 @@ class DynamicKdTrees {
// Collect all live points and corresponding IDs. // Collect all live points and corresponding IDs.
const auto live_ids = std::make_unique<Id[]>(n_entries); const auto live_ids = std::make_unique<Id[]>(n_entries);
Points<Dim, Component> live_points(n_entries); Points<Dim, Component> live_points(n_entries);
Idx i = 0; Size i = 0;
for (const auto &tree : trees) { for (const auto &tree : trees) {
tree.foreach([&](Idx _, auto point, Id id) { tree.foreach([&](Idx _, auto point, Id id) {
assert(i < n_entries); assert(i < n_entries);
live_points.setPoint(i, point); live_points.setPoint(static_cast<Idx>(i), point);
live_ids[i] = id; live_ids[i] = id;
++i; ++i;
}); });
@ -467,7 +470,7 @@ class DynamicKdTrees {
// The "tree pattern" will effectively just be shifted down by one. // The "tree pattern" will effectively just be shifted down by one.
auto id_ptr = live_ids.get(); auto id_ptr = live_ids.get();
std::array<Component const *, Dim> point_ptrs; std::array<Component const *, Dim> point_ptrs;
Idx n = 1; Size n = 1;
for (uint8_t d = 0; d < Dim; ++d) for (uint8_t d = 0; d < Dim; ++d)
point_ptrs[d] = live_points.begin(d); point_ptrs[d] = live_points.begin(d);
for (uint8_t tree_idx = 0; tree_idx < trees.size() - 1; ++tree_idx, n *= 2) { for (uint8_t tree_idx = 0; tree_idx < trees.size() - 1; ++tree_idx, n *= 2) {
@ -491,6 +494,6 @@ class DynamicKdTrees {
Idx in_tree; Idx in_tree;
}; };
std::unordered_map<Id, DelEntry> del_entries; std::unordered_map<Id, DelEntry> del_entries;
Idx n_entries = 0; Size n_entries = 0;
Idx deleted = 0; Size deleted = 0;
}; };