reduces constant overhead
(
&mut self,
qcur: &mut SparseSet,
qnext: &mut SparseSet,
text: &[u8],
)
| 767 | /// Executes the DFA on a reverse NFA. |
| 768 | #[inline(always)] // reduces constant overhead |
| 769 | fn exec_at_reverse( |
| 770 | &mut self, |
| 771 | qcur: &mut SparseSet, |
| 772 | qnext: &mut SparseSet, |
| 773 | text: &[u8], |
| 774 | ) -> Result<usize> { |
| 775 | // The comments in `exec_at` above mostly apply here too. The main |
| 776 | // difference is that we move backwards over the input and we look for |
| 777 | // the longest possible match instead of the leftmost-first match. |
| 778 | // |
| 779 | // N.B. The code duplication here is regrettable. Efforts to improve |
| 780 | // it without sacrificing performance are welcome. ---AG |
| 781 | debug_assert!(self.prog.is_reverse); |
| 782 | let mut result = Result::NoMatch(self.at); |
| 783 | let (mut prev_si, mut next_si) = (self.start, self.start); |
| 784 | let mut at = self.at; |
| 785 | while at > 0 { |
| 786 | while next_si <= STATE_MAX && at > 0 { |
| 787 | // Argument for safety is in the definition of next_si. |
| 788 | at -= 1; |
| 789 | prev_si = unsafe { self.next_si(next_si, text, at) }; |
| 790 | if prev_si > STATE_MAX || at <= 4 { |
| 791 | mem::swap(&mut prev_si, &mut next_si); |
| 792 | break; |
| 793 | } |
| 794 | at -= 1; |
| 795 | next_si = unsafe { self.next_si(prev_si, text, at) }; |
| 796 | if next_si > STATE_MAX { |
| 797 | break; |
| 798 | } |
| 799 | at -= 1; |
| 800 | prev_si = unsafe { self.next_si(next_si, text, at) }; |
| 801 | if prev_si > STATE_MAX { |
| 802 | mem::swap(&mut prev_si, &mut next_si); |
| 803 | break; |
| 804 | } |
| 805 | at -= 1; |
| 806 | next_si = unsafe { self.next_si(prev_si, text, at) }; |
| 807 | } |
| 808 | if next_si & STATE_MATCH > 0 { |
| 809 | next_si &= !STATE_MATCH; |
| 810 | result = Result::Match(at + 1); |
| 811 | if self.quit_after_match { |
| 812 | return result |
| 813 | } |
| 814 | self.last_match_si = next_si; |
| 815 | prev_si = next_si; |
| 816 | let cur = at; |
| 817 | while (next_si & !STATE_MATCH) == prev_si && at >= 2 { |
| 818 | // Argument for safety is in the definition of next_si. |
| 819 | at -= 1; |
| 820 | next_si = unsafe { |
| 821 | self.next_si(next_si & !STATE_MATCH, text, at) |
| 822 | }; |
| 823 | } |
| 824 | if at < cur { |
| 825 | result = Result::Match(at + 2); |
| 826 | } |
no test coverage detected