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

Loading…
Cancel
Save