seekable_iterator/
cursor.rs

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