public:
/// Config
struct config_t {
- size_t num_segments = 0;
- size_t segment_size = 0;
- size_t block_size = 0;
-
size_t target_journal_segments = 0;
size_t max_journal_segments = 0;
/// Number of bytes of journal entries to rewrite per cycle
size_t journal_rewrite_per_cycle = 0;
- static config_t default_from_segment_manager(
- SegmentManager &manager) {
+ static config_t get_default() {
return config_t{
- manager.get_num_segments(),
- static_cast<size_t>(manager.get_segment_size()),
- (size_t)manager.get_block_size(),
2, // target_journal_segments
4, // max_journal_segments
.9, // available_ratio_gc_max
};
private:
+ const bool detailed;
const config_t config;
+ size_t num_segments = 0;
+ size_t segment_size = 0;
+ size_t block_size = 0;
+
SpaceTrackerIRef space_tracker;
std::vector<segment_info_t> segments;
size_t empty_segments;
public:
SegmentCleaner(config_t config, bool detailed = false)
- : config(config),
- space_tracker(
- detailed ?
- (SpaceTrackerI*)new SpaceTrackerDetailed(
- config.num_segments,
- config.segment_size,
- config.block_size) :
- (SpaceTrackerI*)new SpaceTrackerSimple(
- config.num_segments)),
- segments(config.num_segments),
- empty_segments(config.num_segments),
+ : detailed(detailed),
+ config(config),
gc_process(*this) {}
+ void mount(SegmentManager &sm) {
+ init_complete = false;
+ used_bytes = 0;
+ journal_tail_target = journal_seq_t{};
+ journal_tail_committed = journal_seq_t{};
+ journal_head = journal_seq_t{};
+
+ num_segments = sm.get_num_segments();
+ segment_size = static_cast<size_t>(sm.get_segment_size());
+ block_size = static_cast<size_t>(sm.get_block_size());
+
+ space_tracker.reset(
+ detailed ?
+ (SpaceTrackerI*)new SpaceTrackerDetailed(
+ num_segments,
+ segment_size,
+ block_size) :
+ (SpaceTrackerI*)new SpaceTrackerSimple(
+ num_segments));
+
+ segments.clear();
+ segments.resize(num_segments);
+ empty_segments = num_segments;
+ }
+
get_segment_ret get_segment() final;
void close_segment(segment_id_t segment) final;
}
size_t get_bytes_available_current_segment() const {
- return config.segment_size - get_bytes_used_current_segment();
+ return segment_size - get_bytes_used_current_segment();
}
/**
/// Returns free space available for writes
size_t get_available_bytes() const {
- return (empty_segments * config.segment_size) +
+ return (empty_segments * segment_size) +
get_bytes_available_current_segment() +
get_bytes_scanned_current_segment();
}
/// Returns total space available
size_t get_total_bytes() const {
- return config.segment_size * config.num_segments;
+ return segment_size * num_segments;
}
/// Returns total space not free
size_t get_journal_segment_bytes() const {
assert(journal_head >= journal_tail_committed);
return (journal_head.segment_seq - journal_tail_committed.segment_seq + 1) *
- config.segment_size;
+ segment_size;
}
/**
TransactionManager::mkfs_ertr::future<> TransactionManager::mkfs()
{
LOG_PREFIX(TransactionManager::mkfs);
+ segment_cleaner->mount(segment_manager);
return journal->open_for_write().safe_then([this, FNAME](auto addr) {
DEBUG("TransactionManager::mkfs: about to do_with");
segment_cleaner->init_mkfs(addr);
{
LOG_PREFIX(TransactionManager::mount);
cache->init();
+ segment_cleaner->mount(segment_manager);
return journal->replay([this](auto seq, auto paddr, const auto &e) {
return cache->replay_delta(seq, paddr, e);
}).safe_then([this] {