MCPcopy Create free account
hub / github.com/ashvardanian/StringZilla / sz_rfind_byte_serial

Function sz_rfind_byte_serial

include/stringzilla/find.h:417–448  ·  view source on GitHub ↗

Find the last occurrence of a @b single-character needle in an arbitrary length haystack. * This implementation uses hardware-agnostic SWAR technique, to process 8 characters at a time. * Identical to `memrchr(haystack, needle[0], haystack_length)`. */

Source from the content-addressed store, hash-verified

415 * Identical to `memrchr(haystack, needle[0], haystack_length)`.
416 */
417sz_cptr_t sz_rfind_byte_serial(sz_cptr_t h_chars, sz_size_t h_length, sz_cptr_t n_chars) {
418
419 if (!h_length) return SZ_NULL_CHAR;
420 // Reinterpret as unsigned bytes so the SWAR broadcast below cannot sign-extend
421 // on platforms where `char` is signed (e.g. `-fsigned-char`). See issue #306.
422 sz_u8_t const *const h_start = (sz_u8_t const *)h_chars;
423 sz_u8_t const *const n = (sz_u8_t const *)n_chars;
424
425 // Reposition the `h` pointer to the end, as we will be walking backwards.
426 sz_u8_t const *h = h_start + h_length - 1;
427
428#if !SZ_IS_BIG_ENDIAN_ // Use SWAR only on little-endian platforms for brevity.
429#if !SZ_USE_MISALIGNED_LOADS // Process the misaligned head, to void UB on unaligned 64-bit loads.
430 for (; ((sz_size_t)(h + 1) & 7ull) && h >= h_start; --h)
431 if (*h == *n) return (sz_cptr_t)h;
432#endif
433
434 // Broadcast the n into every byte of a 64-bit integer to use SWAR
435 // techniques and process eight characters at a time.
436 sz_u64_vec_t h_vec, n_vec, match_vec;
437 n_vec.u64 = (sz_u64_t)*n * 0x0101010101010101ull;
438 for (; h >= h_start + 7; h -= 8) {
439 h_vec.u64 = *(sz_u64_t const *)(h - 7);
440 match_vec = sz_u64_each_byte_equal_(h_vec, n_vec);
441 if (match_vec.u64) return (sz_cptr_t)(h - sz_u64_clz(match_vec.u64) / 8);
442 }
443#endif
444
445 for (; h >= h_start; --h)
446 if (*h == *n) return (sz_cptr_t)h;
447 return SZ_NULL_CHAR;
448}
449
450/**
451 * @brief 2Byte-level equality comparison between two 64-bit integers.

Callers 5

sz_rfind_1byte_serial_Function · 0.85
sz_rfind_byte_westmereFunction · 0.85
sz_rfind_byte_haswellFunction · 0.85
sz_rfind_byte_neonFunction · 0.85
sz_rfind_byteFunction · 0.85

Calls 1

sz_u64_clzFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…