i->dirty_from_or_retired_at = JOURNAL_SEQ_MIN;
i->state = CachedExtent::extent_state_t::CLEAN;
assert(i->is_logical());
- i->cast<LogicalCachedExtent>()->clear_delta();
+ i->clear_modified_region();
touch_extent(*i);
DEBUGT("inplace rewrite ool block is commmitted -- {}", t, *i);
}
void on_replace_prior(Transaction &t) final;
- virtual void clear_delta() {}
-
struct modified_region_t {
extent_len_t offset;
extent_len_t len;
return std::nullopt;
}
+ virtual void clear_modified_region() {}
+
virtual ~LogicalCachedExtent();
protected:
bufferptr bp;
if (can_inplace_rewrite(t, ex)) {
auto r = ex->get_modified_region();
- if (r.has_value() && r->len > rbm->get_block_size()) {
- offset = p2align(r->offset, rbm->get_block_size());
- extent_len_t len =
- p2roundup(r->offset + r->len, rbm->get_block_size()) - offset;
- bp = ceph::bufferptr(ex->get_bptr(), offset, len);
- } else {
- bp = ex->get_bptr();
- }
+ ceph_assert(r.has_value());
+ offset = p2align(r->offset, rbm->get_block_size());
+ extent_len_t len =
+ p2roundup(r->offset + r->len, rbm->get_block_size()) - offset;
+ bp = ceph::bufferptr(ex->get_bptr(), offset, len);
} else {
bp = ex->get_bptr();
}
for (auto &&d : deltas) {
auto iter = d.bl.cbegin();
iter.copy(d.len, get_bptr().c_str() + d.offset);
+ modified_region.union_insert(d.offset, d.len);
}
}
std::vector<block_delta_t> delta = {};
+ interval_set<extent_len_t> modified_region;
+
explicit ObjectDataBlock(ceph::bufferptr &&ptr)
: LogicalCachedExtent(std::move(ptr)) {}
explicit ObjectDataBlock(const ObjectDataBlock &other)
- : LogicalCachedExtent(other) {}
+ : LogicalCachedExtent(other), modified_region(other.modified_region) {}
explicit ObjectDataBlock(extent_len_t length)
: LogicalCachedExtent(length) {}
auto iter = bl.cbegin();
iter.copy(bl.length(), get_bptr().c_str() + offset);
delta.push_back({offset, bl.length(), bl});
+ modified_region.union_insert(offset, bl.length());
}
ceph::bufferlist get_delta() final;
void apply_delta(const ceph::bufferlist &bl) final;
- void clear_delta() final {
- delta.clear();
- }
-
std::optional<modified_region_t> get_modified_region() final {
- interval_set<extent_len_t> range;
- for (auto &p : delta) {
- if (p.len > 0) {
- range.union_insert(p.offset, p.len);
- }
- }
- if (range.empty()) {
+ if (modified_region.empty()) {
return std::nullopt;
}
- return modified_region_t{range.range_start(),
- range.range_end() - range.range_start()};
+ return modified_region_t{modified_region.range_start(),
+ modified_region.range_end() - modified_region.range_start()};
+ }
+
+ void clear_modified_region() final {
+ modified_region.clear();
+ }
+
+ void logical_on_delta_write() final {
+ delta.clear();
}
};
using ObjectDataBlockRef = TCachedExtentRef<ObjectDataBlock>;
decode(deltas, biter);
for (auto &&d : deltas) {
set_contents(d.val, d.offset, d.len);
+ modified_region.union_insert(d.offset, d.len);
}
}
std::vector<test_block_delta_t> delta = {};
+ interval_set<extent_len_t> modified_region;
+
TestBlock(ceph::bufferptr &&ptr)
: LogicalCachedExtent(std::move(ptr)) {}
TestBlock(const TestBlock &other)
- : LogicalCachedExtent(other) {}
+ : LogicalCachedExtent(other), modified_region(other.modified_region) {}
CachedExtentRef duplicate_for_write(Transaction&) final {
return CachedExtentRef(new TestBlock(*this));
void set_contents(char c, uint16_t offset, uint16_t len) {
::memset(get_bptr().c_str() + offset, c, len);
delta.push_back({c, offset, len});
+ modified_region.union_insert(offset, len);
}
void set_contents(char c) {
void apply_delta(const ceph::bufferlist &bl) final;
- void clear_delta() final {
- delta.clear();
- }
-
std::optional<modified_region_t> get_modified_region() final {
- interval_set<extent_len_t> range;
- for (auto &p : delta) {
- if (p.len > 0) {
- range.union_insert(p.offset, p.len);
- }
- }
- if (range.empty()) {
+ if (modified_region.empty()) {
return std::nullopt;
}
- return modified_region_t{range.range_start(),
- range.range_end() - range.range_start()};
+ return modified_region_t{modified_region.range_start(),
+ modified_region.range_end() - modified_region.range_start()};
+ }
+
+ void clear_modified_region() final {
+ modified_region.clear();
+ }
+
+ void logical_on_delta_write() final {
+ delta.clear();
}
};
using TestBlockRef = TCachedExtentRef<TestBlock>;