use rand; use serde::{Deserialize, Serialize}; use std::env; use std::fs; use external_sort::{ExternalSorter, ExternallySortable}; #[derive(Serialize, Deserialize, Clone, PartialEq, Eq, PartialOrd, Ord)] struct Num { the_num: u8, } impl Num { fn new(num: u8) -> Num { Num { the_num: num } } } impl ExternallySortable for Num { fn get_size(&self) -> u64 { 1 } } #[test] fn sort() { let unsorted = vec![ Num::new(5), Num::new(2), Num::new(1), Num::new(3), Num::new(4), ]; let sorted = vec![ Num::new(1), Num::new(2), Num::new(3), Num::new(4), Num::new(5), ]; let iter = ExternalSorter::new(2, None) .sort(unsorted.into_iter()) .unwrap(); for (idx, i) in iter.enumerate() { assert_eq!(i.unwrap().the_num, sorted[idx].the_num); } } #[test] fn reverse() { let unsorted = vec![ Num::new(5), Num::new(2), Num::new(1), Num::new(3), Num::new(4), ]; let sorted = vec![ Num::new(5), Num::new(4), Num::new(3), Num::new(2), Num::new(1), ]; let iter = ExternalSorter::new(16, None) .sort_by(unsorted.into_iter(), |a, b| b.cmp(a)) .unwrap(); for (idx, i) in iter.enumerate() { assert_eq!(i.unwrap().the_num, sorted[idx].the_num); } } #[test] fn zero_buff() { let unsorted = vec![ Num::new(5), Num::new(2), Num::new(1), Num::new(3), Num::new(4), ]; let sorted = vec![ Num::new(1), Num::new(2), Num::new(3), Num::new(4), Num::new(5), ]; let iter = ExternalSorter::new(0, None) .sort(unsorted.into_iter()) .unwrap(); for (idx, i) in iter.enumerate() { assert_eq!(i.unwrap().the_num, sorted[idx].the_num); } } #[test] fn large_buff() { let unsorted = vec![ Num::new(5), Num::new(2), Num::new(1), Num::new(3), Num::new(4), ]; let sorted = vec![ Num::new(1), Num::new(2), Num::new(3), Num::new(4), Num::new(5), ]; let iter = ExternalSorter::new(999999999, None) .sort(unsorted.into_iter()) .unwrap(); for (idx, i) in iter.enumerate() { assert_eq!(i.unwrap().the_num, sorted[idx].the_num); } } #[test] fn reuse() { let unsorted = vec![ Num::new(5), Num::new(2), Num::new(1), Num::new(3), Num::new(4), ]; let sorted = vec![ Num::new(1), Num::new(2), Num::new(3), Num::new(4), Num::new(5), ]; let iter = ExternalSorter::new(2, None) .sort(unsorted.clone().into_iter()) .unwrap(); for (idx, i) in iter.enumerate() { assert_eq!(i.unwrap().the_num, sorted[idx].the_num); } let iter2 = ExternalSorter::new(2, None) .sort(unsorted.into_iter()) .unwrap(); for (idx, i) in iter2.enumerate() { assert_eq!(i.unwrap().the_num, sorted[idx].the_num); } } #[test] fn large() { let mut unsorted = Vec::new(); for _ in 0..10_000 { unsorted.push(Num::new(rand::random())); } let iter = ExternalSorter::new(100, None) .sort(unsorted.into_iter()) .unwrap(); let mut last = 0; for i in iter { let n = i.unwrap().the_num; assert!(n >= last); last = n; } } #[test] fn handle_fail() { let mut unsorted = Vec::new(); for _ in 0..10_000 { unsorted.push(Num::new(rand::random())); } let r = env::temp_dir().join("external_sort_test"); fs::create_dir_all(r.clone()).unwrap(); let iter = ExternalSorter::new(100, Some(r.clone())) .sort(unsorted.into_iter()) .unwrap(); fs::remove_dir_all(r.clone()).unwrap(); let mut fail = false; for i in iter { if i.is_err() { fail = true; } } assert!(fail); }