{
const auto [left_chunk_index, right_chunk_index] =
sinfo.offset_length_to_data_chunk_indices(offset, length);
- for(uint64_t i = left_chunk_index; i < right_chunk_index; i++) {
- auto raw_chunk = i % sinfo.get_data_chunk_count();
+ const auto distance =
+ std::min(right_chunk_index - left_chunk_index,
+ sinfo.get_data_chunk_count());
+ for(uint64_t i = 0; i < distance; i++) {
+ auto raw_chunk = (left_chunk_index + i) % sinfo.get_data_chunk_count();
auto chunk = chunk_mapping.size() > raw_chunk ?
chunk_mapping[raw_chunk] : static_cast<int>(raw_chunk);
- if (auto [_, inserted] = want_to_read->insert(chunk); !inserted) {
- // aready processed all chunks
- ceph_assert(want_to_read->size() == sinfo.get_data_chunk_count());
- break;
- }
+ want_to_read->insert(chunk);
}
}
ASSERT_TRUE(want_to_read == (std::set<int>{0, 1, 2, 3}));
}
}
+
+TEST(ECCommon, get_min_want_to_read_shards_bug67087)
+{
+ const uint64_t swidth = 4096;
+ const uint64_t ssize = 4;
+
+ ECUtil::stripe_info_t s(ssize, swidth);
+ ASSERT_EQ(s.get_stripe_width(), swidth);
+ ASSERT_EQ(s.get_chunk_size(), 1024);
+
+ const std::vector<int> chunk_mapping = {}; // no remapping
+
+ std::set<int> want_to_read;
+
+ // multitple calls with the same want_to_read can happen during
+ // multi-region reads.
+ {
+ ECCommon::ReadPipeline::get_min_want_to_read_shards(
+ 512, 512, s, chunk_mapping, &want_to_read);
+ ASSERT_EQ(want_to_read, std::set<int>{0});
+ ECCommon::ReadPipeline::get_min_want_to_read_shards(
+ 512+16*1024, 512, s, chunk_mapping, &want_to_read);
+ ASSERT_EQ(want_to_read, std::set<int>{0});
+ }
+}