1use crate::common::errors::Error;
5use std::fs::OpenOptions;
6use std::io::{BufRead, BufReader};
7use std::sync::Arc;
8use std::sync::Mutex;
9use std::sync::MutexGuard;
10use log::warn;
11
12
13#[derive(Clone)]
14pub struct ConfigMt {
16 conf: Arc<Mutex<Config>>,
17}
18
19impl ConfigMt {
20 pub fn new() -> ConfigMt {
22 ConfigMt {
23 conf: Arc::new(Mutex::new(Config::new()))
24 }
25 }
26
27 pub fn get_conf(&self) -> MutexGuard<Config> {
29 self.conf.lock().unwrap()
30 }
31}
32
33macro_rules! gen_config {
34 ( $( $name:ident, $data_type:ty, $default_val:expr, $get_fn:ident, $set_fn:ident, $str_name:literal, $conv_fn:path ), *) => {
35 pub struct Config {
37 $(
38 $name: $data_type,
39 )*
40 }
41
42 impl Config {
43
44 pub fn new() -> Config {
46 Config {
47 $(
48 $name: $default_val,
49 )*
50 }
51 }
52
53 $(
54 pub fn $get_fn(&self) -> &$data_type {
56 &self.$name
57 }
58
59 pub fn $set_fn(&mut self, $name: $data_type) {
61 self.$name = $name;
62 }
63 )*
64
65 fn process_config_file_entry(&mut self, name: &str, val: &str) -> Result<(), Error> {
66
67 match name {
68 $(
69 $str_name => { self.$name = $conv_fn(val)?; },
70 )*
71 _ => warn!("Skipping unexpected config entry: {}", name)
72 };
73
74 Ok(())
75 }
76 }
77 }
78}
79
80
81impl Config {
82
83 pub fn load(&mut self, file_path: &str) -> Result<(), Error> {
85 let f = BufReader::new(OpenOptions::new()
86 .create(false)
87 .write(false)
88 .read(true)
89 .truncate(false)
90 .open(file_path)?);
91
92 for line in f.lines() {
93 if let Ok(line) = line {
94 if let Ok((name, val)) = Self::process_config_file_line(&line) {
95 self.process_config_file_entry(name, val)?;
96 }
97 }
98 }
99
100 Ok(())
101 }
102
103 fn process_config_file_line<'a>(s: &'a str) -> Result<(&'a str, &'a str), ()> {
104 let line = s.as_bytes();
105 let mut p = 0;
106
107 while line[p] == b' ' || line[p] == b'\t' { p += 1; };
109
110 if line[p] == b'#' { return Err(()) }
112
113 let p1 = p;
115 while (line[p] >= b'a' && line[p] <= b'z')
116 || (line[p] >= b'A' && line[p] <= b'Z')
117 || (line[p] >= b'0' && line[p] <= b'9')
118 || line[p] == b'_' || line[p] == b'-'
119 {
120 p+= 1;
121 }
122 if p == p1 { return Err(()) }
123 let p2 = p;
124
125 while line[p] == b' ' || line[p] == b'\t' { p += 1; };
127 if line[p] != b'=' { return Err(()) }
128 while line[p] == b' ' || line[p] == b'\t' { p += 1; };
129
130 Ok((&s[p1..p2], &s[p..]))
132 }
133
134 fn load_string(value: &str) -> Result<String, Error> {
135 Ok(String::from(value))
136 }
137
138 fn load_u32_val(value: &str) -> Result<u32, Error> {
139 let ret = str::parse::<u32>(value)?;
140 Ok(ret)
141 }
142
143 fn load_u64_val(value: &str) -> Result<u64, Error> {
144 let ret = str::parse::<u64>(value)?;
145 Ok(ret)
146 }
147}
148
149gen_config![log_dir, String, "trnlog".to_owned(), get_log_dir, set_log_dir, "log_dir", Config::load_string,
150 datastore_path, String, ".".to_owned(), get_datastore_path, set_datastore_path, "datastore_path", Config::load_string,
151 max_log_file_size, u32, 10*1024*1024, get_max_log_file_size, set_max_log_file_size, "max_log_file_size", Config::load_u32_val,
152 log_writer_buf_size, u32, 1048576, get_log_writer_buf_size, set_log_writer_buf_size, "log_writer_buf_size", Config::load_u32_val,
153 tran_mgr_n_buckets, u32, 128, get_tran_mgr_n_buckets, set_tran_mgr_n_buckets, "tran_mgr_n_buckets", Config::load_u32_val,
154 tran_mgr_n_tran, u32, 1024, get_tran_mgr_n_tran, set_tran_mgr_n_tran, "tran_mgr_n_tran", Config::load_u32_val,
155 tran_mgr_n_obj_buckets, u32, 128, get_tran_mgr_n_obj_buckets, set_tran_mgr_n_obj_buckets, "tran_mgr_n_obj_buckets", Config::load_u32_val,
156 tran_mgr_n_obj_lock, u32, 1024, get_tran_mgr_n_obj_lock, set_tran_mgr_n_obj_lock, "tran_mgr_n_obj_lock", Config::load_u32_val,
157 block_mgr_n_lock, u32, 1024, get_block_mgr_n_lock, set_block_mgr_n_lock, "block_mgr_n_lock", Config::load_u32_val,
158 free_info_n_file_lock, u32, 16, get_free_info_n_file_lock, set_free_info_n_file_lock, "free_info_n_file_lock", Config::load_u32_val,
159 free_info_n_extent_lock, u32, 128, get_free_info_n_extent_lock, set_free_info_n_extent_lock, "free_info_n_extent_lock", Config::load_u32_val,
160 block_buf_size, u64, 32*1024*1024, get_block_buf_size, set_block_buf_size, "block_buf_size", Config::load_u64_val,
161 checkpoint_data_threshold, u64, 10*1024*1024, get_checkpoint_data_threshold, set_checkpoint_data_threshold, "checkpoint_data_threshold", Config::load_u64_val,
162 version_retain_time, u32, 3600, get_version_retain_time, set_version_retain_time, "version_retain_time", Config::load_u32_val,
163 block_fill_ratio, u32, 80, get_block_fill_ratio, set_block_fill_ratio, "block_fill_ratio", Config::load_u32_val,
164 writer_num, u32, 2, get_writer_num, set_writer_num, "writer_num", Config::load_u32_val];
165
166
167
168