@@ -112,11 +112,6 @@ trait NeedleWithSize: Needle {
112112 self . as_bytes ( ) . len ( )
113113 }
114114 }
115-
116- #[ inline]
117- fn is_empty ( & self ) -> bool {
118- self . size ( ) == 0
119- }
120115}
121116
122117impl < N : Needle + ?Sized > NeedleWithSize for N { }
@@ -192,96 +187,106 @@ impl<T: Vector, V: Vector + From<T>> From<&VectorHash<T>> for VectorHash<V> {
192187 }
193188}
194189
195- trait Searcher < N : NeedleWithSize + ?Sized > {
196- fn needle ( & self ) -> & N ;
190+ #[ multiversion:: multiversion]
191+ #[ clone( target = "[x86|x86_64]+avx2" ) ]
192+ #[ clone( target = "wasm32+simd128" ) ]
193+ #[ clone( target = "aarch64+neon" ) ]
194+ unsafe fn vector_search_in_chunk < N : NeedleWithSize + ?Sized , V : Vector > (
195+ needle : & N ,
196+ position : usize ,
197+ hash : & VectorHash < V > ,
198+ start : * const u8 ,
199+ mask : u32 ,
200+ ) -> bool {
201+ let first = V :: load ( start) ;
202+ let last = V :: load ( start. add ( position) ) ;
203+
204+ let eq_first = V :: lanes_eq ( hash. first , first) ;
205+ let eq_last = V :: lanes_eq ( hash. last , last) ;
206+
207+ let eq = V :: bitwise_and ( eq_first, eq_last) ;
208+ let mut eq = V :: to_bitmask ( eq) & mask;
209+
210+ let chunk = start. add ( 1 ) ;
211+ let size = needle. size ( ) - 1 ;
212+ let needle = needle. as_bytes ( ) . as_ptr ( ) . add ( 1 ) ;
213+
214+ while eq != 0 {
215+ let chunk = chunk. add ( eq. trailing_zeros ( ) as usize ) ;
216+ let equal = match N :: SIZE {
217+ Some ( 0 ) => unreachable ! ( ) ,
218+ Some ( 1 ) => dispatch ! ( memcmp:: specialized:: <0 >( chunk, needle) ) ,
219+ Some ( 2 ) => dispatch ! ( memcmp:: specialized:: <1 >( chunk, needle) ) ,
220+ Some ( 3 ) => dispatch ! ( memcmp:: specialized:: <2 >( chunk, needle) ) ,
221+ Some ( 4 ) => dispatch ! ( memcmp:: specialized:: <3 >( chunk, needle) ) ,
222+ Some ( 5 ) => dispatch ! ( memcmp:: specialized:: <4 >( chunk, needle) ) ,
223+ Some ( 6 ) => dispatch ! ( memcmp:: specialized:: <5 >( chunk, needle) ) ,
224+ Some ( 7 ) => dispatch ! ( memcmp:: specialized:: <6 >( chunk, needle) ) ,
225+ Some ( 8 ) => dispatch ! ( memcmp:: specialized:: <7 >( chunk, needle) ) ,
226+ Some ( 9 ) => dispatch ! ( memcmp:: specialized:: <8 >( chunk, needle) ) ,
227+ Some ( 10 ) => dispatch ! ( memcmp:: specialized:: <9 >( chunk, needle) ) ,
228+ Some ( 11 ) => dispatch ! ( memcmp:: specialized:: <10 >( chunk, needle) ) ,
229+ Some ( 12 ) => dispatch ! ( memcmp:: specialized:: <11 >( chunk, needle) ) ,
230+ Some ( 13 ) => dispatch ! ( memcmp:: specialized:: <12 >( chunk, needle) ) ,
231+ Some ( 14 ) => dispatch ! ( memcmp:: specialized:: <13 >( chunk, needle) ) ,
232+ Some ( 15 ) => dispatch ! ( memcmp:: specialized:: <14 >( chunk, needle) ) ,
233+ Some ( 16 ) => dispatch ! ( memcmp:: specialized:: <15 >( chunk, needle) ) ,
234+ _ => dispatch ! ( memcmp:: generic( chunk, needle, size) ) ,
235+ } ;
236+ if equal {
237+ return true ;
238+ }
197239
198- fn position ( & self ) -> usize ;
240+ eq = dispatch ! ( bits:: clear_leftmost_set( eq) ) ;
241+ }
199242
200- #[ multiversion:: multiversion]
201- #[ clone( target = "[x86|x86_64]+avx2" ) ]
202- #[ clone( target = "wasm32+simd128" ) ]
203- #[ clone( target = "aarch64+neon" ) ]
204- unsafe fn vector_search_in_chunk < V : Vector > (
205- & self ,
206- hash : & VectorHash < V > ,
207- start : * const u8 ,
208- mask : u32 ,
209- ) -> bool {
210- let first = V :: load ( start) ;
211- let last = V :: load ( start. add ( self . position ( ) ) ) ;
212-
213- let eq_first = V :: lanes_eq ( hash. first , first) ;
214- let eq_last = V :: lanes_eq ( hash. last , last) ;
215-
216- let eq = V :: bitwise_and ( eq_first, eq_last) ;
217- let mut eq = V :: to_bitmask ( eq) & mask;
218-
219- let chunk = start. add ( 1 ) ;
220- let needle = self . needle ( ) . as_bytes ( ) . as_ptr ( ) . add ( 1 ) ;
221-
222- while eq != 0 {
223- let chunk = chunk. add ( eq. trailing_zeros ( ) as usize ) ;
224- let equal = match N :: SIZE {
225- Some ( 0 ) => unreachable ! ( ) ,
226- Some ( 1 ) => dispatch ! ( memcmp:: specialized:: <0 >( chunk, needle) ) ,
227- Some ( 2 ) => dispatch ! ( memcmp:: specialized:: <1 >( chunk, needle) ) ,
228- Some ( 3 ) => dispatch ! ( memcmp:: specialized:: <2 >( chunk, needle) ) ,
229- Some ( 4 ) => dispatch ! ( memcmp:: specialized:: <3 >( chunk, needle) ) ,
230- Some ( 5 ) => dispatch ! ( memcmp:: specialized:: <4 >( chunk, needle) ) ,
231- Some ( 6 ) => dispatch ! ( memcmp:: specialized:: <5 >( chunk, needle) ) ,
232- Some ( 7 ) => dispatch ! ( memcmp:: specialized:: <6 >( chunk, needle) ) ,
233- Some ( 8 ) => dispatch ! ( memcmp:: specialized:: <7 >( chunk, needle) ) ,
234- Some ( 9 ) => dispatch ! ( memcmp:: specialized:: <8 >( chunk, needle) ) ,
235- Some ( 10 ) => dispatch ! ( memcmp:: specialized:: <9 >( chunk, needle) ) ,
236- Some ( 11 ) => dispatch ! ( memcmp:: specialized:: <10 >( chunk, needle) ) ,
237- Some ( 12 ) => dispatch ! ( memcmp:: specialized:: <11 >( chunk, needle) ) ,
238- Some ( 13 ) => dispatch ! ( memcmp:: specialized:: <12 >( chunk, needle) ) ,
239- Some ( 14 ) => dispatch ! ( memcmp:: specialized:: <13 >( chunk, needle) ) ,
240- Some ( 15 ) => dispatch ! ( memcmp:: specialized:: <14 >( chunk, needle) ) ,
241- Some ( 16 ) => dispatch ! ( memcmp:: specialized:: <15 >( chunk, needle) ) ,
242- _ => dispatch ! ( memcmp:: generic( chunk, needle, self . needle( ) . size( ) - 1 ) ) ,
243- } ;
244- if equal {
245- return true ;
246- }
243+ false
244+ }
247245
248- eq = dispatch ! ( bits:: clear_leftmost_set( eq) ) ;
246+ #[ allow( dead_code) ]
247+ #[ multiversion:: multiversion]
248+ #[ clone( target = "[x86|x86_64]+avx2" ) ]
249+ #[ clone( target = "wasm32+simd128" ) ]
250+ #[ clone( target = "aarch64+neon" ) ]
251+ pub ( crate ) unsafe fn vector_search_in < N : NeedleWithSize + ?Sized , V : Vector > (
252+ needle : & N ,
253+ position : usize ,
254+ haystack : & [ u8 ] ,
255+ end : usize ,
256+ hash : & VectorHash < V > ,
257+ ) -> bool {
258+ debug_assert ! ( haystack. len( ) >= needle. size( ) ) ;
259+
260+ let mut chunks = haystack[ ..end] . chunks_exact ( V :: LANES ) ;
261+ for chunk in & mut chunks {
262+ if dispatch ! ( vector_search_in_chunk(
263+ needle,
264+ position,
265+ hash,
266+ chunk. as_ptr( ) ,
267+ u32 :: MAX
268+ ) ) {
269+ return true ;
249270 }
271+ }
250272
251- false
252- }
253-
254- #[ multiversion:: multiversion]
255- #[ clone( target = "[x86|x86_64]+avx2" ) ]
256- #[ clone( target = "wasm32+simd128" ) ]
257- #[ clone( target = "aarch64+neon" ) ]
258- unsafe fn vector_search_in < V : Vector > (
259- & self ,
260- haystack : & [ u8 ] ,
261- end : usize ,
262- hash : & VectorHash < V > ,
263- ) -> bool {
264- debug_assert ! ( haystack. len( ) >= self . needle( ) . size( ) ) ;
265-
266- let mut chunks = haystack[ ..end] . chunks_exact ( V :: LANES ) ;
267- for chunk in & mut chunks {
268- if dispatch ! ( self . vector_search_in_chunk( hash, chunk. as_ptr( ) , u32 :: MAX ) ) {
269- return true ;
270- }
273+ let remainder = chunks. remainder ( ) . len ( ) ;
274+ if remainder > 0 {
275+ let start = haystack. as_ptr ( ) . add ( end - V :: LANES ) ;
276+ let mask = u32:: MAX << ( V :: LANES - remainder) ;
277+
278+ if dispatch ! ( vector_search_in_chunk( needle, position, hash, start, mask) ) {
279+ return true ;
271280 }
281+ }
272282
273- let remainder = chunks. remainder ( ) . len ( ) ;
274- if remainder > 0 {
275- let start = haystack. as_ptr ( ) . add ( end - V :: LANES ) ;
276- let mask = u32:: MAX << ( V :: LANES - remainder) ;
283+ false
284+ }
277285
278- if dispatch ! ( self . vector_search_in_chunk( hash, start, mask) ) {
279- return true ;
280- }
281- }
286+ trait Searcher < N : NeedleWithSize + ?Sized > {
287+ fn needle ( & self ) -> & N ;
282288
283- false
284- }
289+ fn position ( & self ) -> usize ;
285290}
286291
287292#[ cfg( test) ]
0 commit comments