1 use core::arch::x86_64::__m128i;
2
3 use crate::memmem::{
4 prefilter::{PrefilterFnTy, PrefilterState},
5 NeedleInfo,
6 };
7
8 // Check that the functions below satisfy the Prefilter function type.
9 const _: PrefilterFnTy = find;
10
11 /// An SSE2 accelerated candidate finder for single-substring search.
12 ///
13 /// # Safety
14 ///
15 /// Callers must ensure that the sse2 CPU feature is enabled in the current
16 /// environment. This feature should be enabled in all x86_64 targets.
17 #[target_feature(enable = "sse2")]
find( prestate: &mut PrefilterState, ninfo: &NeedleInfo, haystack: &[u8], needle: &[u8], ) -> Option<usize>18 pub(crate) unsafe fn find(
19 prestate: &mut PrefilterState,
20 ninfo: &NeedleInfo,
21 haystack: &[u8],
22 needle: &[u8],
23 ) -> Option<usize> {
24 // If the haystack is too small for SSE2, then just run memchr on the
25 // rarest byte and be done with it. (It is likely that this code path is
26 // rarely exercised, since a higher level routine will probably dispatch to
27 // Rabin-Karp for such a small haystack.)
28 fn simple_memchr_fallback(
29 _prestate: &mut PrefilterState,
30 ninfo: &NeedleInfo,
31 haystack: &[u8],
32 needle: &[u8],
33 ) -> Option<usize> {
34 let (rare, _) = ninfo.rarebytes.as_rare_ordered_usize();
35 crate::memchr(needle[rare], haystack).map(|i| i.saturating_sub(rare))
36 }
37 super::super::genericsimd::find::<__m128i>(
38 prestate,
39 ninfo,
40 haystack,
41 needle,
42 simple_memchr_fallback,
43 )
44 }
45
46 #[cfg(all(test, feature = "std"))]
47 mod tests {
48 #[test]
49 #[cfg(not(miri))]
prefilter_permutations()50 fn prefilter_permutations() {
51 use crate::memmem::prefilter::tests::PrefilterTest;
52 // SAFETY: super::find is safe to call for all inputs on x86.
53 unsafe { PrefilterTest::run_all_tests(super::find) };
54 }
55 }
56