seekable_iterator/
cursor.rs

1use crate::{
2    lending_iterator_support::{LendItem, LentItem},
3    pooled::{OutOfBuffers, PooledIterator},
4};
5#[cfg(feature = "lender")]
6use crate::lender_adapter::LenderAdapter;
7#[cfg(feature = "lending-iterator")]
8use crate::lending_iterator_adapter::LendingIteratorAdapter;
9
10
11/// A `CursorIterator` provides access to the entries of some sorted collection, and can move its
12/// current position in either direction.
13///
14/// Conceptually, it is circular, and its initial position is before the first entry and after the
15/// last entry. As such, it is not a [`FusedIterator`], as continuing to call `next()` at the
16/// end of iteration wraps around to the start. (Note that if the collection is empty, then the
17/// iterator will remain at that phantom position.)
18///
19/// Implementations may or may not be threadsafe. Even if an implementation is threadsafe,
20/// newly-added entries may or may not be seen immediately by other threads.
21///
22/// Forwards iteration should be preferred over backwards iteration.
23///
24/// [`FusedIterator`]: core::iter::FusedIterator
25pub trait CursorIterator: Iterator {
26    /// Determine whether the iterator is currently at any value in the collection.
27    /// If the iterator is invalid, then it is conceptually one position before the first entry
28    /// and one position after the last entry. (Or, there may be no entries.)
29    ///
30    /// [`current()`] will be `Some` if and only if the iterator is valid.
31    ///
32    /// [`current()`]: CursorIterator::current
33    #[must_use]
34    fn valid(&self) -> bool;
35
36    /// Get the current value the iterator is at, if the iterator is [valid].
37    ///
38    /// [valid]: CursorIterator::valid
39    #[must_use]
40    fn current(&self) -> Option<Self::Item>;
41
42    /// Move the iterator one position back, and return the entry at that position.
43    /// Returns `None` if the iterator was at the first entry.
44    ///
45    /// Some implementations may have worse performance for backwards iteration than forwards
46    /// iteration, so prefer to not use `prev`.
47    fn prev(&mut self) -> Option<Self::Item>;
48}
49
50/// A `CursorLendingIterator` provides access to the entries of some sorted collection, and can
51/// move its current position in either direction.
52///
53/// As a lending iterator, only one entry can be accessed at a time.
54///
55/// Conceptually, it is circular, and its initial position is before the first entry and after the
56/// last entry. As such, it is not a [`FusedIterator`], as continuing to call `next()` at the
57/// end of iteration wraps around to the start. (Note that if the collection is empty, then the
58/// iterator will remain at that phantom position.)
59///
60/// Implementations may or may not be threadsafe. Even if an implementation is threadsafe,
61/// newly-added entries may or may not be seen immediately by other threads.
62///
63/// Forwards iteration should be preferred over backwards iteration.
64///
65/// [`FusedIterator`]: core::iter::FusedIterator
66pub trait CursorLendingIterator: for<'a> LendItem<'a> {
67    /// Determine whether the iterator is currently at any value in the collection.
68    /// If the iterator is invalid, then it is conceptually one position before the first entry
69    /// and one position after the last entry. (Or, there may be no entries.)
70    ///
71    /// [`current()`] will be `Some` if and only if the iterator is valid.
72    ///
73    /// [`current()`]: CursorLendingIterator::current
74    #[must_use]
75    fn valid(&self) -> bool;
76
77    /// Move the iterator one position forwards, and return the entry at that position.
78    /// Returns `None` if the iterator was at the last entry.
79    fn next(&mut self) -> Option<LentItem<'_, Self>>;
80
81    /// Get the current value the iterator is at, if the iterator is [valid].
82    ///
83    /// [valid]: CursorLendingIterator::valid
84    #[must_use]
85    fn current(&self) -> Option<LentItem<'_, Self>>;
86
87    /// Move the iterator one position back, and return the entry at that position.
88    /// Returns `None` if the iterator was at the first entry.
89    ///
90    /// Some implementations may have worse performance for backwards iteration than forwards
91    /// iteration, so prefer to not use `prev`.
92    fn prev(&mut self) -> Option<LentItem<'_, Self>>;
93
94    /// Convert the `CursorLendingIterator` into a [`lender::Lender`] lending iterator.
95    ///
96    /// The seekability and access to cursor methods are preserved, though none of the
97    /// `Cursor*Iterator` or `Seekable*Iterator` traits are implemented for the adaptor, in order
98    /// to avoid conflicts with the `next()` method name.
99    #[cfg(feature = "lender")]
100    #[inline]
101    #[must_use]
102    fn into_lender(self) -> LenderAdapter<Self> where Self: Sized {
103        LenderAdapter::new(self)
104    }
105
106    /// Convert the `CursorLendingIterator` into a [`lending_iterator::LendingIterator`].
107    ///
108    /// The seekability and access to cursor methods are preserved, though none of the
109    /// `Cursor*Iterator` or `Seekable*Iterator` traits are implemented for the adaptor, in order
110    /// to avoid conflicts with the `next()` method name.
111    #[cfg(feature = "lending-iterator")]
112    #[inline]
113    #[must_use]
114    fn into_lending_iterator(self) -> LendingIteratorAdapter<Self> where Self: Sized {
115        LendingIteratorAdapter::new(self)
116    }
117}
118
119/// A `CursorPooledIterator` provides access to the entries of some sorted collection, and can
120/// move its current position in either direction.
121///
122/// The iterator is similar to a lending iterator (which can lend one item at a time), but can
123/// make use of a buffer pool to lend out multiple items at a time.
124///
125/// Conceptually, it is circular, and its initial position is before the first entry and after the
126/// last entry. As such, it is not a [`FusedIterator`], as continuing to call `next()` at the
127/// end of iteration wraps around to the start. (Note that if the collection is empty, then the
128/// iterator will remain at that phantom position.)
129///
130/// Implementations may or may not be threadsafe. Even if an implementation is threadsafe,
131/// newly-added entries may or may not be seen immediately by other threads.
132///
133/// Forwards iteration should be preferred over backwards iteration.
134///
135/// [`FusedIterator`]: core::iter::FusedIterator
136pub trait CursorPooledIterator: PooledIterator {
137    /// Determine whether the iterator is currently at any value in the collection.
138    /// If the iterator is invalid, then it is conceptually one position before the first entry
139    /// and one position after the last entry. (Or, there may be no entries.)
140    ///
141    /// [`current()`] will be `Some` if and only if the iterator is valid.
142    ///
143    /// [`current()`]: CursorPooledIterator::current
144    #[must_use]
145    fn valid(&self) -> bool;
146
147    /// Get the current value the iterator is at, if the iterator is [valid].
148    ///
149    /// May need to wait for a buffer to become available.
150    ///
151    /// # Potential Panics or Deadlocks
152    /// If `self.buffer_pool_size() == 0`, then this method is permitted to panic or deadlock.
153    /// This method may also panic or cause a deadlock if no buffers are currently available, and
154    /// the current thread needs to make progress in order to release a buffer.
155    ///
156    /// If it is possible for a different thread to make progress and make a buffer available,
157    /// this method should not panic or deadlock.
158    ///
159    /// [valid]: CursorPooledIterator::valid
160    #[must_use]
161    fn current(&self) -> Option<Self::Item>;
162
163    /// Move the iterator one position back, and return the entry at that position.
164    /// Returns `None` if the iterator was at the first entry.
165    ///
166    /// May need to wait for a buffer to become available.
167    ///
168    /// Some implementations may have worse performance for backwards iteration than forwards
169    /// iteration, so prefer to not use `prev`.
170    ///
171    /// # Potential Panics or Deadlocks
172    /// If `self.buffer_pool_size() == 0`, then this method is permitted to panic or deadlock.
173    /// This method may also panic or cause a deadlock if no buffers are currently available, and
174    /// the current thread needs to make progress in order to release a buffer.
175    ///
176    /// If it is possible for a different thread to make progress and make a buffer available,
177    /// this method should not panic or deadlock.
178    fn prev(&mut self) -> Option<Self::Item>;
179
180    /// If a buffer is available, get the current value the iterator is at, if the iterator is
181    /// [valid].
182    ///
183    /// # Errors
184    /// Returns an error if no buffers were available.
185    ///
186    /// [valid]: CursorPooledIterator::valid
187    fn try_current(&self) -> Result<Option<Self::Item>, OutOfBuffers>;
188
189    /// If a buffer is available, move the iterator one position back, and return the entry at
190    /// that position. Returns `Ok(None)` if the iterator was at the first entry.
191    ///
192    /// Some implementations may have worse performance for backwards iteration than forwards
193    /// iteration, so prefer to not use `try_prev`.
194    ///
195    /// # Errors
196    /// Returns an error if no buffers were available.
197    fn try_prev(&mut self) -> Result<Option<Self::Item>, OutOfBuffers>;
198}