pub struct RangeIter<'a, 'g, P, A>where
P: LeafPolicy,
A: TreeAllocator<P>,{ /* private fields */ }Expand description
Iterator over a key range in a crate::MassTree.
Yields entries in lexicographic key order. The iterator maintains internal state for the scan position and handles concurrent modifications via the optimistic concurrency control protocol.
Implements both Iterator and DoubleEndedIterator, allowing forward
iteration with next() and reverse iteration with next_back() or .rev().
§Thread Safety
The iterator holds a reference to the tree and the guard. The guard must remain alive for the duration of iteration to protect pointers from garbage collection.
§Consistency
Range scans are weakly consistent:
- Keys are yielded in sorted order
- May see some concurrent inserts and miss others
- No torn reads (partial key/value data)
- Duplicates filtered via cursor key tracking (may rarely occur under extreme contention)
§Performance
The iterator allocates:
Vec<u8>for each key (unavoidable for owned keys)SmallVecfor layer stack (usually inline, up to 4 layers)- No per-item allocation for value cloning (Arc refcount bump or Copy)
For higher performance, use the batch methods: for_each,
for_each_ref, or for_each_intra_leaf_batch_ref.
§Example
let guard = tree.guard();
let mut count = 0;
for entry in tree.range(
RangeBound::Included(b"prefix:"),
RangeBound::Excluded(b"prefix;"), // ';' is after ':' in ASCII
&guard
) {
count += 1;
}
println!("Found {} entries", count);Implementations§
Source§impl<P, A> RangeIter<'_, '_, P, A>where
P: LeafPolicy,
A: TreeAllocator<P>,
impl<P, A> RangeIter<'_, '_, P, A>where
P: LeafPolicy,
A: TreeAllocator<P>,
Sourcepub fn for_each<F>(self, visitor: F) -> usize
pub fn for_each<F>(self, visitor: F) -> usize
Zero-allocation iteration with a visitor closure.
This is significantly faster than the Iterator trait because it:
- Avoids allocating
Vec<u8>for each key - Uses references directly from internal buffers
§Arguments
visitor: Closure receiving(&[u8], P::Output). Returntrueto continue,falseto stop early.
§Returns
Number of entries visited.
Sourcepub fn for_each_ref<F>(self, visitor: F) -> usize
pub fn for_each_ref<F>(self, visitor: F) -> usize
Zero-copy iteration with borrowed value references.
Unlike Self::for_each which clones values (Arc increment for LeafValue),
this returns &P::Value references tied to the guard lifetime.
§Arguments
visitor: Closure receiving(&[u8], &P::Value). Returntrueto continue,falseto stop early.
§Returns
Number of entries visited.
§Lifetime Guarantees
References are borrowed from internal buffers and protected by the guard. The closure signature prevents storing them beyond the callback scope.
Sourcepub fn for_each_batch_ref<F>(self, visitor: F) -> usize
pub fn for_each_batch_ref<F>(self, visitor: F) -> usize
Batch iteration with zero-copy value references and reduced dispatch overhead.
This is the highest-performance iteration method. It eliminates state machine
dispatch overhead while maintaining identical correctness to Self::for_each_ref.
§Correctness
Unlike approaches that validate only once per leaf, this method:
- Uses per-entry OCC validation (same as
for_each_ref) - Properly updates cursor key for duplicate filtering
- Handles layer transitions correctly (dynamically switches from single-layer
to multi-layer mode when
Downis encountered)
§Arguments
visitor: Closure receiving(&[u8], &P::Value). Returntrueto continue.
§Returns
Number of entries visited.
Sourcepub fn for_each_intra_leaf_batch_ref<F>(self, visitor: F) -> usize
pub fn for_each_intra_leaf_batch_ref<F>(self, visitor: F) -> usize
Intra-leaf batch iteration with maximum performance.
This is the highest-performance iteration method. It processes entire leaves in tight loops, minimizing per-entry overhead.
§Performance Characteristics
- Processes all entries in a leaf before moving to next leaf
- Amortized OCC validation overhead (validates once, processes batch)
- No function call overhead per entry within a leaf
- Falls back to state machine for layer transitions
§Arguments
visitor: Closure receiving(&[u8], &P::Value). Returntrueto continue.
§Returns
Number of entries visited.
Sourcepub fn for_each_intra_leaf_batch<F>(self, visitor: F) -> usize
pub fn for_each_intra_leaf_batch<F>(self, visitor: F) -> usize
Intra-leaf batch iteration returning values by copy.
This is the variant of Self::for_each_intra_leaf_batch_ref that works for ALL
LeafPolicy types, including true-inline storage. Instead of returning &P::Value
references, it returns P::Output by value.
§Performance Characteristics
Same optimizations as for_each_intra_leaf_batch_ref:
- Processes all entries in a leaf before moving to next leaf
- Amortized OCC validation overhead (validates once, processes batch)
- No function call overhead per entry within a leaf
- Falls back to state machine for layer transitions
§Use Cases
- True-inline storage: Required since inline values cannot be returned by reference
- Copy types: When cloning is cheap (integers, small structs)
- Arc storage: Works but incurs refcount operations per entry
For Arc-based storage where zero-copy matters, prefer for_each_intra_leaf_batch_ref.
§Arguments
visitor: Closure receiving(&[u8], P::Output). Returntrueto continue.
§Returns
Number of entries visited.
Sourcepub fn for_each_values_batch<F>(self, visitor: F) -> usize
pub fn for_each_values_batch<F>(self, visitor: F) -> usize
Highest-performance value-only batch iteration (no key materialization).
This is the fastest scan method when you only need values. Keys are not built or copied, saving up to 56 bytes of copying per entry for long keys.
§End Bound Behavior
Unbounded: Exact (scans all entries)Included/Excluded: Approximate for keys with suffix
For bounded scans, the end check uses ikey comparison only. This means:
- Keys where
ikey < bound_ikey: correctly included - Keys where
ikey > bound_ikey: correctly excluded - Keys where
ikey == bound_ikey: may over-include entries
If you need exact end bounds with long keys, use for_each_intra_leaf_batch.
§Arguments
visitor: Closure receivingP::Output. Returntrueto continue.
§Returns
Number of entries visited.
§Example
use masstree::MassTree;
let tree: MassTree<u64> = MassTree::new();
let guard = tree.guard();
let mut sum = 0u64;
tree.iter(&guard).for_each_values_batch(|value| {
sum += value; // value is u64 directly (MassTree uses inline storage)
true
});Sourcepub fn try_for_each_ref<F, E>(self, visitor: F) -> Result<usize, E>
pub fn try_for_each_ref<F, E>(self, visitor: F) -> Result<usize, E>
Fallible iteration with zero-copy value references.
Like Self::for_each_ref, but the visitor can return an error to stop
iteration early. This is useful when processing entries might fail (e.g.,
serialization, validation, I/O).
§Arguments
visitor: Closure receiving(&[u8], &P::Value). ReturnOk(true)to continue,Ok(false)to stop early, orErr(E)to stop with an error.
§Returns
Ok(count): Number of entries successfully visitedErr(e): The error returned by the visitor
§Example
let result = tree.iter(&guard).try_for_each_ref(|key, value| {
if key.len() > MAX_KEY_LEN {
return Err(ValidationError::KeyTooLong);
}
writer.write_entry(key, value)?;
Ok(true)
});
match result {
Ok(count) => println!("Wrote {} entries", count),
Err(e) => eprintln!("Failed: {}", e),
}§Errors
Returns an error if the visitor returns an error.
Source§impl<P, A> RangeIter<'_, '_, P, A>where
P: LeafPolicy,
A: TreeAllocator<P>,
impl<P, A> RangeIter<'_, '_, P, A>where
P: LeafPolicy,
A: TreeAllocator<P>,
Sourcepub fn rev_for_each_ref<F>(self, visitor: F) -> usize
pub fn rev_for_each_ref<F>(self, visitor: F) -> usize
High-performance reverse iteration with zero-copy references.
This is the fastest reverse iteration method. It processes entire leaves in tight loops, minimizing per-entry overhead.
§Performance Characteristics
- Processes all entries in a leaf before moving to previous leaf
- Single OCC validation per leaf
- No function call overhead per entry within a leaf
- Falls back to state machine for layer transitions
§Arguments
visitor: Closure receiving(&[u8], &P::Value). Returntrueto continue.
§Returns
Number of entries visited.
Sourcepub fn rev_for_each_intra_leaf_batch<F>(self, visitor: F) -> usize
pub fn rev_for_each_intra_leaf_batch<F>(self, visitor: F) -> usize
Highest-performance batch-optimized reverse iteration (value by copy).
This is the non-reference variant that works with ALL storage types including
true-inline (MassTree15Inline). Unlike rev_for_each_ref which returns
&P::Value references, this returns P::Output by value.
§Performance Characteristics
- Processes all entries in a leaf before moving to previous leaf
- Single OCC validation per leaf
- No function call overhead per entry within a leaf
- Falls back to state machine for layer transitions
§Availability
Available for ALL storage types:
MassTree15<V>(Box-based)MassTree15Inline<V>(true-inline)
§Arguments
visitor: Callback functionfn(&[u8], P::Output) -> bool
§Returns
Number of entries visited.
Sourcepub fn rev_for_each_values_batch<F>(self, visitor: F) -> usize
pub fn rev_for_each_values_batch<F>(self, visitor: F) -> usize
Highest-performance reverse value-only batch iteration (no key materialization).
This is the fastest reverse scan method when you only need values. Keys are not built or copied, saving up to 56 bytes of copying per entry for long keys.
§Performance
For 64-byte keys: ~1.5-2x faster than rev_for_each_intra_leaf_batch when
the visitor would ignore the key parameter anyway.
§Start Bound Behavior (Reverse Iteration)
Unbounded: Exact (scans all entries)Included/Excluded: Approximate for keys with suffix
For bounded scans, the start check uses ikey comparison only. This means:
- Keys where
ikey > bound_ikey: correctly included - Keys where
ikey < bound_ikey: correctly excluded - Keys where
ikey == bound_ikey: may over-include entries
If you need exact start bounds with long keys, use rev_for_each_intra_leaf_batch.
§Arguments
visitor: Closure receivingP::Output. Returntrueto continue.
§Returns
Number of entries visited.
Source§impl<'a, 'g, P, A> RangeIter<'a, 'g, P, A>where
P: LeafPolicy,
A: TreeAllocator<P>,
impl<'a, 'g, P, A> RangeIter<'a, 'g, P, A>where
P: LeafPolicy,
A: TreeAllocator<P>,
Trait Implementations§
Source§impl<P, A> Debug for RangeIter<'_, '_, P, A>where
P: LeafPolicy,
A: TreeAllocator<P>,
impl<P, A> Debug for RangeIter<'_, '_, P, A>where
P: LeafPolicy,
A: TreeAllocator<P>,
Source§impl<P, A> DoubleEndedIterator for RangeIter<'_, '_, P, A>where
P: LeafPolicy,
A: TreeAllocator<P>,
impl<P, A> DoubleEndedIterator for RangeIter<'_, '_, P, A>where
P: LeafPolicy,
A: TreeAllocator<P>,
Source§fn next_back(&mut self) -> Option<Self::Item>
fn next_back(&mut self) -> Option<Self::Item>
Source§fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>>
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>>
iter_advance_by)n elements. Read more1.37.0 · Source§fn nth_back(&mut self, n: usize) -> Option<Self::Item>
fn nth_back(&mut self, n: usize) -> Option<Self::Item>
nth element from the end of the iterator. Read more1.27.0 · Source§fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
Iterator::try_fold(): it takes
elements starting from the back of the iterator. Read moreSource§impl<P, A> Iterator for RangeIter<'_, '_, P, A>where
P: LeafPolicy,
A: TreeAllocator<P>,
impl<P, A> Iterator for RangeIter<'_, '_, P, A>where
P: LeafPolicy,
A: TreeAllocator<P>,
Source§type Item = ScanEntry<<P as LeafPolicy>::Output>
type Item = ScanEntry<<P as LeafPolicy>::Output>
Source§fn next(&mut self) -> Option<Self::Item>
fn next(&mut self) -> Option<Self::Item>
Source§fn size_hint(&self) -> (usize, Option<usize>)
fn size_hint(&self) -> (usize, Option<usize>)
Source§fn next_chunk<const N: usize>(
&mut self,
) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where
Self: Sized,
fn next_chunk<const N: usize>(
&mut self,
) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where
Self: Sized,
iter_next_chunk)N values. Read more1.0.0 · Source§fn count(self) -> usizewhere
Self: Sized,
fn count(self) -> usizewhere
Self: Sized,
1.0.0 · Source§fn last(self) -> Option<Self::Item>where
Self: Sized,
fn last(self) -> Option<Self::Item>where
Self: Sized,
Source§fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>
fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>
iter_advance_by)n elements. Read more1.0.0 · Source§fn nth(&mut self, n: usize) -> Option<Self::Item>
fn nth(&mut self, n: usize) -> Option<Self::Item>
nth element of the iterator. Read more1.28.0 · Source§fn step_by(self, step: usize) -> StepBy<Self>where
Self: Sized,
fn step_by(self, step: usize) -> StepBy<Self>where
Self: Sized,
1.0.0 · Source§fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
1.0.0 · Source§fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where
Self: Sized,
U: IntoIterator,
fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where
Self: Sized,
U: IntoIterator,
Source§fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
iter_intersperse)separator between adjacent
items of the original iterator. Read moreSource§fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
iter_intersperse)separator
between adjacent items of the original iterator. Read more1.0.0 · Source§fn map<B, F>(self, f: F) -> Map<Self, F>
fn map<B, F>(self, f: F) -> Map<Self, F>
1.0.0 · Source§fn filter<P>(self, predicate: P) -> Filter<Self, P>
fn filter<P>(self, predicate: P) -> Filter<Self, P>
1.0.0 · Source§fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
1.0.0 · Source§fn enumerate(self) -> Enumerate<Self>where
Self: Sized,
fn enumerate(self) -> Enumerate<Self>where
Self: Sized,
1.0.0 · Source§fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
1.0.0 · Source§fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
1.57.0 · Source§fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
1.0.0 · Source§fn skip(self, n: usize) -> Skip<Self>where
Self: Sized,
fn skip(self, n: usize) -> Skip<Self>where
Self: Sized,
n elements. Read more1.0.0 · Source§fn take(self, n: usize) -> Take<Self>where
Self: Sized,
fn take(self, n: usize) -> Take<Self>where
Self: Sized,
n elements, or fewer
if the underlying iterator ends sooner. Read more1.0.0 · Source§fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
Source§fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
iter_map_windows)f for each contiguous window of size N over
self and returns an iterator over the outputs of f. Like slice::windows(),
the windows during mapping overlap as well. Read more1.0.0 · Source§fn inspect<F>(self, f: F) -> Inspect<Self, F>
fn inspect<F>(self, f: F) -> Inspect<Self, F>
1.0.0 · Source§fn by_ref(&mut self) -> &mut Selfwhere
Self: Sized,
fn by_ref(&mut self) -> &mut Selfwhere
Self: Sized,
Iterator. Read moreSource§fn collect_into<E>(self, collection: &mut E) -> &mut E
fn collect_into<E>(self, collection: &mut E) -> &mut E
iter_collect_into)1.0.0 · Source§fn partition<B, F>(self, f: F) -> (B, B)
fn partition<B, F>(self, f: F) -> (B, B)
Source§fn partition_in_place<'a, T, P>(self, predicate: P) -> usize
fn partition_in_place<'a, T, P>(self, predicate: P) -> usize
iter_partition_in_place)true precede all those that return false.
Returns the number of true elements found. Read moreSource§fn is_partitioned<P>(self, predicate: P) -> bool
fn is_partitioned<P>(self, predicate: P) -> bool
iter_is_partitioned)true precede all those that return false. Read more1.27.0 · Source§fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
1.27.0 · Source§fn try_for_each<F, R>(&mut self, f: F) -> R
fn try_for_each<F, R>(&mut self, f: F) -> R
1.0.0 · Source§fn fold<B, F>(self, init: B, f: F) -> B
fn fold<B, F>(self, init: B, f: F) -> B
1.51.0 · Source§fn reduce<F>(self, f: F) -> Option<Self::Item>
fn reduce<F>(self, f: F) -> Option<Self::Item>
Source§fn try_reduce<R>(
&mut self,
f: impl FnMut(Self::Item, Self::Item) -> R,
) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
fn try_reduce<R>( &mut self, f: impl FnMut(Self::Item, Self::Item) -> R, ) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
iterator_try_reduce)1.0.0 · Source§fn all<F>(&mut self, f: F) -> bool
fn all<F>(&mut self, f: F) -> bool
1.0.0 · Source§fn any<F>(&mut self, f: F) -> bool
fn any<F>(&mut self, f: F) -> bool
1.0.0 · Source§fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
1.30.0 · Source§fn find_map<B, F>(&mut self, f: F) -> Option<B>
fn find_map<B, F>(&mut self, f: F) -> Option<B>
Source§fn try_find<R>(
&mut self,
f: impl FnMut(&Self::Item) -> R,
) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
fn try_find<R>( &mut self, f: impl FnMut(&Self::Item) -> R, ) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
try_find)1.0.0 · Source§fn position<P>(&mut self, predicate: P) -> Option<usize>
fn position<P>(&mut self, predicate: P) -> Option<usize>
1.6.0 · Source§fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
1.15.0 · Source§fn max_by<F>(self, compare: F) -> Option<Self::Item>
fn max_by<F>(self, compare: F) -> Option<Self::Item>
1.6.0 · Source§fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
1.15.0 · Source§fn min_by<F>(self, compare: F) -> Option<Self::Item>
fn min_by<F>(self, compare: F) -> Option<Self::Item>
1.0.0 · Source§fn rev(self) -> Rev<Self>where
Self: Sized + DoubleEndedIterator,
fn rev(self) -> Rev<Self>where
Self: Sized + DoubleEndedIterator,
1.0.0 · Source§fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
1.36.0 · Source§fn copied<'a, T>(self) -> Copied<Self>
fn copied<'a, T>(self) -> Copied<Self>
Source§fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where
Self: Sized,
fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where
Self: Sized,
iter_array_chunks)N elements of the iterator at a time. Read more1.11.0 · Source§fn product<P>(self) -> P
fn product<P>(self) -> P
Source§fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
iter_order_by)Iterator with those
of another with respect to the specified comparison function. Read more1.5.0 · Source§fn partial_cmp<I>(self, other: I) -> Option<Ordering>
fn partial_cmp<I>(self, other: I) -> Option<Ordering>
PartialOrd elements of
this Iterator with those of another. The comparison works like short-circuit
evaluation, returning a result without comparing the remaining elements.
As soon as an order can be determined, the evaluation stops and a result is returned. Read moreSource§fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where
Self: Sized,
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,
fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where
Self: Sized,
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,
iter_order_by)Iterator with those
of another with respect to the specified comparison function. Read moreSource§fn eq_by<I, F>(self, other: I, eq: F) -> bool
fn eq_by<I, F>(self, other: I, eq: F) -> bool
iter_order_by)1.5.0 · Source§fn lt<I>(self, other: I) -> bool
fn lt<I>(self, other: I) -> bool
Iterator are lexicographically
less than those of another. Read more1.5.0 · Source§fn le<I>(self, other: I) -> bool
fn le<I>(self, other: I) -> bool
Iterator are lexicographically
less or equal to those of another. Read more1.5.0 · Source§fn gt<I>(self, other: I) -> bool
fn gt<I>(self, other: I) -> bool
Iterator are lexicographically
greater than those of another. Read more1.5.0 · Source§fn ge<I>(self, other: I) -> bool
fn ge<I>(self, other: I) -> bool
Iterator are lexicographically
greater than or equal to those of another. Read more