Skip to content

Commit

Permalink
Add comments
Browse files Browse the repository at this point in the history
  • Loading branch information
JustForFun88 authored and a1phyr committed Nov 8, 2023
1 parent 5aa1b77 commit dee5c03
Showing 1 changed file with 53 additions and 6 deletions.
59 changes: 53 additions & 6 deletions src/raw/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3847,8 +3847,30 @@ impl<T> RawIterRange<T> {
}
}

/// Folds every element into an accumulator by applying an operation,
/// returning the final result.
///
/// `fold_impl()` takes three arguments: a number of items in the table, an initial value,
/// and a closure with two arguments: an 'accumulator', and an element. The closure
/// returns the value that the accumulator should have for the next iteration.
///
/// The initial value is the value the accumulator will have on the first call.
///
/// After applying this closure to every element of the iterator, `fold_impl()`
/// returns the accumulator.
///
/// # Safety
/// The provided `n` value must match the actual number of items
///
/// If any of the following conditions are violated, the result is
/// [`Undefined Behavior`]:
///
/// * The [`RawTableInner`] / [`RawTable`] must be alive and not moved,
/// i.e. table outlives the `RawIterRange`;
///
/// * The provided `n` value must match the actual number of items
/// in the table.
///
/// [`Undefined Behavior`]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
#[allow(clippy::while_let_on_iterator)]
#[cfg_attr(feature = "inline-more", inline)]
unsafe fn fold_impl<F, B>(mut self, mut n: usize, mut acc: B, mut f: F) -> B
Expand All @@ -3861,6 +3883,8 @@ impl<T> RawIterRange<T> {

loop {
while let Some(index) = self.current_group.next() {
// The returned `index` will always be in the range `0..Group::WIDTH`,
// so that calling `self.data.next_n(index)` is safe (see detailed explanation below).
debug_assert!(n != 0);
let bucket = self.data.next_n(index);
acc = f(acc, bucket);
Expand All @@ -3871,11 +3895,34 @@ impl<T> RawIterRange<T> {
return acc;
}

// We might read past self.end up to the next group boundary,
// but this is fine because it only occurs on tables smaller
// than the group size where the trailing control bytes are all
// EMPTY. On larger tables self.end is guaranteed to be aligned
// to the group size (since tables are power-of-two sized).
// SAFETY: The caller of this function ensures that:
//
// 1. The provided `n` value matches the actual number of items in the table;
// 2. The table is alive and did not moved.
//
// Taking the above into account, we always stay within the bounds, because:
//
// 1. For tables smaller than the group width (self.buckets() <= Group::WIDTH),
// we will never end up in the given branch, since we should have already
// yielded all the elements of the table.
//
// 2. For tables larger than the group width. The the number of buckets is a
// power of two (2 ^ n), Group::WIDTH is also power of two (2 ^ k). Sinse
// `(2 ^ n) > (2 ^ k)`, than `(2 ^ n) % (2 ^ k) = 0`. As we start from the
// the start of the array of control bytes, and never try to iterate after
// getting all the elements, the last `self.current_group` will read bytes
// from the `self.buckets() - Group::WIDTH` index. We know also that
// `self.current_group.next()` will always retun indices within the range
// `0..Group::WIDTH`.
//
// Knowing all of the above and taking into account that we are synchronizing
// the `self.data` index with the index we used to read the `self.current_group`,
// the subsequent `self.data.next_n(index)` will always return a bucket with
// an index number less than `self.buckets()`.
//
// The last `self.next_ctrl`, whose index would be `self.buckets()`, will never
// actually be read, since we should have already yielded all the elements of
// the table.
self.current_group = Group::load_aligned(self.next_ctrl).match_full().into_iter();
self.data = self.data.next_n(Group::WIDTH);
self.next_ctrl = self.next_ctrl.add(Group::WIDTH);
Expand Down

0 comments on commit dee5c03

Please sign in to comment.