1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 12:07:46 +00:00

uniq: avoid allocations for the iterator

This commit is contained in:
Simon Vandel Sillesen 2018-07-21 15:26:38 +02:00
parent 781c9236e1
commit e30237a714

View file

@ -44,10 +44,6 @@ struct Uniq {
zero_terminated: bool, zero_terminated: bool,
} }
fn iter_ne<'a>(lhs: Box<Iterator<Item = char> + 'a>, rhs: Box<Iterator<Item = char> + 'a>) -> bool {
lhs.ne(rhs)
}
impl Uniq { impl Uniq {
pub fn print_uniq<R: Read, W: Write>( pub fn print_uniq<R: Read, W: Write>(
&self, &self,
@ -107,7 +103,16 @@ impl Uniq {
} }
} }
fn cmp_key<'a>(&'a self, line: &'a str) -> Box<Iterator<Item = char> + 'a> { fn cmp_keys(&self, first: &str, second: &str) -> bool {
self.cmp_key(first, |first_iter| {
self.cmp_key(second, |second_iter| first_iter.ne(second_iter))
})
}
fn cmp_key<F>(&self, line: &str, mut closure: F) -> bool
where
F: FnMut(&mut Iterator<Item = char>) -> bool,
{
let fields_to_check = self.skip_fields(line); let fields_to_check = self.skip_fields(line);
let len = fields_to_check.len(); let len = fields_to_check.len();
let slice_start = self.slice_start.unwrap_or(0); let slice_start = self.slice_start.unwrap_or(0);
@ -115,12 +120,12 @@ impl Uniq {
if len > 0 { if len > 0 {
// fast path: avoid doing any work if there is no need to skip or map to lower-case // fast path: avoid doing any work if there is no need to skip or map to lower-case
if !self.ignore_case && slice_start == 0 && slice_stop == len { if !self.ignore_case && slice_start == 0 && slice_stop == len {
return Box::new(fields_to_check.chars()); return closure(&mut fields_to_check.chars());
} }
// fast path: avoid skipping // fast path: avoid skipping
if self.ignore_case && slice_start == 0 && slice_stop == len { if self.ignore_case && slice_start == 0 && slice_stop == len {
return Box::new(fields_to_check.chars().map(|c| match c { return closure(&mut fields_to_check.chars().map(|c| match c {
'a'...'z' => ((c as u8) - 32) as char, 'a'...'z' => ((c as u8) - 32) as char,
_ => c, _ => c,
})); }));
@ -128,11 +133,11 @@ impl Uniq {
// fast path: we can avoid mapping chars to upper-case, if we don't want to ignore the case // fast path: we can avoid mapping chars to upper-case, if we don't want to ignore the case
if !self.ignore_case { if !self.ignore_case {
return Box::new(fields_to_check.chars().skip(slice_start).take(slice_stop)); return closure(&mut fields_to_check.chars().skip(slice_start).take(slice_stop));
} }
Box::new( closure(
fields_to_check &mut fields_to_check
.chars() .chars()
.skip(slice_start) .skip(slice_start)
.take(slice_stop) .take(slice_stop)
@ -142,7 +147,7 @@ impl Uniq {
}), }),
) )
} else { } else {
Box::new(fields_to_check.chars()) closure(&mut fields_to_check.chars())
} }
} }