fn new_if_unempty(
        hash_iter: impl IntoIterator<Item = T>,
        lazy_iter: impl IntoIterator<IntoIter = I>,
        hash_fields: T::FieldSet,
        lazy_fields: T::FieldSet,
        mut pool: P,
    ) -> Result<Self, (I, P, T::FieldSet, T::FieldSet)> {
        // Get the first tuple of the hash iterator.
        let mut hash_iter = hash_iter.into_iter();
        let hash_val: T = match hash_iter.next() {
            Some(v) => v,
            None => return Err((lazy_iter.into_iter(), pool, hash_fields, lazy_fields)),
        };

        // Get the first tuple of the lazy iterator.
        let mut lazy_iter = lazy_iter.into_iter();
        let lazy_val: T = match lazy_iter.next() {
            Some(v) => v,
            None => return Err((lazy_iter, pool, hash_fields, lazy_fields)),
        };

        // Compute fields common to hash and lazy iterators.
        //
        // Hash and equality comparisons for the join will only consider these
        // fields.
        let shared_fields = hash_fields.intersect(&lazy_fields);

        // Pin those fields to guarantee that a pointer to them will stay valid
        // as long as the returned `HashJoin` is alive.
        let shared_fields = Box::pin(shared_fields);
        let shared_fields_ptr = NonNull::from(shared_fields.as_ref().get_ref());

        // Add all values from `hash_iter` into `hashmap`, grouping those with
        // equal `shared_fields` in a single `HashJoinKey`.
        let mut hashmap = HashMap::new();

        // (First value we obtained earlier.)
        Self::get_raw_entry(&mut hashmap, &shared_fields, &hash_val).or_insert(
            HashJoinKey {
                significant_fields: shared_fields_ptr,
                vec: smallvec![hash_val],
            },
            (),
        );

        // (All other values of the `hash_iter`.)
        for hash_val in hash_iter {
            match Self::get_raw_entry(&mut hashmap, &shared_fields, &hash_val) {
                RawEntryMut::Occupied(mut entry) => entry.key_mut().vec.push(hash_val),
                RawEntryMut::Vacant(entry) => {
                    entry.insert(
                        HashJoinKey {
                            significant_fields: shared_fields_ptr,
                            vec: smallvec![hash_val],
                        },
                        (),
                    );
                }
            }
        }

        // Kick-off the first iteration by finding the values in `hashmap` that
        // correspond to `lazy_val`.
        let vec = match Self::get_raw_entry(&mut hashmap, &shared_fields, &lazy_val) {
            RawEntryMut::Occupied(entry) => entry
                .key()
                .vec
                .iter()
                .map(|v| pool.clone_tuple(v, &hash_fields))
                .collect(),
            RawEntryMut::Vacant(_) => {
                // No match for the first value: we use an empty vector, and
                // `next()` will automatically move on to the next value.
                SmallVec::new()
            }
        };

        Ok(HashJoin {
            iter: lazy_iter,
            hashmap,
            hash_curr: vec.into_iter(),
            iter_curr: std::mem::MaybeUninit::new(lazy_val),
            hash_fields,
            iter_fields: lazy_fields,
            shared_fields,
            pool,
        })
    }
/// Returns an [`HashJoin`] if none of the given iterators is empty.
/// Otherwise, returns an error with all the input parameters.
Returns an [`HashJoin`] if none of the given iterators is empty.
Otherwise, returns an error with all the input parameters.
Returns an [ ` HashJoin ` ] if none of the given iterators is empty . Otherwise returns an error with all the input parameters .
fn new_if_unempty(
        hash_iter: impl IntoIterator<Item = T>,
        lazy_iter: impl IntoIterator<IntoIter = I>,
        hash_fields: T::FieldSet,
        lazy_fields: T::FieldSet,
        mut pool: P,
    ) -> Result<Self, (I, P, T::FieldSet, T::FieldSet)> {
        // Get the first tuple of the hash iterator.
        let mut hash_iter = hash_iter.into_iter();
        let hash_val: T = match hash_iter.next() {
            Some(v) => v,
            None => return Err((lazy_iter.into_iter(), pool, hash_fields, lazy_fields)),
        };
        // Get the first tuple of the lazy iterator.
        let mut lazy_iter = lazy_iter.into_iter();
        let lazy_val: T = match lazy_iter.next() {
            Some(v) => v,
            None => return Err((lazy_iter, pool, hash_fields, lazy_fields)),
        };
        // Compute fields common to hash and lazy iterators.
        //
        // Hash and equality comparisons for the join will only consider these
        // fields.
        let shared_fields = hash_fields.intersect(&lazy_fields);
        // Pin those fields to guarantee that a pointer to them will stay valid
        // as long as the returned `HashJoin` is alive.
        let shared_fields = Box::pin(shared_fields);
        let shared_fields_ptr = NonNull::from(shared_fields.as_ref().get_ref());
        // Add all values from `hash_iter` into `hashmap`, grouping those with
        // equal `shared_fields` in a single `HashJoinKey`.
        let mut hashmap = HashMap::new();
        // (First value we obtained earlier.)
        Self::get_raw_entry(&mut hashmap, &shared_fields, &hash_val).or_insert(
            HashJoinKey {
                significant_fields: shared_fields_ptr,
                vec: smallvec![hash_val],
            },
            (),
        );
        // (All other values of the `hash_iter`.)
        for hash_val in hash_iter {
            match Self::get_raw_entry(&mut hashmap, &shared_fields, &hash_val) {
                RawEntryMut::Occupied(mut entry) => entry.key_mut().vec.push(hash_val),
                RawEntryMut::Vacant(entry) => {
                    entry.insert(
                        HashJoinKey {
                            significant_fields: shared_fields_ptr,
                            vec: smallvec![hash_val],
                        },
                        (),
                    );
                }
            }
        }
        // Kick-off the first iteration by finding the values in `hashmap` that
        // correspond to `lazy_val`.
        let vec = match Self::get_raw_entry(&mut hashmap, &shared_fields, &lazy_val) {
            RawEntryMut::Occupied(entry) => entry
                .key()
                .vec
                .iter()
                .map(|v| pool.clone_tuple(v, &hash_fields))
                .collect(),
            RawEntryMut::Vacant(_) => {
                // No match for the first value: we use an empty vector, and
                // `next()` will automatically move on to the next value.
                SmallVec::new()
            }
        };
        Ok(HashJoin {
            iter: lazy_iter,
            hashmap,
            hash_curr: vec.into_iter(),
            iter_curr: std::mem::MaybeUninit::new(lazy_val),
            hash_fields,
            iter_fields: lazy_fields,
            shared_fields,
            pool,
        })
    }
