dataloader_rs/loader/
iter.rs1#[cfg(feature = "python")]
4use std::time::{Duration, Instant};
5
6use crate::{
7 collator::Collator,
8 error::{Error, Result},
9 loader::source::LoaderSource,
10 transform::{Identity, Transform},
11};
12
13pub(super) fn forked() -> Error {
16 "this epoch was started before fork(); start a new one in this process (iter())".into()
17}
18
19pub trait BatchStream<B> {
22 fn next(&mut self) -> Option<Result<B>>;
24
25 fn len(&self) -> usize;
27
28 #[cfg(feature = "python")]
31 fn next_until(&mut self, deadline: Option<Instant>) -> Option<Option<Result<B>>>;
32
33 #[cfg(feature = "python")]
36 fn stop(&mut self, timeout: Duration) -> bool;
37}
38
39pub struct DataLoaderIter<Src, C, T = Identity>
46where
47 Src: LoaderSource,
48 T: Transform<Src::Item>,
49 C: Collator<T::Output>,
50{
51 epoch: Src::Epoch<T, C, T::Output>,
52}
53
54impl<Src, C, T> DataLoaderIter<Src, C, T>
55where
56 Src: LoaderSource,
57 T: Transform<Src::Item>,
58 C: Collator<T::Output>,
59{
60 pub(super) fn new(epoch: Src::Epoch<T, C, T::Output>) -> Self {
61 Self { epoch }
62 }
63
64 #[cfg(feature = "python")]
68 pub(crate) fn next_until(
69 &mut self,
70 deadline: Option<Instant>,
71 ) -> Option<Option<Result<C::Batch>>> {
72 self.epoch.next_until(deadline)
73 }
74
75 #[cfg(feature = "python")]
79 pub(crate) fn stop(&mut self, timeout: Duration) -> bool {
80 self.epoch.stop(timeout)
81 }
82}
83
84impl<Src, C, T> Iterator for DataLoaderIter<Src, C, T>
85where
86 Src: LoaderSource,
87 T: Transform<Src::Item>,
88 C: Collator<T::Output>,
89{
90 type Item = Result<C::Batch>;
91
92 fn next(&mut self) -> Option<Self::Item> {
93 self.epoch.next()
94 }
95
96 fn size_hint(&self) -> (usize, Option<usize>) {
97 let n = self.epoch.len();
98 (n, Some(n))
99 }
100}
101
102impl<Src, C, T> ExactSizeIterator for DataLoaderIter<Src, C, T>
103where
104 Src: LoaderSource,
105 T: Transform<Src::Item>,
106 C: Collator<T::Output>,
107{
108}
109
110pub struct IndexedIter<Src, C, T = Identity>
116where
117 Src: LoaderSource,
118 T: Transform<Src::Item>,
119 C: Collator<T::Output>,
120{
121 indices: std::vec::IntoIter<Vec<usize>>,
122 batches: DataLoaderIter<Src, C, T>,
123}
124
125impl<Src, C, T> IndexedIter<Src, C, T>
126where
127 Src: LoaderSource,
128 T: Transform<Src::Item>,
129 C: Collator<T::Output>,
130{
131 pub(super) fn new(indices: Vec<Vec<usize>>, batches: DataLoaderIter<Src, C, T>) -> Self {
133 Self {
134 indices: indices.into_iter(),
135 batches,
136 }
137 }
138}
139
140impl<Src, C, T> Iterator for IndexedIter<Src, C, T>
141where
142 Src: LoaderSource,
143 T: Transform<Src::Item>,
144 C: Collator<T::Output>,
145{
146 type Item = Result<(Vec<usize>, C::Batch)>;
147
148 fn next(&mut self) -> Option<Self::Item> {
149 let batch = self.batches.next()?;
152 let indices = self.indices.next()?;
153 Some(batch.map(|batch| (indices, batch)))
154 }
155
156 fn size_hint(&self) -> (usize, Option<usize>) {
157 self.batches.size_hint()
158 }
159}
160
161impl<Src, C, T> ExactSizeIterator for IndexedIter<Src, C, T>
162where
163 Src: LoaderSource,
164 T: Transform<Src::Item>,
165 C: Collator<T::Output>,
166{
167}