Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/overlaybd/lsmt/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -990,8 +990,12 @@ class LSMTFile : public LSMTReadOnlyFile {
DataStat data_stat;
data_stat.total_data_size = (buf.st_size - HeaderTrailer::SPACE);
data_stat.valid_data_size = index()->block_count() * ALIGNMENT;
LOG_DEBUG("data_size: ` ( valid: ` )", data_stat.total_data_size,
data_stat.valid_data_size);
// Get rewrite stats from the index
auto rw_stats = index()->rewrite_stats();
data_stat.total_blocks_written = rw_stats.total_blocks_written;
data_stat.rewritten_blocks = rw_stats.rewritten_blocks;
LOG_DEBUG("data_size: ` ( valid: ` ), rewrites: `/`", data_stat.total_data_size,
data_stat.valid_data_size, data_stat.rewritten_blocks, data_stat.total_blocks_written);
return data_stat;
}

Expand Down
3 changes: 3 additions & 0 deletions src/overlaybd/lsmt/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ class IFileRW : public IFileRO {
struct DataStat {
uint64_t total_data_size = -1; // size of total data
uint64_t valid_data_size = -1; // size of valid data (excluding garbage)
// Block rewrite telemetry (in 512B block units)
uint64_t total_blocks_written = 0; // Total blocks written
uint64_t rewritten_blocks = 0; // Blocks that overwrote previous data
};
virtual DataStat data_stat() const = 0;

Expand Down
38 changes: 38 additions & 0 deletions src/overlaybd/lsmt/index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,12 @@ class Index0 : public IComboIndex {
}
} alloc_blk;

// Block rewrite tracking for telemetry
struct rewrite_stats {
uint64_t total_blocks_written = 0; // Total blocks written (in 512B units)
uint64_t rewritten_blocks = 0; // Blocks that overwrote previous data
} m_rewrite_stats;

// Index0(const set<SegmentMapping> &mapping) : mapping(mapping){};

Index0(const SegmentMapping *pmappings = nullptr, size_t n = 0) {
Expand Down Expand Up @@ -314,6 +320,31 @@ class Index0 : public IComboIndex {
virtual void insert(SegmentMapping m) override {
if (m.length == 0)
return;

// Track total blocks written for rewrite telemetry
m_rewrite_stats.total_blocks_written += m.length;

// Count blocks that will be overwritten (rewritten)
uint64_t rewritten = 0;
auto check_it = mapping.lower_bound(m);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is in the hot path, serving block reads, and we've introduced another lookup.

Should this be somehow gated with a preprocessor guard, and only enabled when building the overlaybd-commit tool?

// Check previous mapping for overlap
if (check_it != mapping.begin()) {
auto prev_it = std::prev(check_it);
if (prev_it->end() > m.offset) {
// Previous mapping overlaps with new write
rewritten += std::min(prev_it->end(), m.end()) - m.offset;
}
}
// Check current and subsequent mappings for overlap
for (auto it = check_it; it != mapping.end() && it->offset < m.end(); ++it) {
uint64_t overlap_start = std::max(it->offset, m.offset);
uint64_t overlap_end = std::min(it->end(), m.end());
if (overlap_end > overlap_start) {
rewritten += overlap_end - overlap_start;
}
}
m_rewrite_stats.rewritten_blocks += rewritten;

alloc_blk += m;
auto it = mapping.lower_bound(m);
if (it == mapping.end()) {
Expand Down Expand Up @@ -369,6 +400,13 @@ class Index0 : public IComboIndex {
return alloc_blk.m_alloc;
}

virtual RewriteStats rewrite_stats() const override {
return RewriteStats{
m_rewrite_stats.total_blocks_written,
m_rewrite_stats.rewritten_blocks
};
}

// returns the first and last mapping in the index
// the there's no one, return an invalid mapping: [INVALID_OFFSET, 0) ==> 0
virtual SegmentMapping front() const override {
Expand Down
9 changes: 9 additions & 0 deletions src/overlaybd/lsmt/index.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ class IMemoryIndex {
virtual IMemoryIndex *make_read_only_index() const = 0;
};

// Block rewrite statistics for telemetry
struct RewriteStats {
uint64_t total_blocks_written = 0; // Total blocks written (in 512B units)
uint64_t rewritten_blocks = 0; // Blocks that overwrote previous data
};

// the level 0 memory index, which supports write
class IMemoryIndex0 : public IMemoryIndex {
public:
Expand All @@ -142,6 +148,9 @@ class IMemoryIndex0 : public IMemoryIndex {
// memory allocation is aligned to the `alignment`
virtual SegmentMapping *dump(size_t alignment = 0) const = 0;
// virtual IMemoryIndex *make_read_only_index() const = 0;

// Get block rewrite statistics for telemetry
virtual RewriteStats rewrite_stats() const = 0;
};

class IComboIndex : public IMemoryIndex0 {
Expand Down
11 changes: 11 additions & 0 deletions src/tools/overlaybd-commit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,17 @@ int main(int argc, char **argv) {
out = fout;
}

// Get data stats before commit for telemetry (includes rewrite frequency)
auto stats = fin->data_stat();
LOG_INFO("data_stat: total_data_size=`, valid_data_size=`, total_blocks_written=`, rewritten_blocks=`",
stats.total_data_size, stats.valid_data_size,
stats.total_blocks_written, stats.rewritten_blocks);

// Output rewrite stats as JSON to stdout for the caller to parse
// Format: {"total_blocks_written": N, "rewritten_blocks": M}
printf("{\"total_blocks_written\": %" PRIu64 ", \"rewritten_blocks\": %" PRIu64 "}\n",
stats.total_blocks_written, stats.rewritten_blocks);

CommitArgs args(out);
if (!uuid.empty()) {
memset(args.uuid.data, 0, UUID::String::LEN);
Expand Down