fn internal_next(&mut self) -> Option<Posting> {
        loop {
            // If we have steps left
            if let Some(mut current_operands) = self.current_operands.take() {
                // NOTE: This is filthy fix as soon as nonliteral borrowing lands
                // Get next entry from step
                let next = And::next(&mut current_operands);
                if next.is_none() {
                    // If it is none... we need to go to the next step
                    if self.counter < (2 as usize).pow(self.operands.len() as u32) {
                        // Get all the relevant operands + filters!
                        let mut new_current_operands = self.filters.clone();
                        let mut curr_weight = Weight(0.);
                        for (i, op) in self.operands.iter().enumerate() {
                            let pow = (2 as usize).pow(i as u32);
                            if pow & self.counter == 0 {
                                curr_weight = Weight(curr_weight.0 + op.inner().weight().0);
                                new_current_operands.push(op.clone());
                            }
                        }

                        if new_current_operands.is_empty() || (curr_weight.0 < (0.01 * self.max_weight.0))  {
                            return None;
                        }
                        // TODO: Sort current operands by length(!)
                        self.counter += 1;
                        self.current_operands = Some(new_current_operands);
                        continue;
                    } else {
                        // We are done!
                        self.current_operands = None;
                        return None;
                    }
                } else {
                    self.current_operands = Some(current_operands);
                    return next;
                }
            } else {
                return None;
            }
        }
    }
/// Operands are ordered by weight.
/// For example
/// Op[0] = "hans in body" | Op[1] = "hans in tag" | Op[2] = "hans in title"
///
/// This operator returns
/// Every results of Op[0] && Op[1] && Op[2]
/// Next: All results of Op[1] && Op[2] // Minus previous results
/// Next: All results of Op[0] && Op[2] // Minus previous results
/// Next: All results of Op[2] // Minus previous results
/// and so on...
///
/// If you paid attention you noticed the pattern:
///
/// | Step | Op[0] | Op[1] | Op[2] |
/// |------+-------+-------+-------|
/// |    0 |     1 |     1 |     1 |
/// |    1 |     0 |     1 |     1 |
/// |    2 |     1 |     0 |     1 |
/// |    3 |     0 |     0 |     1 |
/// |    4 |     1 |     1 |     0 |
/// |    5 |     0 |     1 |     0 |
/// |    6 |     1 |     0 |     0 |
/// |    7 |     0 |     0 |     0 |
///
/// This ensures, that the most relevant results are yielded first
///
/// You might be worried about runtime and complexity
/// The number of operands is query terms * fields
/// And the number of steps is 2^n
///
/// BUT: Perlin is designed for human consumption of search results
/// That means: in all likelihood we will need to yield 10 results
/// The 99% percentile is probably below 100 results
/// So dont worry... (hopefully I'm right)
Operands are ordered by weight.



If you paid attention you noticed the pattern.



This ensures, that the most relevant results are yielded first

You might be worried about runtime and complexity
The number of operands is query terms * fields
And the number of steps is 2^n

Perlin is designed for human consumption of search results
That means: in all likelihood we will need to yield 10 results
The 99% percentile is probably below 100 results
So dont worry... (hopefully I'm right)
Operands are ordered by weight . If you paid attention you noticed the pattern . This ensures that the most relevant results are yielded first You might be worried about runtime and complexity The number of operands is query terms * fields And the number of steps is 2^n Perlin is designed for human consumption of search results That means : in all likelihood we will need to yield 10 results The 99% percentile is probably below 100 results So dont worry ... ( hopefully I ' m right )
fn internal_next(&mut self) -> Option<Posting> {
        loop {
            // If we have steps left
            if let Some(mut current_operands) = self.current_operands.take() {
                // NOTE: This is filthy fix as soon as nonliteral borrowing lands
                // Get next entry from step
                let next = And::next(&mut current_operands);
                if next.is_none() {
                    // If it is none... we need to go to the next step
                    if self.counter < (2 as usize).pow(self.operands.len() as u32) {
                        // Get all the relevant operands + filters!
                        let mut new_current_operands = self.filters.clone();
                        let mut curr_weight = Weight(0.);
                        for (i, op) in self.operands.iter().enumerate() {
                            let pow = (2 as usize).pow(i as u32);
                            if pow & self.counter == 0 {
                                curr_weight = Weight(curr_weight.0 + op.inner().weight().0);
                                new_current_operands.push(op.clone());
                            }
                        }
                        if new_current_operands.is_empty() || (curr_weight.0 < (0.01 * self.max_weight.0))  {
                            return None;
                        }
                        // TODO: Sort current operands by length(!)
                        self.counter += 1;
                        self.current_operands = Some(new_current_operands);
                        continue;
                    } else {
                        // We are done!
                        self.current_operands = None;
                        return None;
                    }
                } else {
                    self.current_operands = Some(current_operands);
                    return next;
                }
            } else {
                return None;
            }
        }
    }
fn internal_next ( & mut self ) -> Option < Posting > { loop { // If we have steps left if let Some ( mut current_operands ) = self . current_operands . take ( ) { // NOTE: This is filthy fix as soon as nonliteral borrowing lands // Get next entry from step let next = And :: next ( & mut current_operands ) ; if next . is_none ( ) { // If it is none... we need to go to the next step if self . counter < ( 2 as usize ) . pow ( self . operands . len ( ) as u32 ) { // Get all the relevant operands + filters! let mut new_current_operands = self . filters . clone ( ) ; let mut curr_weight = Weight ( 0. ) ; for ( i , op ) in self . operands . iter ( ) . enumerate ( ) { let pow = ( 2 as usize ) . pow ( i as u32 ) ; if pow & self . counter == 0 { curr_weight = Weight ( curr_weight . 0 + op . inner ( ) . weight ( ) . 0 ) ; new_current_operands . push ( op . clone ( ) ) ; } } if new_current_operands . is_empty ( ) || ( curr_weight . 0 < ( 0.01 * self . max_weight . 0 ) ) { return None ; } // TODO: Sort current operands by length(!) self . counter += 1 ; self . current_operands = Some ( new_current_operands ) ; continue ; } else { // We are done! self . current_operands = None ; return None ; } } else { self . current_operands = Some ( current_operands ) ; return next ; } } else { return None ; } } }
Operands are ordered by weight.
Operands are ordered by weight .
&mut self
&mut self