in below/procfs/src/lib.rs [1012:1069]
fn read_kv_diff_line(&self, stats_filename: &str) -> Result<BTreeMap<String, u64>> {
let cur_path = self
.proc_net_dir
.recover_path()
.unwrap_or_else(|_| NET_PROCFS.into())
.join(stats_filename);
let stats_file = self
.proc_net_dir
.open_file(stats_filename)
.map_err(|e| Error::IoError(cur_path.clone(), e))?;
let buf_reader = BufReader::new(stats_file);
let content: Vec<String> = buf_reader
.lines()
.filter_map(|line| match line {
Ok(l) => Some(l),
_ => None,
})
.collect();
let mut res = BTreeMap::new();
for topic in content.chunks(2) {
let fields: Vec<&str> = topic[0].split(':').collect();
let vals: Vec<&str> = topic[1].split(':').collect();
if fields.len() != 2 || vals.len() != 2 || fields.len() != vals.len() {
return Err(Error::InvalidFileFormat(cur_path));
}
let key_header = fields[0];
let keys: Vec<&str> = fields[1].split_whitespace().collect();
let vals: Vec<&str> = vals[1].split_whitespace().collect();
if keys.is_empty() && keys.len() != vals.len() {
return Err(Error::InvalidFileFormat(cur_path));
}
for (&k, &v) in keys.iter().zip(vals.iter()) {
// There's case that stats like max_conn may have -1 value that represent no max. It's
// safe to skip such value and keep the result as None.
if v.starts_with('-') {
continue;
}
res.insert(
format!("{}_{}", key_header, &k),
v.parse::<u64>().map_err(|_| Error::ParseError {
line: k.into(),
item: v.into(),
type_name: "u64".into(),
path: cur_path.clone(),
})?,
);
}
}
Ok(res)
}