rsonpath-lib 0.10.0

Blazing fast JSONPath query engine powered by SIMD. Core library of `rsonpath`.
Documentation
#[cfg(target_arch = "x86")]
use ::core::arch::x86::*;
#[cfg(target_arch = "x86_64")]
use ::core::arch::x86_64::*;

const LOWER_NIBBLE_MASK_ARRAY: [u8; 32] = [
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x01, 0x02, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x01, 0x02, 0x01, 0xff, 0xff,
];
const UPPER_NIBBLE_MASK_ARRAY: [u8; 32] = [
    0xfe, 0xfe, 0x10, 0x10, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x10,
    0x10, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
];
const COMMAS_TOGGLE_MASK_ARRAY: [u8; 32] = [
    0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];
const COLON_TOGGLE_MASK_ARRAY: [u8; 32] = [
    0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
];

#[target_feature(enable = "avx2")]
#[inline]
pub(crate) unsafe fn upper_nibble_zeroing_mask() -> __m256i {
    _mm256_set1_epi8(0x0F)
}

#[target_feature(enable = "avx2")]
#[inline]
pub(crate) unsafe fn lower_nibble_mask() -> __m256i {
    _mm256_loadu_si256(LOWER_NIBBLE_MASK_ARRAY.as_ptr().cast::<__m256i>())
}

#[target_feature(enable = "avx2")]
#[inline]
pub(crate) unsafe fn upper_nibble_mask() -> __m256i {
    _mm256_loadu_si256(UPPER_NIBBLE_MASK_ARRAY.as_ptr().cast::<__m256i>())
}

#[target_feature(enable = "avx2")]
#[inline]
pub(crate) unsafe fn commas_toggle_mask() -> __m256i {
    _mm256_loadu_si256(COMMAS_TOGGLE_MASK_ARRAY.as_ptr().cast::<__m256i>())
}

#[target_feature(enable = "avx2")]
#[inline]
pub(crate) unsafe fn colons_toggle_mask() -> __m256i {
    _mm256_loadu_si256(COLON_TOGGLE_MASK_ARRAY.as_ptr().cast::<__m256i>())
}

#[target_feature(enable = "avx2")]
#[inline]
pub(crate) unsafe fn colons_and_commas_toggle_mask() -> __m256i {
    _mm256_or_si256(colons_toggle_mask(), commas_toggle_mask())
}

pub(crate) struct BlockClassifier256 {
    upper_nibble_mask: __m256i,
}

impl BlockClassifier256 {
    #[target_feature(enable = "avx2")]
    #[inline]
    pub(crate) unsafe fn new() -> Self {
        Self {
            upper_nibble_mask: upper_nibble_mask(),
        }
    }

    #[target_feature(enable = "avx2")]
    #[inline]
    pub(crate) unsafe fn toggle_commas(&mut self) {
        self.upper_nibble_mask = _mm256_xor_si256(self.upper_nibble_mask, commas_toggle_mask());
    }

    #[target_feature(enable = "avx2")]
    #[inline]
    pub(crate) unsafe fn toggle_colons(&mut self) {
        self.upper_nibble_mask = _mm256_xor_si256(self.upper_nibble_mask, colons_toggle_mask());
    }

    #[target_feature(enable = "avx2")]
    #[inline]
    pub(crate) unsafe fn toggle_colons_and_commas(&mut self) {
        self.upper_nibble_mask = _mm256_xor_si256(self.upper_nibble_mask, colons_and_commas_toggle_mask());
    }

    #[target_feature(enable = "avx2")]
    #[inline]
    pub(crate) unsafe fn classify_block(&self, block: &[u8]) -> BlockClassification256 {
        let byte_vector = _mm256_loadu_si256(block.as_ptr().cast::<__m256i>());
        let shifted_byte_vector = _mm256_srli_epi16::<4>(byte_vector);
        let upper_nibble_byte_vector = _mm256_and_si256(shifted_byte_vector, upper_nibble_zeroing_mask());
        let lower_nibble_lookup = _mm256_shuffle_epi8(lower_nibble_mask(), byte_vector);
        let upper_nibble_lookup = _mm256_shuffle_epi8(self.upper_nibble_mask, upper_nibble_byte_vector);
        let structural_vector = _mm256_cmpeq_epi8(lower_nibble_lookup, upper_nibble_lookup);
        let structural = _mm256_movemask_epi8(structural_vector) as u32;

        BlockClassification256 { structural }
    }
}

pub(crate) struct BlockClassification256 {
    pub(crate) structural: u32,
}