t.read_set.clear();
t.write_set.clear();
- record_t record(trans_src);
+ record_t record(record_type_t::JOURNAL, trans_src);
auto commit_time = seastar::lowres_system_clock::now();
// Add new copy of mutated blocks, set_io_wait to block until written
return do_write(t, extents);
});
}
- record_t record(t.get_src());
+ record_t record(record_type_t::JOURNAL, t.get_src());
std::list<LogicalCachedExtentRef> pending_extents;
auto commit_time = seastar::lowres_system_clock::now();
extent_len_t record_size_t::get_raw_mdlength() const
{
+ assert(record_type < record_type_t::MAX);
// empty record is allowed to submit
- return plain_mdlength +
- ceph::encoded_sizeof_bounded<record_header_t>();
+ extent_len_t ret = plain_mdlength;
+ if (record_type == record_type_t::JOURNAL) {
+ ret += ceph::encoded_sizeof_bounded<record_header_t>();
+ } else {
+ // OOL won't contain metadata
+ assert(ret == 0);
+ }
+ return ret;
}
void record_size_t::account_extent(extent_len_t extent_len)
{
assert(extent_len);
- plain_mdlength += ceph::encoded_sizeof_bounded<extent_info_t>();
+ if (record_type == record_type_t::JOURNAL) {
+ plain_mdlength += ceph::encoded_sizeof_bounded<extent_info_t>();
+ } else {
+ // OOL won't contain metadata
+ }
dlength += extent_len;
}
void record_size_t::account(const delta_info_t& delta)
{
+ assert(record_type == record_type_t::JOURNAL);
assert(delta.bl.length());
plain_mdlength += ceph::encoded_sizeof(delta);
}
std::ostream &operator<<(std::ostream& out, const record_size_t& rsize)
{
return out << "record_size_t("
+ << "record_type=" << rsize.record_type
<< "raw_md=" << rsize.get_raw_mdlength()
<< ", data=" << rsize.dlength
<< ")";
}
+std::ostream &operator<<(std::ostream& out, const record_type_t& type)
+{
+ switch (type) {
+ case record_type_t::JOURNAL:
+ return out << "JOURNAL";
+ case record_type_t::OOL:
+ return out << "OOL";
+ case record_type_t::MAX:
+ return out << "NULL";
+ default:
+ return out << "INVALID_RECORD_TYPE("
+ << static_cast<std::size_t>(type)
+ << ")";
+ }
+}
+
std::ostream &operator<<(std::ostream& out, const record_t& r)
{
return out << "record_t("
extent_len_t record_group_size_t::get_raw_mdlength() const
{
- return plain_mdlength +
- sizeof(checksum_t) +
- ceph::encoded_sizeof_bounded<record_group_header_t>();
+ assert(record_type < record_type_t::MAX);
+ extent_len_t ret = plain_mdlength;
+ if (record_type == record_type_t::JOURNAL) {
+ ret += sizeof(checksum_t);
+ ret += ceph::encoded_sizeof_bounded<record_group_header_t>();
+ } else {
+ // OOL won't contain metadata
+ assert(ret == 0);
+ }
+ return ret;
}
void record_group_size_t::account(
assert(_block_size > 0);
assert(rsize.dlength % _block_size == 0);
assert(block_size == 0 || block_size == _block_size);
- plain_mdlength += rsize.get_raw_mdlength();
- dlength += rsize.dlength;
+ assert(record_type == RECORD_TYPE_NULL ||
+ record_type == rsize.record_type);
block_size = _block_size;
+ record_type = rsize.record_type;
+ if (record_type == record_type_t::JOURNAL) {
+ plain_mdlength += rsize.get_raw_mdlength();
+ } else {
+ // OOL won't contain metadata
+ assert(rsize.get_raw_mdlength() == 0);
+ }
+ dlength += rsize.dlength;
}
std::ostream& operator<<(std::ostream& out, const record_group_size_t& size)
{
return out << "record_group_size_t("
+ << "record_type=" << size.record_type
<< "raw_md=" << size.get_raw_mdlength()
<< ", data=" << size.dlength
<< ", block_size=" << size.block_size
is_background_transaction(type));
}
+// Note: It is possible to statically introduce structs for OOL, which must be
+// more efficient, but that requires to specialize the RecordSubmitter as well.
+// Let's delay this optimization until necessary.
+enum class record_type_t {
+ JOURNAL = 0,
+ OOL, // no header, no metadata, so no padding
+ MAX
+};
+std::ostream &operator<<(std::ostream&, const record_type_t&);
+
+static constexpr auto RECORD_TYPE_NULL = record_type_t::MAX;
+
struct record_size_t {
+ record_type_t record_type = RECORD_TYPE_NULL; // must not be NULL in use
extent_len_t plain_mdlength = 0; // mdlength without the record header
extent_len_t dlength = 0;
record_size_t size;
sea_time_point modify_time = NULL_TIME;
- record_t(transaction_type_t t_type) : trans_type{t_type} { }
+ record_t(record_type_t r_type,
+ transaction_type_t t_type)
+ : trans_type{t_type} {
+ assert(r_type != RECORD_TYPE_NULL);
+ size.record_type = r_type;
+ }
// unit test only
record_t() {
trans_type = transaction_type_t::MUTATE;
+ size.record_type = record_type_t::JOURNAL;
}
// unit test only
record_t(std::vector<extent_t>&& _extents,
std::vector<delta_info_t>&& _deltas) {
+ trans_type = transaction_type_t::MUTATE;
+ size.record_type = record_type_t::JOURNAL;
auto modify_time = seastar::lowres_system_clock::now();
for (auto& e: _extents) {
push_back(std::move(e), modify_time);
for (auto& d: _deltas) {
push_back(std::move(d));
}
- trans_type = transaction_type_t::MUTATE;
}
bool is_empty() const {
}
std::size_t get_delta_size() const {
+ assert(size.record_type < record_type_t::MAX);
+ if (size.record_type == record_type_t::OOL) {
+ // OOL won't contain metadata
+ assert(deltas.size() == 0);
+ return 0;
+ }
+ // JOURNAL
auto delta_size = std::accumulate(
deltas.begin(), deltas.end(), 0,
[](uint64_t sum, auto& delta) {
std::ostream& operator<<(std::ostream&, const record_group_header_t&);
struct record_group_size_t {
+ record_type_t record_type = RECORD_TYPE_NULL; // must not be NULL in use
extent_len_t plain_mdlength = 0; // mdlength without the group header
extent_len_t dlength = 0;
extent_len_t block_size = 0;
extent_len_t get_mdlength() const {
assert(block_size > 0);
- return p2roundup(get_raw_mdlength(), block_size);
+ assert(record_type < record_type_t::MAX);
+ if (record_type == record_type_t::JOURNAL) {
+ return p2roundup(get_raw_mdlength(), block_size);
+ } else {
+ // OOL won't contain metadata
+ assert(get_raw_mdlength() == 0);
+ return 0;
+ }
}
extent_len_t get_encoded_length() const {
template <> struct fmt::formatter<crimson::os::seastore::record_group_size_t> : fmt::ostream_formatter {};
template <> struct fmt::formatter<crimson::os::seastore::record_header_t> : fmt::ostream_formatter {};
template <> struct fmt::formatter<crimson::os::seastore::record_locator_t> : fmt::ostream_formatter {};
+template <> struct fmt::formatter<crimson::os::seastore::record_type_t> : fmt::ostream_formatter {};
template <> struct fmt::formatter<crimson::os::seastore::record_t> : fmt::ostream_formatter {};
template <> struct fmt::formatter<crimson::os::seastore::rewrite_gen_printer_t> : fmt::ostream_formatter {};
template <> struct fmt::formatter<crimson::os::seastore::scan_valid_records_cursor> : fmt::ostream_formatter {};