Skip to content

Commit 2ab039e

Browse files
committed
Report rewritten blocks telemetry
1 parent 98a9c3d commit 2ab039e

5 files changed

Lines changed: 67 additions & 2 deletions

File tree

src/overlaybd/lsmt/file.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -990,8 +990,12 @@ class LSMTFile : public LSMTReadOnlyFile {
990990
DataStat data_stat;
991991
data_stat.total_data_size = (buf.st_size - HeaderTrailer::SPACE);
992992
data_stat.valid_data_size = index()->block_count() * ALIGNMENT;
993-
LOG_DEBUG("data_size: ` ( valid: ` )", data_stat.total_data_size,
994-
data_stat.valid_data_size);
993+
// Get rewrite stats from the index
994+
auto rw_stats = index()->rewrite_stats();
995+
data_stat.total_blocks_written = rw_stats.total_blocks_written;
996+
data_stat.rewritten_blocks = rw_stats.rewritten_blocks;
997+
LOG_DEBUG("data_size: ` ( valid: ` ), rewrites: `/`", data_stat.total_data_size,
998+
data_stat.valid_data_size, data_stat.rewritten_blocks, data_stat.total_blocks_written);
995999
return data_stat;
9961000
}
9971001

src/overlaybd/lsmt/file.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ class IFileRW : public IFileRO {
9898
struct DataStat {
9999
uint64_t total_data_size = -1; // size of total data
100100
uint64_t valid_data_size = -1; // size of valid data (excluding garbage)
101+
// Block rewrite telemetry (in 512B block units)
102+
uint64_t total_blocks_written = 0; // Total blocks written
103+
uint64_t rewritten_blocks = 0; // Blocks that overwrote previous data
101104
};
102105
virtual DataStat data_stat() const = 0;
103106

src/overlaybd/lsmt/index.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,12 @@ class Index0 : public IComboIndex {
256256
}
257257
} alloc_blk;
258258

259+
// Block rewrite tracking for telemetry
260+
struct rewrite_stats {
261+
uint64_t total_blocks_written = 0; // Total blocks written (in 512B units)
262+
uint64_t rewritten_blocks = 0; // Blocks that overwrote previous data
263+
} m_rewrite_stats;
264+
259265
// Index0(const set<SegmentMapping> &mapping) : mapping(mapping){};
260266

261267
Index0(const SegmentMapping *pmappings = nullptr, size_t n = 0) {
@@ -314,6 +320,31 @@ class Index0 : public IComboIndex {
314320
virtual void insert(SegmentMapping m) override {
315321
if (m.length == 0)
316322
return;
323+
324+
// Track total blocks written for rewrite telemetry
325+
m_rewrite_stats.total_blocks_written += m.length;
326+
327+
// Count blocks that will be overwritten (rewritten)
328+
uint64_t rewritten = 0;
329+
auto check_it = mapping.lower_bound(m);
330+
// Check previous mapping for overlap
331+
if (check_it != mapping.begin()) {
332+
auto prev_it = std::prev(check_it);
333+
if (prev_it->end() > m.offset) {
334+
// Previous mapping overlaps with new write
335+
rewritten += std::min(prev_it->end(), m.end()) - m.offset;
336+
}
337+
}
338+
// Check current and subsequent mappings for overlap
339+
for (auto it = check_it; it != mapping.end() && it->offset < m.end(); ++it) {
340+
uint64_t overlap_start = std::max(it->offset, m.offset);
341+
uint64_t overlap_end = std::min(it->end(), m.end());
342+
if (overlap_end > overlap_start) {
343+
rewritten += overlap_end - overlap_start;
344+
}
345+
}
346+
m_rewrite_stats.rewritten_blocks += rewritten;
347+
317348
alloc_blk += m;
318349
auto it = mapping.lower_bound(m);
319350
if (it == mapping.end()) {
@@ -369,6 +400,13 @@ class Index0 : public IComboIndex {
369400
return alloc_blk.m_alloc;
370401
}
371402

403+
virtual RewriteStats rewrite_stats() const override {
404+
return RewriteStats{
405+
m_rewrite_stats.total_blocks_written,
406+
m_rewrite_stats.rewritten_blocks
407+
};
408+
}
409+
372410
// returns the first and last mapping in the index
373411
// the there's no one, return an invalid mapping: [INVALID_OFFSET, 0) ==> 0
374412
virtual SegmentMapping front() const override {

src/overlaybd/lsmt/index.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,12 @@ class IMemoryIndex {
132132
virtual IMemoryIndex *make_read_only_index() const = 0;
133133
};
134134

135+
// Block rewrite statistics for telemetry
136+
struct RewriteStats {
137+
uint64_t total_blocks_written = 0; // Total blocks written (in 512B units)
138+
uint64_t rewritten_blocks = 0; // Blocks that overwrote previous data
139+
};
140+
135141
// the level 0 memory index, which supports write
136142
class IMemoryIndex0 : public IMemoryIndex {
137143
public:
@@ -142,6 +148,9 @@ class IMemoryIndex0 : public IMemoryIndex {
142148
// memory allocation is aligned to the `alignment`
143149
virtual SegmentMapping *dump(size_t alignment = 0) const = 0;
144150
// virtual IMemoryIndex *make_read_only_index() const = 0;
151+
152+
// Get block rewrite statistics for telemetry
153+
virtual RewriteStats rewrite_stats() const = 0;
145154
};
146155

147156
class IComboIndex : public IMemoryIndex0 {

src/tools/overlaybd-commit.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,17 @@ int main(int argc, char **argv) {
188188
out = fout;
189189
}
190190

191+
// Get data stats before commit for telemetry (includes rewrite frequency)
192+
auto stats = fin->data_stat();
193+
LOG_INFO("data_stat: total_data_size=`, valid_data_size=`, total_blocks_written=`, rewritten_blocks=`",
194+
stats.total_data_size, stats.valid_data_size,
195+
stats.total_blocks_written, stats.rewritten_blocks);
196+
197+
// Output rewrite stats as JSON to stdout for the caller to parse
198+
// Format: {"total_blocks_written": N, "rewritten_blocks": M}
199+
printf("{\"total_blocks_written\": %" PRIu64 ", \"rewritten_blocks\": %" PRIu64 "}\n",
200+
stats.total_blocks_written, stats.rewritten_blocks);
201+
191202
CommitArgs args(out);
192203
if (!uuid.empty()) {
193204
memset(args.uuid.data, 0, UUID::String::LEN);

0 commit comments

Comments
 (0)