Repository: tikv/tikv
File: src/config/mod.rs (Rust)

Code before:
            shared.compaction_thread_limiters.get(CF_RAFT),
            no_region_info_accessor
        );
        cf_opts
            .set_prefix_extractor("NoopSliceTransform", NoopSliceTransform)
            .unwrap();
        cf_opts.set_memtable_prefix_bloom_size_ratio(0.1);
        cf_opts.set_titan_cf_options(&self.titan.build_opts(&shared.cache));
        cf_opts
    }
}

#[derive(Clone, Serialize, Deserialize, PartialEq, Debug, OnlineConfig)]
#[serde(default)]
#[serde(rename_all = "kebab-case")]
pub struct TitanDbConfig {
    #[online_config(skip)]
    pub enabled: Option<bool>,
    #[online_config(skip)]
    pub dirname: String,
    #[online_config(skip)]
    pub disable_gc: bool,
    #[online_config(skip)]
    pub max_background_gc: i32,
    // The value of this field will be truncated to seconds.
    #[online_config(skip)]
    pub purge_obsolete_files_period: ReadableDuration,
}

impl Default for TitanDbConfig {
    fn default() -> Self {
        Self {
            enabled: None, // Enabled only for newly created cluster
            dirname: "".to_owned(),
            disable_gc: false,
            max_background_gc: 1,
            purge_obsolete_files_period: ReadableDuration::secs(10),
        }
    }
}

impl TitanDbConfig {
    fn build_opts(&self) -> RocksTitanDbOptions {
        let mut opts = RocksTitanDbOptions::new();
        opts.set_dirname(&self.dirname);
        opts.set_disable_background_gc(self.disable_gc);
        opts.set_max_background_gc(self.max_background_gc);
        opts.set_purge_obsolete_files_period(self.purge_obsolete_files_period.as_secs() as usize);
        opts
    }


Review comment (bug):
```suggestion
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(default)]
#[serde(rename_all = "kebab-case")]
pub struct TitanDbConfig {
    pub enabled: Option<bool>,
    pub dirname: String,
    pub disable_gc: bool,
    pub max_background_gc: i32,
    // The value of this field will be truncated to seconds.
```

FYI, `TitanDbConfig` has already been marked with `#[online_config(skip)]`, ref: https://github.com/tikv/tikv/blob/b53e5f79efe8873719ecae2c7904651d30e09e3c/src/config/mod.rs#L1866-L1867

Code after:
            shared.compaction_thread_limiters.get(CF_RAFT),
            no_region_info_accessor
        );
        cf_opts
            .set_prefix_extractor("NoopSliceTransform", NoopSliceTransform)
            .unwrap();
        cf_opts.set_memtable_prefix_bloom_size_ratio(0.1);
        cf_opts.set_titan_cf_options(&self.titan.build_opts(&shared.cache));
        cf_opts
    }
}

#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(default)]
#[serde(rename_all = "kebab-case")]
pub struct TitanDbConfig {
    pub enabled: Option<bool>,
    pub dirname: String,
    pub disable_gc: bool,
    pub max_background_gc: i32,
    // The value of this field will be truncated to seconds.
    pub purge_obsolete_files_period: ReadableDuration,
}

impl Default for TitanDbConfig {
    fn default() -> Self {
        Self {
            enabled: None, // Enabled only for newly created cluster
            dirname: "".to_owned(),
            disable_gc: false,
            max_background_gc: 1,
            purge_obsolete_files_period: ReadableDuration::secs(10),
        }
    }
}

impl TitanDbConfig {
    fn build_opts(&self) -> RocksTitanDbOptions {
        let mut opts = RocksTitanDbOptions::new();
        opts.set_dirname(&self.dirname);
        opts.set_disable_background_gc(self.disable_gc);
        opts.set_max_background_gc(self.max_background_gc);
        opts.set_purge_obsolete_files_period(self.purge_obsolete_files_period.as_secs() as usize);
        opts
    }

    fn validate(&self) -> Result<(), Box<dyn Error>> {
        Ok(())
    }

    fn write_into_metrics(&self) {