#[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*;
pub struct SimdScanner {
simd_enabled: bool,
}
impl SimdScanner {
pub fn new() -> Self {
Self {
simd_enabled: Self::detect_simd_support(),
}
}
#[cfg(target_arch = "x86_64")]
fn detect_simd_support() -> bool {
is_x86_feature_detected!("sse4.2") && is_x86_feature_detected!("avx2")
}
#[cfg(not(target_arch = "x86_64"))]
fn detect_simd_support() -> bool {
false
}
pub fn trim<'a>(&self, text: &'a str) -> &'a str {
if self.simd_enabled && text.len() >= 16 {
let trimmed_start = self.skip_whitespace_simd(text);
self.skip_whitespace_end_simd(trimmed_start)
} else {
text.trim()
}
}
pub fn contains_quoted_triple(&self, text: &str) -> bool {
if self.simd_enabled && text.len() >= 16 {
self.contains_pattern_simd(text, b"<<") || self.contains_pattern_simd(text, b">>")
} else {
text.contains("<<") || text.contains(">>")
}
}
pub fn contains_annotation_block(&self, text: &str) -> bool {
if self.simd_enabled && text.len() >= 16 {
self.contains_pattern_simd(text, b"{|") || self.contains_pattern_simd(text, b"|}")
} else {
text.contains("{|") || text.contains("|}")
}
}
pub fn count_quoted_open(&self, text: &str) -> usize {
if self.simd_enabled && text.len() >= 16 {
self.count_pattern_simd(text, b"<<")
} else {
text.matches("<<").count()
}
}
pub fn count_quoted_close(&self, text: &str) -> usize {
if self.simd_enabled && text.len() >= 16 {
self.count_pattern_simd(text, b">>")
} else {
text.matches(">>").count()
}
}
pub fn is_quoted_balanced(&self, text: &str) -> bool {
self.count_quoted_open(text) == self.count_quoted_close(text)
}
#[cfg(target_arch = "x86_64")]
#[target_feature(enable = "sse4.2,avx2")]
unsafe fn skip_whitespace_simd_impl<'a>(&self, text: &'a str) -> &'a str {
let bytes = text.as_bytes();
let len = bytes.len();
if len < 16 {
return text.trim_start();
}
let mut offset = 0;
while offset + 16 <= len {
let chunk = _mm_loadu_si128(bytes.as_ptr().add(offset) as *const __m128i);
let spaces = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b' ' as i8));
let tabs = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\t' as i8));
let newlines = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8));
let carriage = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\r' as i8));
let ws1 = _mm_or_si128(spaces, tabs);
let ws2 = _mm_or_si128(newlines, carriage);
let whitespace = _mm_or_si128(ws1, ws2);
let mask = _mm_movemask_epi8(whitespace) as u32;
if mask == 0xFFFF {
offset += 16;
} else if mask == 0 {
break;
} else {
let trailing_zeros = mask.trailing_ones() as usize;
offset += trailing_zeros;
break;
}
}
while offset < len && bytes[offset].is_ascii_whitespace() {
offset += 1;
}
&text[offset..]
}
#[cfg(target_arch = "x86_64")]
fn skip_whitespace_simd<'a>(&self, text: &'a str) -> &'a str {
unsafe { self.skip_whitespace_simd_impl(text) }
}
#[cfg(not(target_arch = "x86_64"))]
fn skip_whitespace_simd<'a>(&self, text: &'a str) -> &'a str {
text.trim_start()
}
#[cfg(target_arch = "x86_64")]
#[target_feature(enable = "sse4.2,avx2")]
unsafe fn skip_whitespace_end_simd_impl<'a>(&self, text: &'a str) -> &'a str {
let bytes = text.as_bytes();
let len = bytes.len();
if len < 16 {
return text.trim_end();
}
let mut end = len;
while end >= 16 {
let chunk = _mm_loadu_si128(bytes.as_ptr().add(end - 16) as *const __m128i);
let spaces = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b' ' as i8));
let tabs = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\t' as i8));
let newlines = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8));
let carriage = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\r' as i8));
let ws1 = _mm_or_si128(spaces, tabs);
let ws2 = _mm_or_si128(newlines, carriage);
let whitespace = _mm_or_si128(ws1, ws2);
let mask = _mm_movemask_epi8(whitespace) as u32;
if mask == 0xFFFF {
end -= 16;
} else if mask == 0 {
break;
} else {
let leading_zeros = mask.leading_ones() as usize;
end -= leading_zeros;
break;
}
}
while end > 0 && bytes[end - 1].is_ascii_whitespace() {
end -= 1;
}
&text[..end]
}
#[cfg(target_arch = "x86_64")]
fn skip_whitespace_end_simd<'a>(&self, text: &'a str) -> &'a str {
unsafe { self.skip_whitespace_end_simd_impl(text) }
}
#[cfg(not(target_arch = "x86_64"))]
fn skip_whitespace_end_simd<'a>(&self, text: &'a str) -> &'a str {
text.trim_end()
}
#[cfg(target_arch = "x86_64")]
#[target_feature(enable = "sse4.2,avx2")]
unsafe fn contains_pattern_simd_impl(&self, text: &str, pattern: &[u8]) -> bool {
if pattern.len() != 2 {
return text.as_bytes().windows(pattern.len()).any(|w| w == pattern);
}
let bytes = text.as_bytes();
let len = bytes.len();
if len < 16 {
return bytes.windows(2).any(|w| w == pattern);
}
let pattern_first = _mm_set1_epi8(pattern[0] as i8);
let _pattern_second = _mm_set1_epi8(pattern[1] as i8);
let mut offset = 0;
while offset + 16 <= len {
let chunk = _mm_loadu_si128(bytes.as_ptr().add(offset) as *const __m128i);
let first_match = _mm_cmpeq_epi8(chunk, pattern_first);
let mask = _mm_movemask_epi8(first_match) as u32;
if mask != 0 {
for bit in 0..16 {
if (mask & (1 << bit)) != 0 && offset + bit + 1 < len {
if bytes[offset + bit + 1] == pattern[1] {
return true;
}
}
}
}
offset += 16;
}
bytes[offset..].windows(2).any(|w| w == pattern)
}
#[cfg(target_arch = "x86_64")]
fn contains_pattern_simd(&self, text: &str, pattern: &[u8]) -> bool {
unsafe { self.contains_pattern_simd_impl(text, pattern) }
}
#[cfg(not(target_arch = "x86_64"))]
fn contains_pattern_simd(&self, text: &str, pattern: &[u8]) -> bool {
text.as_bytes().windows(pattern.len()).any(|w| w == pattern)
}
#[cfg(target_arch = "x86_64")]
fn count_pattern_simd(&self, text: &str, pattern: &[u8]) -> usize {
if pattern.len() != 2 {
return text
.as_bytes()
.windows(pattern.len())
.filter(|w| *w == pattern)
.count();
}
let bytes = text.as_bytes();
let len = bytes.len();
let mut count = 0;
if len < 16 {
return bytes.windows(2).filter(|w| *w == pattern).count();
}
let mut offset = 0;
unsafe {
let pattern_first = _mm_set1_epi8(pattern[0] as i8);
while offset + 16 <= len {
let chunk = _mm_loadu_si128(bytes.as_ptr().add(offset) as *const __m128i);
let first_match = _mm_cmpeq_epi8(chunk, pattern_first);
let mask = _mm_movemask_epi8(first_match) as u32;
if mask != 0 {
for bit in 0..16 {
if (mask & (1 << bit)) != 0 && offset + bit + 1 < len {
if bytes[offset + bit + 1] == pattern[1] {
count += 1;
}
}
}
}
offset += 16;
}
}
count + bytes[offset..].windows(2).filter(|w| *w == pattern).count()
}
#[cfg(not(target_arch = "x86_64"))]
fn count_pattern_simd(&self, text: &str, pattern: &[u8]) -> usize {
text.as_bytes()
.windows(pattern.len())
.filter(|w| *w == pattern)
.count()
}
}
impl Default for SimdScanner {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_trim() {
let scanner = SimdScanner::new();
assert_eq!(scanner.trim(" hello "), "hello");
assert_eq!(scanner.trim("\t\nhello\r\n"), "hello");
assert_eq!(scanner.trim("hello"), "hello");
assert_eq!(scanner.trim(""), "");
}
#[test]
fn test_contains_quoted_triple() {
let scanner = SimdScanner::new();
assert!(scanner.contains_quoted_triple("<< :s :p :o >>"));
assert!(scanner.contains_quoted_triple("some text << quoted"));
assert!(scanner.contains_quoted_triple("some text >> end"));
assert!(!scanner.contains_quoted_triple("no quoted triple here"));
assert!(!scanner.contains_quoted_triple(""));
let long_text = format!("{:100}<< :s :p :o >>", "prefix ");
assert!(scanner.contains_quoted_triple(&long_text));
}
#[test]
fn test_contains_annotation_block() {
let scanner = SimdScanner::new();
assert!(scanner.contains_annotation_block("{| :meta :value |}"));
assert!(scanner.contains_annotation_block("some text {| annotation"));
assert!(scanner.contains_annotation_block("some text |} end"));
assert!(!scanner.contains_annotation_block("no annotation here"));
assert!(!scanner.contains_annotation_block(""));
}
#[test]
fn test_count_quoted() {
let scanner = SimdScanner::new();
assert_eq!(scanner.count_quoted_open("<< :s :p :o >>"), 1);
assert_eq!(scanner.count_quoted_close("<< :s :p :o >>"), 1);
assert_eq!(scanner.count_quoted_open("<< << nested >> >>"), 2);
assert_eq!(scanner.count_quoted_close("<< << nested >> >>"), 2);
assert_eq!(scanner.count_quoted_open("no quoted"), 0);
let long_text = format!("{:100}<< :s :p :o >> {:100}<< :s2 :p2 :o2 >>", "", "");
assert_eq!(scanner.count_quoted_open(&long_text), 2);
assert_eq!(scanner.count_quoted_close(&long_text), 2);
}
#[test]
fn test_is_quoted_balanced() {
let scanner = SimdScanner::new();
assert!(scanner.is_quoted_balanced("<< :s :p :o >>"));
assert!(scanner.is_quoted_balanced("<< << nested >> >>"));
assert!(!scanner.is_quoted_balanced("<< :s :p :o"));
assert!(!scanner.is_quoted_balanced(":s :p :o >>"));
assert!(scanner.is_quoted_balanced("no quoted"));
}
#[test]
fn test_simd_vs_scalar_consistency() {
let scanner = SimdScanner::new();
let long_text = format!("{:200}<< :long :text :here >>", "");
let test_cases = vec![
" << :s :p :o >> {| :meta :value |} ",
"<< << nested >> >>",
"\"string with <<\" # comment with >>",
&long_text,
];
for case in test_cases {
let trimmed = scanner.trim(case);
assert_eq!(trimmed, case.trim());
let has_quoted = scanner.contains_quoted_triple(case);
assert_eq!(has_quoted, case.contains("<<") || case.contains(">>"));
let has_annotation = scanner.contains_annotation_block(case);
assert_eq!(has_annotation, case.contains("{|") || case.contains("|}"));
}
}
}