Avoid intermediate allocations in parse_cpu_ranges

pull/1043/head
Tamir Duberstein 4 months ago
parent f3b2744072
commit 0e867572ff

@ -203,30 +203,33 @@ fn read_cpu_ranges(path: &'static str) -> Result<Vec<u32>, (&'static str, io::Er
(|| { (|| {
let data = fs::read_to_string(path)?; let data = fs::read_to_string(path)?;
parse_cpu_ranges(data.trim()) parse_cpu_ranges(data.trim())
.map_err(|range| io::Error::new(io::ErrorKind::InvalidData, range))
})() })()
.map_err(|error| (path, error)) .map_err(|error| (path, error))
} }
fn parse_cpu_ranges(data: &str) -> Result<Vec<u32>, &str> { fn parse_cpu_ranges(data: &str) -> Result<Vec<u32>, io::Error> {
let mut cpus = Vec::new(); data.split(',')
for range in data.split(',') { .map(|range| {
cpus.extend({ let mut iter = range
match range .split('-')
.splitn(2, '-') .map(|s| s.parse::<u32>().map_err(|ParseIntError { .. }| range));
.map(u32::from_str) let start = iter.next().unwrap()?; // str::split always returns at least one element.
.collect::<Result<Vec<_>, _>>() let end = match iter.next() {
.map_err(|ParseIntError { .. }| range)? None => start,
.as_slice() Some(end) => {
{ if iter.next().is_some() {
&[] | &[_, _, _, ..] => return Err(range), return Err(range);
&[start] => start..=start, }
&[start, end] => start..=end, end?
} }
};
Ok(start..=end)
})
.try_fold(Vec::new(), |mut cpus, range| {
let range = range.map_err(|range| io::Error::new(io::ErrorKind::InvalidData, range))?;
cpus.extend(range);
Ok(cpus)
}) })
}
Ok(cpus)
} }
/// Loads kernel symbols from `/proc/kallsyms`. /// Loads kernel symbols from `/proc/kallsyms`.

Loading…
Cancel
Save