BLI: refactor IndexMask for better performance and memory usage #104629

Merged
Jacques Lucke merged 254 commits from JacquesLucke/blender:index-mask-refactor into main 2023-05-24 18:11:47 +02:00
2 changed files with 23 additions and 5 deletions
Showing only changes of commit 3d4ced77ed - Show all commits

View File

@ -80,9 +80,9 @@ class IndexMask {
IndexMask slice(IndexRange range) const;
template<typename Fn> void foreach_raw_segment(Fn &&fn) const;
template<typename Fn> void foreach_segment(Fn &&fn) const;
template<typename Fn> void foreach_span(Fn &&fn) const;
template<typename Fn> void foreach_index(Fn &&fn) const;
template<typename Fn> void foreach_index_range_or_span(Fn &&fn) const;
template<typename Fn> void foreach_span_or_range(Fn &&fn) const;
const IndexMaskData &data() const;
IndexMaskData &data_for_inplace_construction();
@ -484,7 +484,7 @@ template<typename Fn> inline void IndexMask::foreach_raw_segment(Fn &&fn) const
}
}
template<typename Fn> inline void IndexMask::foreach_segment(Fn &&fn) const
template<typename Fn> inline void IndexMask::foreach_span(Fn &&fn) const
{
this->foreach_raw_segment([&](const int64_t /*mask_index_offset*/,
const int64_t index_offset,
@ -504,6 +504,23 @@ template<typename Fn> inline void IndexMask::foreach_index(Fn &&fn) const
});
}
template<typename Fn> inline void IndexMask::foreach_span_or_range(Fn &&fn) const
{
IndexRangeChecker is_index_mask;
this->foreach_raw_segment([&, is_index_mask](const int64_t /*mask_index_offset*/,
const int64_t index_offset,
const Span<int16_t> indices) {
if (is_index_mask.check(indices)) {
const int64_t start = indices.first() + index_offset;
const int64_t size = indices.size();
fn(IndexRange(start, size));
}
else {
fn(OffsetSpan<int64_t, int16_t>(index_offset, indices));
}
});
}
} // namespace index_mask
using index_mask::IndexMask;

View File

@ -99,10 +99,11 @@ TEST(index_mask2, SplitByChunk)
TEST(index_mask2, IndicesToMask)
{
ResourceScope scope;
Array<int> data = {5, 100, 16383, 16384, 16385, 20000, 20001, 100000, 101000};
Array<int> data = {
5, 100, 16383, 16384, 16385, 20000, 20001, 50000, 50001, 50002, 100000, 101000};
IndexMask mask = unique_sorted_indices::to_index_mask<int>(data, scope);
mask.foreach_segment([&](auto segment) {
mask.foreach_span_or_range([&](auto segment) {
for (const int64_t i : segment) {
std::cout << i << ", ";
}