Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

Commit

Permalink
perf: auto-vectorized try_check_offsets
Browse files Browse the repository at this point in the history
  • Loading branch information
ritchie46 committed Nov 28, 2022
1 parent 368aacc commit cf34814
Showing 1 changed file with 29 additions and 11 deletions.
40 changes: 29 additions & 11 deletions src/array/specification.rs
Expand Up @@ -76,17 +76,35 @@ pub fn try_check_offsets_and_utf8<O: Offset>(offsets: &[O], values: &[u8]) -> Re
/// Checks that `offsets` is monotonically increasing, and all offsets are less than or equal to
/// `values_len`.
pub fn try_check_offsets<O: Offset>(offsets: &[O], values_len: usize) -> Result<()> {
if offsets.windows(2).any(|window| window[0] > window[1]) {
Err(Error::oos("offsets must be monotonically increasing"))
} else if offsets
.last()
.map_or(true, |last| last.to_usize() > values_len)
{
Err(Error::oos(
"offsets must have at least one element and must not exceed values length",
))
} else {
Ok(())
// this code is carefully constructed to auto-vectorize, don't change naively!
match offsets.first() {
None => Ok(()),
Some(first) => {
let mut previous = *first;
let mut any_invalid = false;

// This loop will auto-vectorize because there is not any break,
// an invalid value will be returned once the whole offsets buffer is processed.
for offset in offsets {
if previous > *offset {
any_invalid = true
}
previous = *offset;
}

if any_invalid {
Err(Error::oos("offsets must be monotonically increasing"))
} else if offsets
.last()
.map_or(true, |last| last.to_usize() > values_len)
{
Err(Error::oos(
"offsets must have at least one element and must not exceed values length",
))
} else {
Ok(())
}
}
}
}

Expand Down

0 comments on commit cf34814

Please sign in to comment.