pub fn hash_weigthed_hashmap<Hidx, F>(&mut self, data: &HashMap<D, F, Hidx>) 
                where   Hidx : std::hash::BuildHasher ,
                        F : num::ToPrimitive + std::fmt::Display {
        //
        let unif0m = Uniform::<usize>::new(0, self.m);
        let mut qmax:f64 = self.maxvaluetracker.get_max_value();
        let mut iter = data.iter();

        while let Some((key, weight_t)) = iter.next() {
            trace!("hash_item : id {:?}  weight {} ", key, weight_t);
            let weight = weight_t.to_f64().unwrap();
            assert!(weight.is_finite() && weight >= 0., "conversion to f64 failed");
            let winv = 1./weight;
            // rebuild a new hasher at each id for reproductibility
            let mut hasher = self.b_hasher.build_hasher();
            key.hash(&mut hasher);
            let new_hash : u64 = hasher.finish();
            let mut rng = Xoshiro256PlusPlus::seed_from_u64(new_hash);
            let h = winv * self.exp01.sample(&mut rng);
            qmax = self.maxvaluetracker.get_max_value();
            
            if h < qmax {
                let k = unif0m.sample(&mut rng);
                assert!(k < self.m);
                if h < self.maxvaluetracker.values[k] {
                    self.signature[k] = *key;
                    // 
                    self.maxvaluetracker.update(k, h);
                    qmax = self.maxvaluetracker.get_max_value();
                }
                if winv < qmax {
                    // we store point for further processing in second step, if inequality is not verified
                    // it cannot be added anymore anywhere.
                    self.to_be_processed.push((*key, winv, rng));
                }                       
            } // end if h < qmax
        } // end initial loop
        //
        // now we have second step
        //
        let mut i = 2;    // by comparison to ProbMinHash3 we are not at i = 2 !!
        // 
        while self.to_be_processed.len() > 0 {
            let mut insert_pos = 0;
            trace!(" i : {:?}  , nb to process : {}", i , self.to_be_processed.len());
            for j in 0..self.to_be_processed.len() {
                let (key, winv, rng) = &mut self.to_be_processed[j];
                let mut h = (*winv) * (i - 1) as f64;
                if h < self.maxvaluetracker.get_max_value() {
                    h = h + (*winv) * self.exp01.sample(rng);
                    let k = unif0m.sample(rng);
                    if h < self.maxvaluetracker.values[k] {
                        self.signature[k] = *key;
                        // 
                        self.maxvaluetracker.update(k, h);
                        qmax = self.maxvaluetracker.get_max_value();
                    }
                    if (*winv) * (i as f64) < qmax {
                        self.to_be_processed[insert_pos] = (*key, *winv, rng.clone());
                        insert_pos = insert_pos + 1;
                    }
                }
            }  // end of for j
            self.to_be_processed.truncate(insert_pos);
            i = i+1;
        }  // end of while 
    }
/// It is the entry point of this hash algorithm with a HashMap (same as with IndexMap just in case)
/// The HashMap gives multiplicity (or weight) to the objects hashed.
/// The weight be positive and be convertible to a f64 without overflow (so )
It is the entry point of this hash algorithm with a HashMap (same as with IndexMap just in case)
The HashMap gives multiplicity (or weight) to the objects hashed.
The weight be positive and be convertible to a f64 without overflow (so )
It is the entry point of this hash algorithm with a HashMap ( same as with IndexMap just in case ) The HashMap gives multiplicity ( or weight ) to the objects hashed . The weight be positive and be convertible to a f64 without overflow ( so )
pub fn hash_weigthed_hashmap<Hidx, F>(&mut self, data: &HashMap<D, F, Hidx>) 
                where   Hidx : std::hash::BuildHasher ,
                        F : num::ToPrimitive + std::fmt::Display {
        //
        let unif0m = Uniform::<usize>::new(0, self.m);
        let mut qmax:f64 = self.maxvaluetracker.get_max_value();
        let mut iter = data.iter();
        while let Some((key, weight_t)) = iter.next() {
            trace!("hash_item : id {:?}  weight {} ", key, weight_t);
            let weight = weight_t.to_f64().unwrap();
            assert!(weight.is_finite() && weight >= 0., "conversion to f64 failed");
            let winv = 1./weight;
            // rebuild a new hasher at each id for reproductibility
            let mut hasher = self.b_hasher.build_hasher();
            key.hash(&mut hasher);
            let new_hash : u64 = hasher.finish();
            let mut rng = Xoshiro256PlusPlus::seed_from_u64(new_hash);
            let h = winv * self.exp01.sample(&mut rng);
            qmax = self.maxvaluetracker.get_max_value();
            if h < qmax {
                let k = unif0m.sample(&mut rng);
                assert!(k < self.m);
                if h < self.maxvaluetracker.values[k] {
                    self.signature[k] = *key;
                    // 
                    self.maxvaluetracker.update(k, h);
                    qmax = self.maxvaluetracker.get_max_value();
                }
                if winv < qmax {
                    // we store point for further processing in second step, if inequality is not verified
                    // it cannot be added anymore anywhere.
                    self.to_be_processed.push((*key, winv, rng));
                }                       
            } // end if h < qmax
        } // end initial loop
        //
        // now we have second step
        //
        let mut i = 2;    // by comparison to ProbMinHash3 we are not at i = 2 !!
        // 
        while self.to_be_processed.len() > 0 {
            let mut insert_pos = 0;
            trace!(" i : {:?}  , nb to process : {}", i , self.to_be_processed.len());
            for j in 0..self.to_be_processed.len() {
                let (key, winv, rng) = &mut self.to_be_processed[j];
                let mut h = (*winv) * (i - 1) as f64;
                if h < self.maxvaluetracker.get_max_value() {
                    h = h + (*winv) * self.exp01.sample(rng);
                    let k = unif0m.sample(rng);
                    if h < self.maxvaluetracker.values[k] {
                        self.signature[k] = *key;
                        // 
                        self.maxvaluetracker.update(k, h);
                        qmax = self.maxvaluetracker.get_max_value();
                    }
                    if (*winv) * (i as f64) < qmax {
                        self.to_be_processed[insert_pos] = (*key, *winv, rng.clone());
                        insert_pos = insert_pos + 1;
                    }
                }
            }  // end of for j
            self.to_be_processed.truncate(insert_pos);
            i = i+1;
        }  // end of while 
    }
