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;
-                }
-            }
-        }
-    }
-}