fn rehash_in_place(&mut self, hasher: impl Fn(&T) -> u64) {
        unsafe {
            // Bulk convert all full control bytes to DELETED, and all DELETED
            // control bytes to EMPTY. This effectively frees up all buckets
            // containing a DELETED entry.
            for i in (0..self.buckets()).step_by(Group::WIDTH) {
                let group = Group::load_aligned(self.ctrl(i));
                let group = group.convert_special_to_empty_and_full_to_deleted();
                group.store_aligned(self.ctrl(i));
            }

            // Fix up the trailing control bytes. See the comments in set_ctrl.
            if self.buckets() < Group::WIDTH {
                self.ctrl(0)
                    .copy_to(self.ctrl(Group::WIDTH), self.buckets());
                self.ctrl(self.buckets())
                    .write_bytes(DELETED, Group::WIDTH - self.buckets());
            } else {
                self.ctrl(0)
                    .copy_to(self.ctrl(self.buckets()), Group::WIDTH);
            }

            // If the hash function panics then properly clean up any elements
            // that we haven't rehashed yet. We unfortunately can't preserve the
            // element since we lost their hash and have no way of recovering it
            // without risking another panic.
            let mut guard = guard(self, |self_| {
                if mem::needs_drop::<T>() {
                    for i in 0..self_.buckets() {
                        if *self_.ctrl(i) == DELETED {
                            self_.set_ctrl(i, EMPTY);
                            self_.bucket(i).drop();
                            self_.items -= 1;
                        }
                    }
                }
                self_.growth_left = bucket_mask_to_capacity(self_.bucket_mask) - self_.items;
            });

            // At this point, DELETED elements are elements that we haven't
            // rehashed yet. Find them and re-insert them at their ideal
            // position.
            'outer: for i in 0..guard.buckets() {
                if *guard.ctrl(i) != DELETED {
                    continue;
                }
                'inner: loop {
                    // Hash the current item
                    let item = guard.bucket(i);
                    let hash = hasher(item.as_ref());

                    // Search for a suitable place to put it
                    let new_i = guard.find_insert_slot(hash);

                    // Probing works by scanning through all of the control
                    // bytes in groups, which may not be aligned to the group
                    // size. If both the new and old position fall within the
                    // same unaligned group, then there is no benefit in moving
                    // it and we can just continue to the next item.
                    let probe_index = |pos: usize| {
                        (pos.wrapping_sub(guard.probe_seq(hash).offset) & guard.bucket_mask)
                            / Group::WIDTH
                    };
                    if likely(probe_index(i) == probe_index(new_i)) {
                        guard.set_ctrl(i, h2(hash));
                        continue 'outer;
                    }

                    // We are moving the current item to a new position. Write
                    // our H2 to the control byte of the new position.
                    let prev_ctrl = *guard.ctrl(new_i);
                    guard.set_ctrl(new_i, h2(hash));

                    if prev_ctrl == EMPTY {
                        // If the target slot is empty, simply move the current
                        // element into the new slot and clear the old control
                        // byte.
                        guard.set_ctrl(i, EMPTY);
                        guard.bucket(new_i).write(item.read());
                        continue 'outer;
                    } else {
                        // If the target slot is occupied, swap the two elements
                        // and then continue processing the element that we just
                        // swapped into the old slot.
                        debug_assert_eq!(prev_ctrl, DELETED);
                        mem::swap(guard.bucket(new_i).as_mut(), item.as_mut());
                        continue 'inner;
                    }
                }
            }

            guard.growth_left = bucket_mask_to_capacity(guard.bucket_mask) - guard.items;
            mem::forget(guard);
        }
    }
/// Rehashes the contents of the table in place (i.e. without changing the
/// allocation).
///
/// If `hasher` panics then some the table's contents may be lost.
Rehashes the contents of the table in place .

If `hasher` panics then some the table's contents may be lost.
Rehashes the contents of the table in place . If ` hasher ` panics then some the table ' s contents may be lost .
fn rehash_in_place(&mut self, hasher: impl Fn(&T) -> u64) {
        unsafe {
            // Bulk convert all full control bytes to DELETED, and all DELETED
            // control bytes to EMPTY. This effectively frees up all buckets
            // containing a DELETED entry.
            for i in (0..self.buckets()).step_by(Group::WIDTH) {
                let group = Group::load_aligned(self.ctrl(i));
                let group = group.convert_special_to_empty_and_full_to_deleted();
                group.store_aligned(self.ctrl(i));
            }
            // Fix up the trailing control bytes. See the comments in set_ctrl.
            if self.buckets() < Group::WIDTH {
                self.ctrl(0)
                    .copy_to(self.ctrl(Group::WIDTH), self.buckets());
                self.ctrl(self.buckets())
                    .write_bytes(DELETED, Group::WIDTH - self.buckets());
            } else {
                self.ctrl(0)
                    .copy_to(self.ctrl(self.buckets()), Group::WIDTH);
            }
            // If the hash function panics then properly clean up any elements
            // that we haven't rehashed yet. We unfortunately can't preserve the
            // element since we lost their hash and have no way of recovering it
            // without risking another panic.
            let mut guard = guard(self, |self_| {
                if mem::needs_drop::<T>() {
                    for i in 0..self_.buckets() {
                        if *self_.ctrl(i) == DELETED {
                            self_.set_ctrl(i, EMPTY);
                            self_.bucket(i).drop();
                            self_.items -= 1;
                        }
                    }
                }
                self_.growth_left = bucket_mask_to_capacity(self_.bucket_mask) - self_.items;
            });
            // At this point, DELETED elements are elements that we haven't
            // rehashed yet. Find them and re-insert them at their ideal
            // position.
            'outer: for i in 0..guard.buckets() {
                if *guard.ctrl(i) != DELETED {
                    continue;
                }
                'inner: loop {
                    // Hash the current item
                    let item = guard.bucket(i);
                    let hash = hasher(item.as_ref());
                    // Search for a suitable place to put it
                    let new_i = guard.find_insert_slot(hash);
                    // Probing works by scanning through all of the control
                    // bytes in groups, which may not be aligned to the group
                    // size. If both the new and old position fall within the
                    // same unaligned group, then there is no benefit in moving
                    // it and we can just continue to the next item.
                    let probe_index = |pos: usize| {
                        (pos.wrapping_sub(guard.probe_seq(hash).offset) & guard.bucket_mask)
                            / Group::WIDTH
                    };
                    if likely(probe_index(i) == probe_index(new_i)) {
                        guard.set_ctrl(i, h2(hash));
                        continue 'outer;
                    }
                    // We are moving the current item to a new position. Write
                    // our H2 to the control byte of the new position.
                    let prev_ctrl = *guard.ctrl(new_i);
                    guard.set_ctrl(new_i, h2(hash));
                    if prev_ctrl == EMPTY {
                        // If the target slot is empty, simply move the current
                        // element into the new slot and clear the old control
                        // byte.
                        guard.set_ctrl(i, EMPTY);
                        guard.bucket(new_i).write(item.read());
                        continue 'outer;
                    } else {
                        // If the target slot is occupied, swap the two elements
                        // and then continue processing the element that we just
                        // swapped into the old slot.
                        debug_assert_eq!(prev_ctrl, DELETED);
                        mem::swap(guard.bucket(new_i).as_mut(), item.as_mut());
                        continue 'inner;
                    }
                }
            }
            guard.growth_left = bucket_mask_to_capacity(guard.bucket_mask) - guard.items;
            mem::forget(guard);
        }
    }
