}
// Remove keys in removed_ranges
- for (auto out_it = out->begin(); out_it != out->end(); ++out_it) {
- if (should_be_removed(removed_ranges, out_it->first)) {
- out->erase(out_it->first);
- }
- }
+ remove_keys_in_ranges(removed_ranges, out);
// Apply updates in update_map
for (const auto &[key, val_opt] : update_map) {
// No ranges contain the key, return false
return false;
}
+
+void ECBackend::remove_keys_in_ranges(
+ const std::map<std::string, std::optional<std::string>>& removed_ranges,
+ std::map<std::string, ceph::buffer::list>* out) {
+ for (const auto& [start, end] : removed_ranges) {
+ out->erase(out->lower_bound(start),
+ end ? out->lower_bound(*end) : out->end());
+ }
+}
const std::map<std::string, std::optional<std::string>>& removed_ranges,
const std::string_view key
);
+
+ static void remove_keys_in_ranges(
+ const std::map<std::string, std::optional<std::string>>& removed_ranges,
+ std::map<std::string, ceph::buffer::list>* out
+ );
};
#include "test/unit.cc"
#include "osd/ECOmapJournal.h"
+#include "osd/ECBackend.h"
#include "common/dout.h"
class MockDoutPrefixProvider : public DoutPrefixProvider {
// Should not have updates after removing all entries
ASSERT_FALSE(journal.has_omap_updates(test_hoid));
-}
\ No newline at end of file
+}
+
+// A removed range spanning several adjacent keys erases all of them.
+TEST(ecbackend_remove_keys_in_ranges, removes_contiguous_block)
+{
+ std::map<std::string, ceph::buffer::list> out;
+ for (std::string_view k : {"k01", "k02", "k03", "k04", "k05", "k06"}) {
+ out[std::string(k)].append(k);
+ }
+ std::map<std::string, std::optional<std::string>> removed = {
+ {"k02", "k05"}, // -> erases k02, k03, k04
+ };
+
+ ECBackend::remove_keys_in_ranges(removed, &out);
+
+ std::vector<std::string> remaining;
+ for (const auto &[k, v] : out) {
+ remaining.push_back(k);
+ }
+ EXPECT_EQ((std::vector<std::string>{"k01", "k05", "k06"}), remaining);
+
+ // Surviving values must be untouched.
+ ASSERT_TRUE(out.contains("k05"));
+ ceph::buffer::list k05_bl;
+ k05_bl.append("k05");
+ EXPECT_TRUE(out["k05"].contents_equal(k05_bl));
+}