@@ -248,10 +248,14 @@ class BlobFileMeta {
248248 uint64_t file_size () const { return file_size_; }
249249 uint64_t live_data_size () const { return live_data_size_; }
250250 uint32_t file_level () const { return file_level_; }
251+ uint64_t block_size () const { return block_size_; }
251252 const std::string& smallest_key () const { return smallest_key_; }
252253 const std::string& largest_key () const { return largest_key_; }
254+ int64_t effective_file_size () const { return effective_file_size_; }
253255
254256 void set_live_data_size (int64_t size) { live_data_size_ = size; }
257+ // This should be called with db mutex held.
258+ void set_effective_file_size (int64_t size) { effective_file_size_ = size; }
255259 uint64_t file_entries () const { return file_entries_; }
256260 FileState file_state () const { return state_; }
257261 bool is_obsolete () const { return state_ == FileState::kObsolete ; }
@@ -275,6 +279,10 @@ class BlobFileMeta {
275279 (file_size_ - kBlobMaxHeaderSize - kBlobFooterSize ));
276280 }
277281 TitanInternalStats::StatsType GetDiscardableRatioLevel () const ;
282+ // This should be called with db mutex held.
283+ uint64_t GetHolePunchableSize () const {
284+ return effective_file_size_ - live_data_size_;
285+ }
278286 void Dump (bool with_keys) const ;
279287
280288 private:
@@ -291,6 +299,18 @@ class BlobFileMeta {
291299 std::string smallest_key_;
292300 std::string largest_key_;
293301
302+ // The effective size of current file. This is different from `file_size_`, as
303+ // `file_size_` is the original size of the file, and does not consider space
304+ // reclaimed by punch hole GC.
305+ // We can't use file system's `st_blocks` to get the logical size, because
306+ // the file system's block size may be different from Titan's block size.
307+ // This is used to calculate the size of the punchable hole. i.e.
308+ // effective_file_size_ - live_data_size_.
309+ // This might be bigger than the actual size of the file, when Titan crashes
310+ // before updating the `effective_file_size_` during punch hole GC. This is
311+ // fine, as it will be corrected when the file is chose for GC next time.
312+ int64_t effective_file_size_{0 };
313+
294314 // Not persistent field
295315
296316 // Size of data with reference from SST files.
@@ -303,7 +323,11 @@ class BlobFileMeta {
303323 // So when state_ == kPendingLSM, it uses this to record the delta as a
304324 // positive number if any later compaction is trigger before previous
305325 // `OnCompactionCompleted()` is called.
326+ // The size is aligned with block size, when punch hole GC is enabled.
306327 std::atomic<int64_t > live_data_size_{0 };
328+ // This is different from `file_size_`, as `file_size_` is the original size
329+ // of the file, and does not consider space reclaimed by punch hole GC.
330+ std::atomic<int64_t > disk_usage_{0 };
307331 std::atomic<FileState> state_{FileState::kNone };
308332};
309333
0 commit comments