fn rehash_in_place ( & mut self , hasher : impl Fn ( & T ) -> u64 ) { unsafe { // Bulk convert all full control bytes to DELETED, and all DELETED // control bytes to EMPTY. This effectively frees up all buckets // containing a DELETED entry. for i in ( 0 .. self . buckets ( ) ) . step_by ( Group :: WIDTH ) { let group = Group :: load_aligned ( self . ctrl ( i ) ) ; let group = group . convert_special_to_empty_and_full_to_deleted ( ) ; group . store_aligned ( self . ctrl ( i ) ) ; } // Fix up the trailing control bytes. See the comments in set_ctrl. if self . buckets ( ) < Group :: WIDTH { self . ctrl ( 0 ) . copy_to ( self . ctrl ( Group :: WIDTH ) , self . buckets ( ) ) ; self . ctrl ( self . buckets ( ) ) . write_bytes ( DELETED , Group :: WIDTH - self . buckets ( ) ) ; } else { self . ctrl ( 0 ) . copy_to ( self . ctrl ( self . buckets ( ) ) , Group :: WIDTH ) ; } // If the hash function panics then properly clean up any elements // that we haven't rehashed yet. We unfortunately can't preserve the // element since we lost their hash and have no way of recovering it // without risking another panic. let mut guard = guard ( self , | self_ | { if mem :: needs_drop :: < T > ( ) { for i in 0 .. self_ . buckets ( ) { if * self_ . ctrl ( i ) == DELETED { self_ . set_ctrl ( i , EMPTY ) ; self_ . bucket ( i ) . drop ( ) ; self_ . items -= 1 ; } } } self_ . growth_left = bucket_mask_to_capacity ( self_ . bucket_mask ) - self_ . items ; } ) ; // At this point, DELETED elements are elements that we haven't // rehashed yet. Find them and re-insert them at their ideal // position. ' outer : for i in 0 .. guard . buckets ( ) { if * guard . ctrl ( i ) != DELETED { continue ; } ' inner : loop { // Hash the current item let item = guard . bucket ( i ) ; let hash = hasher ( item . as_ref ( ) ) ; // Search for a suitable place to put it let new_i = guard . find_insert_slot ( hash ) ; // Probing works by scanning through all of the control // bytes in groups, which may not be aligned to the group // size. If both the new and old position fall within the // same unaligned group, then there is no benefit in moving // it and we can just continue to the next item. let probe_index = | pos : usize | { ( pos . wrapping_sub ( guard . probe_seq ( hash ) . offset ) & guard . bucket_mask ) / Group :: WIDTH } ; if likely ( probe_index ( i ) == probe_index ( new_i ) ) { guard . set_ctrl ( i , h2 ( hash ) ) ; continue ' outer ; } // We are moving the current item to a new position. Write // our H2 to the control byte of the new position. let prev_ctrl = * guard . ctrl ( new_i ) ; guard . set_ctrl ( new_i , h2 ( hash ) ) ; if prev_ctrl == EMPTY { // If the target slot is empty, simply move the current // element into the new slot and clear the old control // byte. guard . set_ctrl ( i , EMPTY ) ; guard . bucket ( new_i ) . write ( item . read ( ) ) ; continue ' outer ; } else { // If the target slot is occupied, swap the two elements // and then continue processing the element that we just // swapped into the old slot. debug_assert_eq ! ( prev_ctrl DELETED ) ; mem :: swap ( guard . bucket ( new_i ) . as_mut ( ) , item . as_mut ( ) ) ; continue ' inner ; } } } guard . growth_left = bucket_mask_to_capacity ( guard . bucket_mask ) - guard . items ; mem :: forget ( guard ) ; } }
Rehashes the contents of the table in place (i.e.
Rehashes the contents of the table in place ( i . e .
&mut self
hasher
impl Fn(&T) -> u64
&mut self
hasher
impl Fn(&T) -> u64