pub fn hash_weigthed_hashmap < Hidx , F > ( & mut self , data : & HashMap < D , F , Hidx > ) where Hidx : std :: hash :: BuildHasher , F : num :: ToPrimitive + std :: fmt :: Display { // let unif0m = Uniform :: < usize > :: new ( 0 , self . m ) ; let mut qmax : f64 = self . maxvaluetracker . get_max_value ( ) ; let mut iter = data . iter ( ) ; while let Some ( ( key , weight_t ) ) = iter . next ( ) { trace ! ( " " key weight_t ) ; let weight = weight_t . to_f64 ( ) . unwrap ( ) ; assert ! ( weight is_finite ( ) weight 0. " " ) ; let winv = 1. / weight ; // rebuild a new hasher at each id for reproductibility let mut hasher = self . b_hasher . build_hasher ( ) ; key . hash ( & mut hasher ) ; let new_hash : u64 = hasher . finish ( ) ; let mut rng = Xoshiro256PlusPlus :: seed_from_u64 ( new_hash ) ; let h = winv * self . exp01 . sample ( & mut rng ) ; qmax = self . maxvaluetracker . get_max_value ( ) ; if h < qmax { let k = unif0m . sample ( & mut rng ) ; assert ! ( k self m ) ; if h < self . maxvaluetracker . values [ k ] { self . signature [ k ] = * key ; //  self . maxvaluetracker . update ( k , h ) ; qmax = self . maxvaluetracker . get_max_value ( ) ; } if winv < qmax { // we store point for further processing in second step, if inequality is not verified // it cannot be added anymore anywhere. self . to_be_processed . push ( ( * key , winv , rng ) ) ; } } // end if h < qmax } // end initial loop // // now we have second step // let mut i = 2 ; // by comparison to ProbMinHash3 we are not at i = 2 !! //  while self . to_be_processed . len ( ) > 0 { let mut insert_pos = 0 ; trace ! ( " " i self to_be_processed len ( ) ) ; for j in 0 .. self . to_be_processed . len ( ) { let ( key , winv , rng ) = & mut self . to_be_processed [ j ] ; let mut h = ( * winv ) * ( i - 1 ) as f64 ; if h < self . maxvaluetracker . get_max_value ( ) { h = h + ( * winv ) * self . exp01 . sample ( rng ) ; let k = unif0m . sample ( rng ) ; if h < self . maxvaluetracker . values [ k ] { self . signature [ k ] = * key ; //  self . maxvaluetracker . update ( k , h ) ; qmax = self . maxvaluetracker . get_max_value ( ) ; } if ( * winv ) * ( i as f64 ) < qmax { self . to_be_processed [ insert_pos ] = ( * key , * winv , rng . clone ( ) ) ; insert_pos = insert_pos + 1 ; } } } // end of for j self . to_be_processed . truncate ( insert_pos ) ; i = i + 1 ; } // end of while  }
It is the entry point of this hash algorithm with a HashMap (same as with IndexMap just in case)
The HashMap gives multiplicity (or weight) to the objects hashed.
It is the entry point of this hash algorithm with a HashMap ( same as with IndexMap just in case ) The HashMap gives multiplicity ( or weight ) to the objects hashed .
&mut self
data
&HashMap<D, F, Hidx>