use std::{cmp::Ordering, io::Error, path::PathBuf};
use crate::{iter::SortedIterator, push::PushExternalSorter, ExternalSorterOptions, Sortable};
pub struct ExternalSorter {
options: ExternalSorterOptions,
}
impl ExternalSorter {
pub fn new() -> ExternalSorter {
ExternalSorter {
options: ExternalSorterOptions::default(),
}
}
pub fn with_segment_size(mut self, size: usize) -> Self {
self.options.segment_size = size;
self
}
pub fn with_sort_dir(mut self, path: PathBuf) -> Self {
self.options.sort_dir = Some(path);
self
}
pub fn with_parallel_sort(mut self) -> Self {
self.options.parallel = true;
self
}
pub fn with_heap_iter_segment_count(mut self, count: usize) -> Self {
self.options.heap_iter_segment_count = count;
self
}
pub fn sort<T, I>(
self,
iterator: I,
) -> Result<SortedIterator<T, impl Fn(&T, &T) -> Ordering + Send + Sync + Clone>, Error>
where
T: Sortable + Ord,
I: IntoIterator<Item = T>,
{
self.sort_by(iterator, |a, b| a.cmp(b))
}
pub fn sort_by_key<T, I, F, K>(
self,
iterator: I,
f: F,
) -> Result<SortedIterator<T, impl Fn(&T, &T) -> Ordering + Send + Sync + Clone>, Error>
where
T: Sortable,
I: IntoIterator<Item = T>,
F: Fn(&T) -> K + Send + Sync + Clone,
K: Ord,
{
self.sort_by(iterator, move |a, b| f(a).cmp(&f(b)))
}
pub fn sort_by<T, I, F>(self, iterator: I, cmp: F) -> Result<SortedIterator<T, F>, Error>
where
T: Sortable,
I: IntoIterator<Item = T>,
F: Fn(&T, &T) -> Ordering + Send + Sync + Clone,
{
let mut sorter = PushExternalSorter::new(self.options, cmp);
sorter.push_iter(iterator)?;
sorter.done()
}
pub fn pushed<T>(
self,
) -> PushExternalSorter<T, impl Fn(&T, &T) -> Ordering + Send + Sync + Clone>
where
T: Sortable + Ord,
{
self.pushed_by::<T, _>(|a, b| a.cmp(b))
}
pub fn pushed_by<T, F>(self, cmp: F) -> PushExternalSorter<T, F>
where
T: Sortable,
F: Fn(&T, &T) -> Ordering + Send + Sync + Clone,
{
PushExternalSorter::new(self.options, cmp)
}
pub fn pushed_by_key<T, F, K>(
self,
f: F,
) -> PushExternalSorter<T, impl Fn(&T, &T) -> Ordering + Send + Sync + Clone>
where
T: Sortable,
F: Fn(&T) -> K + Send + Sync + Clone,
K: Ord,
{
self.pushed_by(move |a, b| f(a).cmp(&f(b)))
}
}
impl Default for ExternalSorter {
fn default() -> Self {
ExternalSorter::new()
}
}