| 1 | use crate::util::{ |
| 2 | prefilter::PrefilterI, |
| 3 | search::{MatchKind, Span}, |
| 4 | }; |
| 5 | |
| 6 | #[derive (Clone, Debug)] |
| 7 | pub(crate) struct ByteSet([bool; 256]); |
| 8 | |
| 9 | impl ByteSet { |
| 10 | pub(crate) fn new<B: AsRef<[u8]>>( |
| 11 | _kind: MatchKind, |
| 12 | needles: &[B], |
| 13 | ) -> Option<ByteSet> { |
| 14 | #[cfg (not(feature = "perf-literal-multisubstring" ))] |
| 15 | { |
| 16 | None |
| 17 | } |
| 18 | #[cfg (feature = "perf-literal-multisubstring" )] |
| 19 | { |
| 20 | let mut set: [bool; 256] = [false; 256]; |
| 21 | for needle: &B in needles.iter() { |
| 22 | let needle: &[u8] = needle.as_ref(); |
| 23 | if needle.len() != 1 { |
| 24 | return None; |
| 25 | } |
| 26 | set[usize::from(needle[0])] = true; |
| 27 | } |
| 28 | Some(ByteSet(set)) |
| 29 | } |
| 30 | } |
| 31 | } |
| 32 | |
| 33 | impl PrefilterI for ByteSet { |
| 34 | fn find(&self, haystack: &[u8], span: Span) -> Option<Span> { |
| 35 | haystack[span].iter().position(|&b| self.0[usize::from(b)]).map(|i| { |
| 36 | let start = span.start + i; |
| 37 | let end = start + 1; |
| 38 | Span { start, end } |
| 39 | }) |
| 40 | } |
| 41 | |
| 42 | fn prefix(&self, haystack: &[u8], span: Span) -> Option<Span> { |
| 43 | let b = *haystack.get(span.start)?; |
| 44 | if self.0[usize::from(b)] { |
| 45 | Some(Span { start: span.start, end: span.start + 1 }) |
| 46 | } else { |
| 47 | None |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | fn memory_usage(&self) -> usize { |
| 52 | 0 |
| 53 | } |
| 54 | |
| 55 | fn is_fast(&self) -> bool { |
| 56 | false |
| 57 | } |
| 58 | } |
| 59 | |