1use core::{
2 borrow::{Borrow, BorrowMut},
3 ops::{Deref, DerefMut},
4};
5use alloc::borrow::ToOwned;
6
7use anchored_pool::{PooledResource, ResetNothing, ResourcePoolEmpty, BoundedPool};
8
9use crate::{comparator::Comparator, lending_iterator_support::LentItem, seekable::Seekable};
10use crate::{
11 pooled::{OutOfBuffers, PooledIterator},
12 cursor::{CursorLendingIterator, CursorPooledIterator},
13};
14
15
16#[derive(Debug)]
30#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
31pub struct PooledIter<I, BorrowedItem: ToOwned> {
32 iter: I,
33 pool: BoundedPool<BorrowedItem::Owned, ResetNothing>,
34}
35
36impl<I, BorrowedItem> PooledIter<I, BorrowedItem>
37where
38 BorrowedItem: ToOwned,
39 BorrowedItem::Owned: Default,
40{
41 #[must_use]
49 pub fn new(iter: I, num_buffers: usize) -> Self {
50 let pool = BoundedPool::new_default_without_reset(num_buffers);
51
52 Self { iter, pool }
53 }
54}
55
56impl<I, BorrowedItem> PooledIter<I, BorrowedItem>
57where
58 I: CursorLendingIterator,
59 BorrowedItem: ToOwned,
60 for<'lend> LentItem<'lend, I>: Borrow<BorrowedItem>,
61{
62 #[expect(clippy::needless_pass_by_value, reason = "lent item usually consists of references")]
65 #[inline]
66 fn fill_buffer(
67 pool: &BoundedPool<BorrowedItem::Owned, ResetNothing>,
68 item: LentItem<'_, I>,
69 ) -> PoolItem<BorrowedItem::Owned> {
70 let mut pool_item = pool.get();
71 item.borrow().clone_into(&mut pool_item);
72 PoolItem(pool_item)
73 }
74}
75
76impl<I, BorrowedItem> PooledIterator for PooledIter<I, BorrowedItem>
77where
78 I: CursorLendingIterator,
79 BorrowedItem: ToOwned,
80 for<'lend> LentItem<'lend, I>: Borrow<BorrowedItem>,
81{
82 type Item = PoolItem<BorrowedItem::Owned>;
83
84 fn next(&mut self) -> Option<Self::Item> {
90 self.iter.next().map(|item| Self::fill_buffer(&self.pool, item))
91 }
92
93 fn try_next(&mut self) -> Result<Option<Self::Item>, OutOfBuffers> {
94 let mut buffer = self.pool.try_get()
95 .map_err(|ResourcePoolEmpty| OutOfBuffers)?;
96
97 if let Some(item) = self.iter.next() {
98 item.borrow().clone_into(&mut buffer);
99 Ok(Some(PoolItem(buffer)))
100 } else {
101 Ok(None)
102 }
103 }
104
105 #[inline]
106 fn buffer_pool_size(&self) -> usize {
107 self.pool.pool_size()
108 }
109
110 fn available_buffers(&self) -> usize {
111 self.pool.available_resources()
112 }
113}
114
115impl<I, BorrowedItem> CursorPooledIterator for PooledIter<I, BorrowedItem>
116where
117 I: CursorLendingIterator,
118 BorrowedItem: ToOwned,
119 for<'lend> LentItem<'lend, I>: Borrow<BorrowedItem>,
120{
121 #[inline]
122 fn valid(&self) -> bool {
123 self.iter.valid()
124 }
125
126 #[inline]
133 fn current(&self) -> Option<Self::Item> {
134 self.iter.current().map(|item| Self::fill_buffer(&self.pool, item))
135 }
136
137 fn try_current(&self) -> Result<Option<Self::Item>, OutOfBuffers> {
138 let mut buffer = self.pool.try_get()
139 .map_err(|ResourcePoolEmpty| OutOfBuffers)?;
140
141 if let Some(item) = self.iter.current() {
142 item.borrow().clone_into(&mut buffer);
143 Ok(Some(PoolItem(buffer)))
144 } else {
145 Ok(None)
146 }
147 }
148
149 fn prev(&mut self) -> Option<Self::Item> {
158 self.iter.prev().map(|item| Self::fill_buffer(&self.pool, item))
159 }
160
161 fn try_prev(&mut self) -> Result<Option<Self::Item>, OutOfBuffers> {
162 let mut buffer = self.pool.try_get()
163 .map_err(|ResourcePoolEmpty| OutOfBuffers)?;
164
165 if let Some(item) = self.iter.prev() {
166 item.borrow().clone_into(&mut buffer);
167 Ok(Some(PoolItem(buffer)))
168 } else {
169 Ok(None)
170 }
171 }
172}
173
174impl<I, BorrowedItem, Key, Cmp> Seekable<Key, Cmp> for PooledIter<I, BorrowedItem>
175where
176 I: CursorLendingIterator + Seekable<Key, Cmp>,
177 BorrowedItem: ToOwned,
178 Key: ?Sized,
179 Cmp: Comparator<Key>,
180 for<'lend> LentItem<'lend, I>: Borrow<BorrowedItem>,
181{
182 #[inline]
183 fn reset(&mut self) {
184 self.iter.reset();
185 }
186
187 fn seek(&mut self, min_bound: &Key) {
188 self.iter.seek(min_bound);
189 }
190
191 fn seek_before(&mut self, strict_upper_bound: &Key) {
192 self.iter.seek_before(strict_upper_bound);
193 }
194
195 #[inline]
196 fn seek_to_first(&mut self) {
197 self.iter.seek_to_first();
198 }
199
200 fn seek_to_last(&mut self) {
201 self.iter.seek_to_last();
202 }
203}
204
205#[derive(Debug)]
209#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
210pub struct PoolItem<OwnedItem>(
211 PooledResource<BoundedPool<OwnedItem, ResetNothing>, OwnedItem>,
212);
213
214impl<OwnedItem> Deref for PoolItem<OwnedItem> {
215 type Target = OwnedItem;
216
217 #[inline]
218 fn deref(&self) -> &Self::Target {
219 &self.0
220 }
221}
222
223impl<OwnedItem> DerefMut for PoolItem<OwnedItem> {
224 #[inline]
225 fn deref_mut(&mut self) -> &mut Self::Target {
226 &mut self.0
227 }
228}
229
230impl<OwnedItem> Borrow<OwnedItem> for PoolItem<OwnedItem> {
231 #[inline]
232 fn borrow(&self) -> &OwnedItem {
233 self
234 }
235}
236
237impl<OwnedItem> BorrowMut<OwnedItem> for PoolItem<OwnedItem> {
238 #[inline]
239 fn borrow_mut(&mut self) -> &mut OwnedItem {
240 self
241 }
242}
243
244impl<OwnedItem> AsRef<OwnedItem> for PoolItem<OwnedItem> {
245 #[inline]
246 fn as_ref(&self) -> &OwnedItem {
247 self
248 }
249}
250
251impl<OwnedItem> AsMut<OwnedItem> for PoolItem<OwnedItem> {
252 #[inline]
253 fn as_mut(&mut self) -> &mut OwnedItem {
254 self
255 }
256}
257
258
259#[cfg(test)]
260mod tests {
261 use crate::test_iter::TestIter;
262 use super::*;
263
264
265 #[test]
266 fn pooled_test_iter() {
267 let data: &[u8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].as_slice();
268 let mut iter = PooledIter::<_, u8>::new(TestIter::new(data).unwrap(), 2);
269
270 let first = iter.next().unwrap();
272 assert_eq!(*first, 0);
273
274 for i in 1..=9 {
275 assert!(iter.valid());
276 let next = iter.next().unwrap();
277 assert!(iter.try_next().is_err());
279 assert_eq!(*next, i);
280 }
281 drop(first);
282
283 assert!(iter.next().is_none());
284
285 for i in (0..=9).rev() {
286 let current = iter.current();
287 let prev = iter.prev().unwrap();
288
289 if current.is_some() {
290 assert!(iter.try_next().is_err());
292 }
293
294 assert!(iter.valid());
295
296 assert!(!current.is_some_and(|curr| *curr == *prev));
298
299 let new_current = iter.current().unwrap();
300
301 assert_eq!(*prev, i);
302 assert_eq!(*new_current, i);
303 }
304 }
305
306 #[test]
307 fn seek_test() {
308 let data: &[u8] = [0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 99].as_slice();
309 let mut iter = PooledIter::<_, u8>::new(TestIter::new(data).unwrap(), 1);
310
311 iter.seek_to_first();
312 assert_eq!(*iter.current().unwrap(), 0);
313
314 iter.seek(&0);
315 assert_eq!(*iter.current().unwrap(), 0);
316
317 iter.seek(&1);
318 assert_eq!(*iter.current().unwrap(), 1);
319
320 iter.seek(&9);
321 assert_eq!(*iter.current().unwrap(), 9);
322
323 iter.seek(&8);
324 assert_eq!(*iter.current().unwrap(), 8);
325
326 iter.seek(&10);
327 assert_eq!(*iter.current().unwrap(), 99);
328
329 iter.seek_before(&92);
330 assert_eq!(*iter.current().unwrap(), 9);
331
332 iter.seek_before(&99);
333 assert_eq!(*iter.current().unwrap(), 9);
334
335 iter.seek_before(&100);
336 assert_eq!(*iter.current().unwrap(), 99);
337
338 iter.seek_before(&1);
339 assert_eq!(*iter.current().unwrap(), 0);
340
341 iter.seek_before(&0);
342 assert!(!iter.valid());
343
344 iter.seek(&100);
345 assert!(!iter.valid());
346
347 iter.seek(&99);
348 assert_eq!(*iter.current().unwrap(), 99);
349
350 iter.seek_to_last();
351 assert_eq!(*iter.current().unwrap(), 99);
352
353 iter.seek_before(&4);
354 assert_eq!(*iter.current().unwrap(), 3);
355 }
356}