seekable_iterator/
pooled.rs

1use core::error::Error;
2use core::fmt::{Display, Formatter, Result as FmtResult};
3
4#[cfg(feature = "lender")]
5use crate::lender_adapter::PooledLenderAdapter;
6#[cfg(feature = "lending-iterator")]
7use crate::lending_iterator_adapter::PooledLendingIteratorAdapter;
8
9
10/// A `PooledIterator` is similar to a lending iterator (which can lend one item at a time), but
11/// can make use of a buffer pool to lend out multiple items at a time.
12///
13/// Implementations may or may not be threadsafe. Even if an implementation is threadsafe,
14/// items newly-added to the backing collection of the iterator may or may not be seen
15/// immediately by other threads.
16///
17/// [`FusedIterator`]: core::iter::FusedIterator
18pub trait PooledIterator {
19    /// The item of this iterator, which likely has a nontrivial drop implementation that returns
20    /// a buffer to the iterator's buffer pool.
21    type Item;
22
23    /// Move the iterator one position forwards, and return the entry at that position.
24    /// Returns `None` if the iterator was at the last entry.
25    ///
26    /// May need to wait for a buffer to become available.
27    ///
28    /// # Potential Panics or Deadlocks
29    /// If `self.buffer_pool_size() == 0`, then this method may panic or deadlock.
30    fn next(&mut self) -> Option<Self::Item>;
31
32    /// If a buffer is available, move the iterator one position forwards, and return the entry at
33    /// that position. Returns `Ok(None)` if the iterator was at the last entry.
34    ///
35    /// # Errors
36    /// Returns an error if no buffers were available.
37    fn try_next(&mut self) -> Result<Option<Self::Item>, OutOfBuffers>;
38
39    /// Get the total number of buffers in the buffer pool, including buffers that are
40    /// currently in use.
41    #[must_use]
42    fn buffer_pool_size(&self) -> usize;
43
44    /// Get the number of buffers that are currently available.
45    ///
46    /// In multithreaded scenarios, the returned value could change at any time.
47    #[must_use]
48    fn available_buffers(&self) -> usize;
49
50    /// Convert the `PooledIterator` into a [`lender::Lender`] lending iterator which only uses
51    /// one buffer at a time.
52    ///
53    /// The seekability and access to cursor methods are preserved, though none of the
54    /// `Cursor*Iterator` or `Seekable*Iterator` traits are implemented for the adaptor, in order
55    /// to avoid conflicts with the `next()` method name.
56    ///
57    /// # Potential Panics or Deadlocks
58    /// If `self.buffer_pool_size() == 0`, then methods of the returned iterator might panic or
59    /// deadlock.
60    #[cfg(feature = "lender")]
61    #[inline]
62    #[must_use]
63    fn into_lender(self) -> PooledLenderAdapter<Self> where Self: Sized {
64        PooledLenderAdapter::new(self)
65    }
66
67    /// Convert the `PooledIterator` into a [`lending_iterator::LendingIterator`] which only uses
68    /// one buffer at a time.
69    ///
70    /// The seekability and access to cursor methods are preserved, though none of the
71    /// `Cursor*Iterator` or `Seekable*Iterator` traits are implemented for the adaptor, in order
72    /// to avoid conflicts with the `next()` method name.
73    ///
74    /// # Potential Panics or Deadlocks
75    /// If `self.buffer_pool_size() == 0`, then methods of the returned iterator might panic or
76    /// deadlock.
77    #[cfg(feature = "lending-iterator")]
78    #[inline]
79    #[must_use]
80    fn into_lending_iterator(self) -> PooledLendingIteratorAdapter<Self> where Self: Sized {
81        PooledLendingIteratorAdapter::new(self)
82    }
83}
84
85/// An error that may be returned if no buffer pools were available in a [`PooledIterator`],
86/// instead of waiting for a buffer to become available.
87#[derive(Debug, Clone, Copy)]
88pub struct OutOfBuffers;
89
90impl Display for OutOfBuffers {
91    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
92        write!(
93            f,
94            "a pooled iterator operation was not performed because there were no buffers available",
95        )
96    }
97}
98
99impl Error for OutOfBuffers {}