BLI: refactor IndexMask for better performance and memory usage #104629
|
@ -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;
|
||||
|
|
|
@ -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 << ", ";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue