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}