fn new_if_unempty ( hash_iter : impl IntoIterator < Item = T > , lazy_iter : impl IntoIterator < IntoIter = I > , hash_fields : T :: FieldSet , lazy_fields : T :: FieldSet , mut pool : P , ) -> Result < Self , ( I , P , T :: FieldSet , T :: FieldSet ) > { // Get the first tuple of the hash iterator. let mut hash_iter = hash_iter . into_iter ( ) ; let hash_val : T = match hash_iter . next ( ) { Some ( v ) => v , None => return Err ( ( lazy_iter . into_iter ( ) , pool , hash_fields , lazy_fields ) ) , } ; // Get the first tuple of the lazy iterator. let mut lazy_iter = lazy_iter . into_iter ( ) ; let lazy_val : T = match lazy_iter . next ( ) { Some ( v ) => v , None => return Err ( ( lazy_iter , pool , hash_fields , lazy_fields ) ) , } ; // Compute fields common to hash and lazy iterators. // // Hash and equality comparisons for the join will only consider these // fields. let shared_fields = hash_fields . intersect ( & lazy_fields ) ; // Pin those fields to guarantee that a pointer to them will stay valid // as long as the returned `HashJoin` is alive. let shared_fields = Box :: pin ( shared_fields ) ; let shared_fields_ptr = NonNull :: from ( shared_fields . as_ref ( ) . get_ref ( ) ) ; // Add all values from `hash_iter` into `hashmap`, grouping those with // equal `shared_fields` in a single `HashJoinKey`. let mut hashmap = HashMap :: new ( ) ; // (First value we obtained earlier.) Self :: get_raw_entry ( & mut hashmap , & shared_fields , & hash_val ) . or_insert ( HashJoinKey { significant_fields : shared_fields_ptr , vec : smallvec ! [ hash_val ] , } , ( ) , ) ; // (All other values of the `hash_iter`.) for hash_val in hash_iter { match Self :: get_raw_entry ( & mut hashmap , & shared_fields , & hash_val ) { RawEntryMut :: Occupied ( mut entry ) => entry . key_mut ( ) . vec . push ( hash_val ) , RawEntryMut :: Vacant ( entry ) => { entry . insert ( HashJoinKey { significant_fields : shared_fields_ptr , vec : smallvec ! [ hash_val ] , } , ( ) , ) ; } } } // Kick-off the first iteration by finding the values in `hashmap` that // correspond to `lazy_val`. let vec = match Self :: get_raw_entry ( & mut hashmap , & shared_fields , & lazy_val ) { RawEntryMut :: Occupied ( entry ) => entry . key ( ) . vec . iter ( ) . map ( | v | pool . clone_tuple ( v , & hash_fields ) ) . collect ( ) , RawEntryMut :: Vacant ( _ ) => { // No match for the first value: we use an empty vector, and // `next()` will automatically move on to the next value. SmallVec :: new ( ) } } ; Ok ( HashJoin { iter : lazy_iter , hashmap , hash_curr : vec . into_iter ( ) , iter_curr : std :: mem :: MaybeUninit :: new ( lazy_val ) , hash_fields , iter_fields : lazy_fields , shared_fields , pool , } ) }
Returns an [`HashJoin`] if none of the given iterators is empty.
Returns an [ ` HashJoin ` ] if none of the given iterators is empty .
hash_iter
impl IntoIterator<Item = T>
lazy_iter
impl IntoIterator<IntoIter = I>
hash_fields
T::FieldSet
lazy_fields
T::FieldSet
pool
P
hash_iter
impl IntoIterator<Item = T>
lazy_iter
impl IntoIterator<IntoIter = I>
hash_fields
T::FieldSet
lazy_fields
T::FieldSet
pool
P