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}