Skip to content

Commit 19b5a06

Browse files
committed
ByteSubstring: add an option to used an owned needle (not borrowed)
1 parent f607f4a commit 19b5a06

File tree

3 files changed

+22
-8
lines changed

3 files changed

+22
-8
lines changed

src/fallback.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// TODO: Try boxing the closure to see if we can hide the type
22
// TODO: Or maybe use a function pointer?
33

4+
use std::borrow::Cow;
5+
46
pub struct Bytes<F>
57
where
68
F: Fn(u8) -> bool,
@@ -22,11 +24,11 @@ where
2224
}
2325

2426
pub struct ByteSubstring<'a> {
25-
needle: &'a [u8],
27+
needle: Cow<'a, [u8]>,
2628
}
2729

2830
impl<'a> ByteSubstring<'a> {
29-
pub /* const */ fn new(needle: &'a[u8]) -> Self {
31+
pub /* const */ fn from_cow(needle: Cow<'a, [u8]>) -> Self {
3032
ByteSubstring { needle }
3133
}
3234

@@ -38,6 +40,6 @@ impl<'a> ByteSubstring<'a> {
3840
pub fn find(&self, haystack: &[u8]) -> Option<usize> {
3941
haystack
4042
.windows(self.needle.len())
41-
.position(|window| window == self.needle)
43+
.position(|window| window == self.needle.as_ref())
4244
}
4345
}

src/lib.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ extern crate proptest;
152152
extern crate region;
153153

154154
use std::marker::PhantomData;
155+
use std::borrow::Cow;
155156

156157
include!(concat!(env!("OUT_DIR"), "/src/macros.rs"));
157158

@@ -301,12 +302,17 @@ pub struct ByteSubstring<'a> {
301302

302303
impl<'a> ByteSubstring<'a> {
303304
pub /* const */ fn new(needle: &'a [u8]) -> Self {
305+
Self::from_cow(Cow::Borrowed(needle))
306+
}
307+
308+
pub /* const */ fn from_cow(needle: Cow<'a, [u8]>) -> Self {
309+
let needle_clone = needle.clone();
304310
ByteSubstring {
305311
#[cfg(target_arch = "x86_64")]
306-
simd: simd::ByteSubstring::new(needle),
312+
simd: simd::ByteSubstring::from_cow(needle),
307313

308314
#[cfg(not(target_feature = "sse4.2"))]
309-
fallback: fallback::ByteSubstring::new(needle),
315+
fallback: fallback::ByteSubstring::from_cow(needle_clone),
310316
}
311317
}
312318

src/simd.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::{
66
arch::x86_64::{
77
__m128i, _mm_cmpestri, _mm_cmpestrm, _mm_extract_epi16, _mm_loadu_si128, _SIDD_CMP_EQUAL_ORDERED,
88
},
9+
borrow::Cow,
910
cmp::min,
1011
slice,
1112
};
@@ -245,13 +246,18 @@ impl<'b> PackedCompareControl for &'b Bytes {
245246
}
246247

247248
pub struct ByteSubstring<'a> {
248-
complete_needle: &'a [u8],
249+
complete_needle: Cow<'a, [u8]>,
249250
needle: __m128i,
250251
needle_len: i32,
251252
}
252253

253254
impl<'a> ByteSubstring<'a> {
254-
pub /* const */ fn new(needle: &'a[u8]) -> Self {
255+
#[cfg(test)]
256+
pub /* const */ fn new(needle: &'a [u8]) -> Self {
257+
Self::from_cow(Cow::Borrowed(needle))
258+
}
259+
260+
pub /* const */ fn from_cow(needle: Cow<'a, [u8]>) -> Self {
255261
use std::cmp;
256262

257263
let mut simd_needle = [0; 16];
@@ -277,7 +283,7 @@ impl<'a> ByteSubstring<'a> {
277283
while let Some(idx) = find(PackedCompare::<_, _SIDD_CMP_EQUAL_ORDERED>(self), &haystack[offset..]) {
278284
let abs_offset = offset + idx;
279285
// Found a match, but is it really?
280-
if haystack[abs_offset..].starts_with(self.complete_needle) {
286+
if haystack[abs_offset..].starts_with(&self.complete_needle) {
281287
return Some(abs_offset);
282288
}
283289

0 commit comments

Comments
 (0)