Skip to main content

leveldb/database/
iterator.rs

1//! LevelDB iterators
2//!
3//! Iteration is one of the most important parts of LevelDB. This module provides
4//! Iterators to iterate over key, values and pairs of both.
5//!
6//! Use the `Iterable` trait methods to create iterator instances. For convenience,
7//! various Iterator type aliases are provided.
8//!
9//! Furthermore, policies can be used to control iteration behavior:
10//!
11//! ```ignore
12//! // Basic iterator with default policy
13//! let iter: KeyIterator<'_> = database.iter(ReadOptions::new());
14//!
15//! // Iterator with custom policy
16//! let policy = BoundedKeyPolicy::new(Some(start_key), Some(end_key));
17//! let bounded_iter: EntryIterator<'_, _> = database.iter_with_policy(ReadOptions::new(), policy);
18//! ```
19use super::Database;
20use super::error::Error;
21use super::options::{ReadOptions, c_readoptions};
22use super::slice::Slice;
23use crate::binding::{
24    leveldb_create_iterator, leveldb_iter_destroy, leveldb_iter_get_error, leveldb_iter_key,
25    leveldb_iter_next, leveldb_iter_prev, leveldb_iter_seek, leveldb_iter_seek_to_first,
26    leveldb_iter_seek_to_last, leveldb_iter_valid, leveldb_iter_value, leveldb_iterator_t,
27    leveldb_readoptions_destroy,
28};
29use libc::{c_char, size_t};
30use std::iter;
31use std::marker::PhantomData;
32
33#[allow(missing_docs)]
34struct RawIterator {
35    ptr: *mut leveldb_iterator_t,
36}
37
38#[allow(missing_docs)]
39impl Drop for RawIterator {
40    fn drop(&mut self) {
41        unsafe { leveldb_iter_destroy(self.ptr) }
42    }
43}
44
45/// Marker types of iterators return key only
46pub struct KeyType;
47/// Marker types of iterators return value only
48pub struct ValueType;
49/// Marker types of iterators return key & value pair
50pub struct EntryType;
51
52/// Marker types for iterating direction: front to back through block data
53pub struct Forward;
54/// Marker types for iterating direction: back to front through block data
55pub struct Backward;
56
57/// Trait for providing context for policy to make decisions
58pub trait Context<'a> {
59    /// Get the current key as a slice that borrows from the iterator
60    ///
61    /// # Safety
62    ///
63    /// ## Iterator Validity Requirement
64    /// Use `valid()` to check iterator state before calling this method.
65    ///
66    /// ## Lifetime Safety
67    /// The returned slice borrows data directly from the LevelDB iterator without copying.
68    /// The data is only valid until the iterator is advanced to the next position or destroyed.
69    ///
70    /// The caller must ensure that the returned slice does not outlive the iterator
71    /// or any operation that would advance the iterator (such as calling `next()`, `seek()`, etc.).
72    /// To keep the data longer, the slice should be cloned.
73    ///
74    /// ## Performance
75    /// This method provides zero-copy access to LevelDB data for maximum performance.
76    /// Get the current key as a slice
77    unsafe fn key(&self) -> Option<Slice<'a>>;
78
79    /// Get the current value as a slice that borrows from the iterator
80    ///
81    /// # Safety
82    ///
83    /// ## Iterator Validity Requirement
84    /// Use `valid()` to check iterator state before calling this method.
85    ///
86    /// ## Lifetime Safety
87    /// The returned slice borrows data directly from the LevelDB iterator without copying.
88    /// The data is only valid until the iterator is advanced to the next position or destroyed.
89    ///
90    /// The caller must ensure that the returned slice does not outlive the iterator
91    /// or any operation that would advance the iterator (such as calling `next()`, `seek()`, etc.).
92    /// To keep the data longer, the slice should be cloned.
93    ///
94    /// ## Performance
95    /// This method provides zero-copy access to LevelDB data for maximum performance.
96    unsafe fn value(&self) -> Option<Slice<'a>>;
97
98    /// Get the current key-value pair as slices that borrow from the iterator
99    ///
100    /// # Safety
101    ///
102    /// ## Iterator Validity Requirement
103    /// Use `valid()` to check iterator state before calling this method.
104    ///
105    /// ## Lifetime Safety
106    /// The returned slices borrow data directly from the LevelDB iterator without copying.
107    /// The data is only valid until the iterator is advanced to the next position or destroyed.
108    ///
109    /// The caller must ensure that the returned slices do not outlive the iterator
110    /// or any operation that would advance the iterator (such as calling `next()`, `seek()`, etc.).
111    /// To keep the data longer, the slice should be cloned.
112    ///
113    /// ## Performance
114    /// This method provides zero-copy access to LevelDB data for maximum performance.
115    unsafe fn entry(&self) -> Option<(Slice<'a>, Slice<'a>)>;
116}
117
118/// Trait for LevelDB iterator operations
119pub trait LevelDBIterator<'a>: Context<'a> {
120    /// Check if iterator is valid
121    fn valid(&self) -> bool;
122
123    /// Seek to specific key
124    fn seek(&self, key: &Slice);
125
126    /// Seek to the first key
127    fn seek_to_first(&self);
128
129    /// Seek to the last key
130    fn seek_to_last(&self);
131
132    /// Get the error message if the iterator is invalid
133    fn get_error(&self) -> Option<Error>;
134}
135
136/// Policy for controlling iterator behavior
137///
138/// This trait defines how iterators should behave during iteration,
139/// including when to stop and whether to seek to the beginning at start.
140pub trait Policy {
141    /// Determines if iteration should continue based on current context
142    fn should_continue(&self, context: &dyn Context) -> bool;
143
144    /// Determines if iterator should seek to beginning at start, default is true
145    fn should_seek_begin(&self) -> bool {
146        true
147    }
148}
149
150/// Default iteration policy with no bounds (iterates over all data)
151pub struct DefaultPolicy;
152
153impl DefaultPolicy {
154    pub fn new() -> Self {
155        Self
156    }
157}
158
159impl Default for DefaultPolicy {
160    fn default() -> Self {
161        Self::new()
162    }
163}
164
165impl Policy for DefaultPolicy {
166    fn should_continue(&self, _context: &dyn Context) -> bool {
167        true
168    }
169}
170
171/// Policy for bounded key iteration with from/to bounds.
172///
173/// This policy restricts iteration to a specific key range.
174///
175/// **Important**: When using `BoundedKeyPolicy`, the method `seek()` must be called explicitly
176/// before starting iteration. This policy does not automatically seek to the beginning position.
177pub struct BoundedKeyPolicy<'a> {
178    from: Option<Slice<'a>>,
179    to: Option<Slice<'a>>,
180}
181
182impl<'a> BoundedKeyPolicy<'a> {
183    pub fn new(from: Option<Slice<'a>>, to: Option<Slice<'a>>) -> Self {
184        Self { from, to }
185    }
186}
187
188impl<'a> Policy for BoundedKeyPolicy<'a> {
189    fn should_continue(&self, context: &dyn Context) -> bool {
190        if let Some(key) = unsafe { context.key() } {
191            if let Some(from) = &self.from
192                && key < *from
193            {
194                return false;
195            }
196            if let Some(to) = &self.to
197                && key >= *to
198            {
199                return false;
200            }
201        }
202        true
203    }
204
205    fn should_seek_begin(&self) -> bool {
206        false
207    }
208}
209
210/// A fully unified iterator over the LevelDB keyspace.
211///
212/// The iteration direction is determined by the generic parameters `D`.
213/// The return type is determined by the generic parameters `T`.
214/// The iteration policy is determined by parameter `P`.
215/// This provides static dispatch for direction-specific, type-specific, and policy-specific operations.
216pub struct Iterator<'a, T = KeyType, D = Forward, P = DefaultPolicy> {
217    iter: RawIterator,
218    started: bool,
219    stopped: bool,
220    policy: P,
221    // Iterator accesses the Database through a leveldb_iter_t pointer
222    // but needs to hold the reference for lifetime tracking
223    #[allow(dead_code)]
224    database: PhantomData<&'a Database>,
225    _return_type: PhantomData<T>,
226    _direction: PhantomData<D>,
227}
228
229// Private methods for this crate only
230impl<'a, T, D, P> Iterator<'a, T, D, P> {
231    /// Core factory method to create iterator with specified direction and policy
232    fn new(
233        database: &'a Database,
234        options: ReadOptions<'a>,
235        policy: P,
236        _direction: PhantomData<D>,
237        _return_type: PhantomData<T>,
238    ) -> Self {
239        unsafe {
240            let c_readoptions = c_readoptions(&options);
241            let ptr = leveldb_create_iterator(database.database.ptr, c_readoptions);
242            leveldb_readoptions_destroy(c_readoptions);
243
244            Iterator {
245                iter: RawIterator { ptr },
246                started: false,
247                stopped: false,
248                policy,
249                database: PhantomData,
250                _return_type: PhantomData,
251                _direction: PhantomData,
252            }
253        }
254    }
255
256    /// Get the raw iterator pointer
257    #[inline]
258    fn raw_iterator(&self) -> *mut leveldb_iterator_t {
259        self.iter.ptr
260    }
261
262    #[inline]
263    fn move_forward(&self) {
264        unsafe { leveldb_iter_next(self.raw_iterator()) }
265    }
266
267    #[inline]
268    fn move_backward(&self) {
269        unsafe { leveldb_iter_prev(self.raw_iterator()) }
270    }
271}
272
273impl<'a, T, D, P> Context<'a> for Iterator<'a, T, D, P> {
274    #[inline]
275    unsafe fn key(&self) -> Option<Slice<'a>> {
276        unsafe {
277            let length: size_t = 0;
278            let value = leveldb_iter_key(self.raw_iterator(), &length) as *const u8;
279            if value.is_null() || length == 0 {
280                None
281            } else {
282                let data = std::slice::from_raw_parts(value, length);
283                Some(Slice::from(data))
284            }
285        }
286    }
287
288    #[inline]
289    unsafe fn value(&self) -> Option<Slice<'a>> {
290        unsafe {
291            let length: size_t = 0;
292            let value = leveldb_iter_value(self.raw_iterator(), &length) as *const u8;
293            if value.is_null() || length == 0 {
294                None
295            } else {
296                let data = std::slice::from_raw_parts(value, length);
297                Some(Slice::from(data))
298            }
299        }
300    }
301
302    #[inline]
303    unsafe fn entry(&self) -> Option<(Slice<'a>, Slice<'a>)> {
304        unsafe {
305            match (self.key(), self.value()) {
306                (Some(key), Some(value)) => Some((key, value)),
307                _ => None,
308            }
309        }
310    }
311}
312
313/// Macro to implement Iterator trait for different
314/// - return types
315/// - directions
316/// - policies
317macro_rules! impl_iterator {
318    ($T:ty, $Item:ty, $ItemFn:ident, $D:ty, $MoveFn:ident, $SeekInitFn:ident, $SeekLastFn:ident) => {
319        impl<'a, P: Policy> iter::Iterator for Iterator<'a, $T, $D, P> {
320            type Item = $Item;
321
322            #[inline]
323            fn next(&mut self) -> Option<Self::Item> {
324                if self.advance() {
325                    unsafe { self.$ItemFn() }
326                } else {
327                    None
328                }
329            }
330        }
331
332        impl<'a, P: Policy> Iterator<'a, $T, $D, P> {
333            /// Return the last element of the iterator
334            ///
335            /// The returned slice borrows data directly from the LevelDB iterator without copying.
336            /// The data is only valid until the iterator is advanced to the next position or destroyed.
337            ///
338            /// # Safety
339            /// The caller must ensure that the returned slice does not outlive the iterator
340            /// or any operation that would advance the iterator (such as calling `next()`).
341            /// To keep the data longer, the slice should be cloned.
342            ///
343            /// # Performance
344            /// This method provides zero-copy access to LevelDB data for maximum performance
345            #[inline]
346            pub fn last(&mut self) -> Result<Option<$Item>, Error> {
347                self.$SeekLastFn();
348                if self.valid() {
349                    Ok(unsafe { self.$ItemFn() })
350                } else {
351                    match self.get_error() {
352                        Some(e) => Err(e),
353                        None => Ok(None),
354                    }
355                }
356            }
357
358            #[inline]
359            fn advance(&mut self) -> bool {
360                if self.stopped {
361                    return false;
362                }
363                if !self.started {
364                    if self.policy.should_seek_begin() {
365                        self.$SeekInitFn();
366                    }
367                    self.started = true;
368                } else {
369                    // Subsequent calls: move to next position
370                    self.$MoveFn();
371                }
372                // Check if current position is valid and should continue
373                self.stopped = !self.valid() || !self.policy.should_continue(self);
374                !self.stopped
375            }
376        }
377    };
378}
379
380impl<'a, T, D, P: Policy> LevelDBIterator<'a> for Iterator<'a, T, D, P> {
381    #[inline]
382    fn valid(&self) -> bool {
383        unsafe { leveldb_iter_valid(self.raw_iterator()) != 0 }
384    }
385
386    #[inline]
387    fn seek(&self, key: &Slice) {
388        unsafe {
389            let key = key.as_bytes();
390            leveldb_iter_seek(
391                self.raw_iterator(),
392                key.as_ptr() as *mut c_char,
393                key.len() as size_t,
394            );
395        }
396    }
397
398    #[inline]
399    fn seek_to_first(&self) {
400        unsafe { leveldb_iter_seek_to_first(self.raw_iterator()) }
401    }
402
403    #[inline]
404    fn seek_to_last(&self) {
405        unsafe { leveldb_iter_seek_to_last(self.raw_iterator()) }
406    }
407
408    #[inline]
409    fn get_error(&self) -> Option<Error> {
410        unsafe {
411            let mut errptr: *mut c_char = std::ptr::null_mut();
412            leveldb_iter_get_error(self.raw_iterator(), &mut errptr);
413
414            if errptr.is_null() {
415                None
416            } else {
417                Some(Error::new_from_char(errptr))
418            }
419        }
420    }
421}
422
423// Apply macro to generate Iterator implementations
424// For different types: key, value & entry
425macro_rules! impl_iterators_for_direction {
426    ($MoveFn:ident, $SeekInitFn:ident, $SeekLastFn:ident, $Dir:ty) => {
427        impl_iterator!(
428            KeyType,
429            Slice<'a>,
430            key,
431            $Dir,
432            $MoveFn,
433            $SeekInitFn,
434            $SeekLastFn
435        );
436        impl_iterator!(
437            ValueType,
438            Slice<'a>,
439            value,
440            $Dir,
441            $MoveFn,
442            $SeekInitFn,
443            $SeekLastFn
444        );
445        impl_iterator!(
446            EntryType,
447            (Slice<'a>, Slice<'a>),
448            entry,
449            $Dir,
450            $MoveFn,
451            $SeekInitFn,
452            $SeekLastFn
453        );
454    };
455}
456// For 2 different directions
457impl_iterators_for_direction!(move_forward, seek_to_first, seek_to_last, Forward);
458impl_iterators_for_direction!(move_backward, seek_to_last, seek_to_first, Backward);
459
460pub type KeyIterator<'a, P = DefaultPolicy> = Iterator<'a, KeyType, Forward, P>;
461pub type ValueIterator<'a, P = DefaultPolicy> = Iterator<'a, ValueType, Forward, P>;
462pub type EntryIterator<'a, P = DefaultPolicy> = Iterator<'a, EntryType, Forward, P>;
463pub type KeyIteratorRev<'a, P = DefaultPolicy> = Iterator<'a, KeyType, Backward, P>;
464pub type ValueIteratorRev<'a, P = DefaultPolicy> = Iterator<'a, ValueType, Backward, P>;
465pub type EntryIteratorRev<'a, P = DefaultPolicy> = Iterator<'a, EntryType, Backward, P>;
466
467/// A trait to provide various iterators of LevelDB instance.
468///
469/// This trait provides a unified interface for creating different types of iterators
470/// over LevelDB data. The API is designed to be flexible while maintaining type safety
471/// and performance.
472///
473/// # Iterator Types
474///
475/// There are three main iterator types, each defined by `T` type parameter:
476///
477/// - **EntryIterator** (`EntryType`): Iterates over key-value pairs `(K, V)`
478/// - **KeyIterator** (`KeyType`): Iterates over keys only `K`
479/// - **ValueIterator** (`ValueType`): Iterates over values only `V`
480///
481/// # Direction
482///
483/// The direction is controlled by `D` type parameter:
484///
485/// - **Forward** (`Forward`): Iterates from smallest to largest key
486/// - **Backward** (`Backward`): Iterates from largest to smallest key
487///
488/// # Policies
489///
490/// Policies control iteration behavior and bounds. For example:
491///
492/// - **DefaultPolicy**: No bounds, iterates over all data
493/// - **BoundedKeyPolicy**: Iterates within specified key bounds
494///
495/// # Usage Examples
496///
497/// ## Basic Entry Iteration
498///
499/// ```ignore
500/// // Forward iteration over all key-value pairs
501/// let iter: EntryIterator<'_> = database.iter(ReadOptions::new());
502///
503/// // Backward iteration over all key-value pairs
504/// let iter: EntryIteratorRev<'_> = database.iter(ReadOptions::new());
505/// ```
506///
507/// ## Key-Only Iteration
508///
509/// ```ignore
510/// // Forward iteration over keys only
511/// let iter: KeyIterator<'_> = database.iter(ReadOptions::new());
512///
513/// // Backward iteration over keys only
514/// let iter: KeyIteratorRev<'_> = database.iter(ReadOptions::new());
515/// ```
516///
517/// ## Value-Only Iteration
518///
519/// ```ignore
520/// // Forward iteration over values only
521/// let iter: ValueIterator<'_> = database.iter(ReadOptions::new());
522///
523/// // Backward iteration over values only
524/// let iter: ValueIteratorRev<'_> = database.iter(ReadOptions::new());
525/// ```
526pub trait Iterable<'a> {
527    /// Create an iterator with specified type, direction, and policy
528    /// Specify return type for correctness of inference
529    ///
530    /// This is the most flexible method that allows complete control over iterator behavior,
531    /// with custom policies.
532    ///
533    /// # Parameters
534    ///
535    /// - `options`: Read options for the iterator
536    /// - `policy`: Iteration policy (bounds, filtering, etc.)
537    ///
538    /// # Returns
539    ///
540    /// An iterator with the specified type, direction, and policy.
541    ///
542    /// # Example
543    ///
544    /// ```ignore
545    /// let begin = Slice::from(&b"key1"[..]);
546    /// let end = Slice::from(&b"key9"[..]);
547    /// let policy = BoundedKeyPolicy::new(Some(begin), Some(end));
548    ///
549    /// // Bounded entry iteration
550    /// let iter: KeyIterator<'_, _>  = database.iter_with_policy(ReadOptions::new(), policy);
551    ///
552    /// // Remember to seek to the start position for bounded iteration
553    /// iter.seek(&begin);
554    /// ```
555    fn iter_with_policy<T, D, P: Policy>(
556        &'a self,
557        options: ReadOptions<'a>,
558        policy: P,
559    ) -> Iterator<'a, T, D, P>;
560
561    /// Create an iterator with specified type and direction, using DefaultPolicy
562    ///
563    /// This is a convenience method that uses the `DefaultPolicy`.
564    ///
565    /// Note: The default iterator type is `KeyIterator` for key-only iteration.
566    /// Use explicit type annotation for other iterator types.
567    ///
568    /// # Parameters
569    ///
570    /// - `options`: Read options for the iterator
571    ///
572    /// # Returns
573    ///
574    /// An iterator with the specified type and direction, using DefaultPolicy.
575    ///
576    /// # Example
577    ///
578    /// ```ignore
579    /// let policy = BoundedKeyPolicy::new(
580    ///     Some(Slice::from(&b"start"[..])),
581    ///     Some(Slice::from(&b"end"[..]))
582    /// );
583    /// let iter: EntryIterator<'_, _> = database.iter_with_policy(ReadOptions::new(), policy);
584    /// ```
585    fn iter<T, D>(&'a self, options: ReadOptions<'a>) -> Iterator<'a, T, D, DefaultPolicy> {
586        self.iter_with_policy(options, DefaultPolicy)
587    }
588}
589
590impl<'a> Iterable<'a> for Database {
591    fn iter_with_policy<T, D, P: Policy>(
592        &'a self,
593        options: ReadOptions<'a>,
594        policy: P,
595    ) -> Iterator<'a, T, D, P> {
596        Iterator::new(self, options, policy, PhantomData, PhantomData)
597    }
598}