Mercurial > lbo > hg > localmr
changeset 59:359c981afa71
Reorganize SMI sorting function: Use default implementation in-line
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Fri, 05 Feb 2016 21:48:31 +0000 |
parents | 2e7fba6d7cad |
children | c8cab29a9d89 |
files | src/shard_merge.rs src/sort.rs |
diffstat | 2 files changed, 59 insertions(+), 59 deletions(-) [+] |
line wrap: on
line diff
--- a/src/shard_merge.rs Fri Feb 05 21:38:25 2016 +0000 +++ b/src/shard_merge.rs Fri Feb 05 21:48:31 2016 +0000 @@ -18,7 +18,7 @@ left_peeked: Option<T>, right_peeked: Option<T>, - comparer: Option<sort::Comparer<T>>, + comparer: sort::Comparer<T>, } impl<'a, T: Ord + Clone> Iterator for ShardMergeIterator<'a, T> { @@ -47,7 +47,7 @@ return r; } (Some(l), Some(r)) => { - let cmp = self.compare(&l, &r); + let cmp = (self.comparer)(&l, &r); if cmp == Ordering::Less || cmp == Ordering::Equal { self.left_peeked = None; return Some(l); @@ -69,7 +69,7 @@ right: Box::new(iter::empty()), left_peeked: None, right_peeked: None, - comparer: None, + comparer: sort::default_generic_compare, } } @@ -94,12 +94,13 @@ /// Takes multiple iterators of type It and generates one ShardedMergeIterator.. /// (yes, iterator over a collection of iterators). fn _build<It: Iterator<Item = T>, ItIt: Iterator<Item = It>>(sources: &mut ItIt, - cmp: Option<sort::Comparer<T>>) + cmp_o: Option<sort::Comparer<T>>) -> ShardMergeIterator<'a, T> where T: 'a, It: 'a { let mut merged: Vec<ShardMergeIterator<T>> = Vec::new(); + let cmp_fn = cmp_o.unwrap_or(sort::default_generic_compare); // Initial merging: Merge pairs of input iterators together. loop { @@ -113,7 +114,7 @@ merged.push(ShardMergeIterator { left: Box::new(src1), right: Box::new(iter::empty()), - comparer: cmp, + comparer: cmp_fn, ..ShardMergeIterator::default() }) } @@ -121,7 +122,7 @@ merged.push(ShardMergeIterator { left: Box::new(src1), right: Box::new(src), - comparer: cmp, + comparer: cmp_fn, ..ShardMergeIterator::default() }) } @@ -129,20 +130,13 @@ } // Recursively build the merge tree from the leaves. - ShardMergeIterator::merge(merged, cmp) - } - - fn compare(&self, a: &T, b: &T) -> Ordering { - match self.comparer { - None => a.cmp(b), - Some(f) => f(a, b), - } + ShardMergeIterator::merge(merged, cmp_fn) } /// Merge multiple ShardMergeIterators, recursively (meaning it will result in a more or less /// balanced merge sort tree). fn merge(mut its: Vec<ShardMergeIterator<'a, T>>, - cmp: Option<sort::Comparer<T>>) + cmp: sort::Comparer<T>) -> ShardMergeIterator<'a, T> where T: 'a {
--- a/src/sort.rs Fri Feb 05 21:38:25 2016 +0000 +++ b/src/sort.rs Fri Feb 05 21:48:31 2016 +0000 @@ -2,12 +2,61 @@ #![allow(dead_code)] -use std::cmp::Ordering; +use std::cmp::{Ord, Ordering}; /// Function type to be used as custom compare function /// (rust's standard String comparison is based on ASCII values, not dictionary order) pub type Comparer<T> = fn(a: &T, b: &T) -> Ordering; +/// Comparer<T: Ord> +#[inline] +pub fn default_generic_compare<T: Ord>(a: &T, b: &T) -> Ordering { + a.cmp(b) +} + +/// Compares a with b in a totally case insensitive manner +/// (like coreutil sort) +#[inline] +pub fn dict_string_compare(a: &String, b: &String) -> Ordering { + let (mut charsa, mut charsb) = (a.chars(), b.chars()); + loop { + match (charsa.next(), charsb.next()) { + (None, None) => return Ordering::Equal, + (_, None) => return Ordering::Greater, + (None, _) => return Ordering::Less, + (Some(ca), Some(cb)) => { + let cmp = dict_char_compare(ca, cb); + if cmp != Ordering::Equal { + return cmp; + } else { + continue; + } + } + } + } +} + +/// Compares a with b in dictionary order (case insensitive) +#[inline] +pub fn sane_string_compare(a: &String, b: &String) -> Ordering { + let (mut charsa, mut charsb) = (a.chars(), b.chars()); + loop { + match (charsa.next(), charsb.next()) { + (None, None) => return Ordering::Equal, + (_, None) => return Ordering::Greater, + (None, _) => return Ordering::Less, + (Some(ca), Some(cb)) => { + let cmp = sane_char_compare(ca, cb); + if cmp != Ordering::Equal { + return cmp; + } else { + continue; + } + } + } + } +} + #[inline] fn sane_char_compare(a: char, b: char) -> Ordering { use std::ascii::AsciiExt; @@ -33,46 +82,3 @@ // denormalize case to lower case a.to_ascii_lowercase().cmp(&b.to_ascii_lowercase()) } - -/// Compares a with b in a totally case insensitive manner -/// (like coreutil sort) -#[inline] -fn dict_string_compare(a: &String, b: &String) -> Ordering { - let (mut charsa, mut charsb) = (a.chars(), b.chars()); - loop { - match (charsa.next(), charsb.next()) { - (None, None) => return Ordering::Equal, - (_, None) => return Ordering::Greater, - (None, _) => return Ordering::Less, - (Some(ca), Some(cb)) => { - let cmp = dict_char_compare(ca, cb); - if cmp != Ordering::Equal { - return cmp; - } else { - continue; - } - } - } - } -} - -/// Compares a with b in dictionary order (case insensitive) -#[inline] -fn sane_string_compare(a: &String, b: &String) -> Ordering { - let (mut charsa, mut charsb) = (a.chars(), b.chars()); - loop { - match (charsa.next(), charsb.next()) { - (None, None) => return Ordering::Equal, - (_, None) => return Ordering::Greater, - (None, _) => return Ordering::Less, - (Some(ca), Some(cb)) => { - let cmp = sane_char_compare(ca, cb); - if cmp != Ordering::Equal { - return cmp; - } else { - continue; - } - } - } - } -}