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 | |