extsort_iter/extension_trait/
sequential.rs

1use std::{
2    cmp::Ordering,
3    io::{self, Read},
4};
5
6use crate::{
7    orderer::{FuncOrderer, KeyOrderer, OrdOrderer, Orderer},
8    run::{file_run::ExternalRun, Run},
9    sorter::{
10        self, buffer_cleaner::sequential::SingleThreadedBufferCleaner, result_iter::ResultIterator,
11        ExtsortConfig,
12    },
13};
14
15pub trait ExtSortOrdExtension: Iterator {
16    /// Sorts the provided Iterator according to the provided config
17    /// using the native ordering on the type to sort
18    /// # Errors
19    /// This function may error if a sort file fails to be written.
20    /// In this case the library will do its best to clean up the
21    /// already written files, but no guarantee is made.
22    fn external_sort(
23        self,
24        options: ExtsortConfig,
25    ) -> io::Result<ResultIterator<Self::Item, OrdOrderer>>;
26}
27
28fn buffer_sort<T>(orderer: &impl Orderer<T>, buffer: &mut [T]) {
29    buffer.sort_unstable_by(|a, b| orderer.compare(a, b));
30}
31
32fn run<T, O>(
33    source: impl Iterator<Item = T>,
34    options: ExtsortConfig,
35    orderer: O,
36) -> io::Result<ResultIterator<T, O>>
37where
38    O: Orderer<T>,
39{
40    let cleaner = SingleThreadedBufferCleaner::new(options, orderer, buffer_sort);
41    sorter::ExtSorter::new().run(source, cleaner)
42}
43
44impl<I, T> ExtSortOrdExtension for I
45where
46    I: Iterator<Item = T>,
47    T: Ord,
48{
49    fn external_sort(
50        self,
51        options: ExtsortConfig,
52    ) -> io::Result<ResultIterator<Self::Item, OrdOrderer>> {
53        run(self, options, OrdOrderer::new())
54    }
55}
56
57pub trait ExtSortByExtension: Iterator {
58    type Run: Run<Self::Item>;
59    /// Sorts the provided Iterator according to the provided config
60    /// using a custom comparator function
61    /// # Errors
62    /// This function may error if a sort file fails to be written.
63    /// In this case the library will do its best to clean up the
64    /// already written files, but no guarantee is made.
65    fn external_sort_by<F>(
66        self,
67        options: ExtsortConfig,
68        comparator: F,
69    ) -> io::Result<ResultIterator<Self::Item, FuncOrderer<F>>>
70    where
71        F: Fn(&Self::Item, &Self::Item) -> Ordering;
72
73    /// Sorts the provided Iterator according to the provided config
74    /// using a key extraction function.
75    /// # Errors
76    /// This function may error if a sort file fails to be written.
77    /// In this case the library will do its best to clean up the
78    /// already written files, but no guarantee is made.
79    fn external_sort_by_key<F, K>(
80        self,
81        options: ExtsortConfig,
82        key_extractor: F,
83    ) -> io::Result<ResultIterator<Self::Item, KeyOrderer<F>>>
84    where
85        F: Fn(&Self::Item) -> K,
86        K: Ord;
87}
88
89impl<I, T> ExtSortByExtension for I
90where
91    I: Iterator<Item = T>,
92{
93    type Run = ExternalRun<T, Box<dyn Read + Send>>;
94
95    fn external_sort_by<F>(
96        self,
97        options: ExtsortConfig,
98        comparator: F,
99    ) -> io::Result<ResultIterator<Self::Item, FuncOrderer<F>>>
100    where
101        F: Fn(&Self::Item, &Self::Item) -> Ordering,
102    {
103        run(self, options, FuncOrderer::new(comparator))
104    }
105
106    fn external_sort_by_key<F, K>(
107        self,
108        options: ExtsortConfig,
109        key_extractor: F,
110    ) -> io::Result<ResultIterator<Self::Item, KeyOrderer<F>>>
111    where
112        F: Fn(&Self::Item) -> K,
113        K: Ord,
114    {
115        run(self, options, KeyOrderer::new(key_extractor))
116    }
117}