Skip to content

Commit

Permalink
Decide that BSATN byte that ain't 0 or 1 is not a valid AV::Bool (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Centril authored Nov 29, 2024
1 parent 80dff96 commit 6aa08ce
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 4 deletions.
11 changes: 10 additions & 1 deletion crates/sats/src/bsatn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ impl ToBsatn for ProductValue {

#[cfg(test)]
mod tests {
use super::to_vec;
use super::{to_vec, DecodeError};
use crate::proptest::generate_typed_value;
use crate::{meta_type::MetaType, AlgebraicType, AlgebraicValue};
use proptest::prelude::*;
Expand All @@ -179,5 +179,14 @@ mod tests {
let val_decoded = AlgebraicValue::decode(&ty, &mut &bytes[..]).unwrap();
prop_assert_eq!(val, val_decoded);
}

#[test]
fn bsatn_non_zero_one_u8_aint_bool(val in 2u8..) {
let bytes = [val];
prop_assert_eq!(
AlgebraicValue::decode(&AlgebraicType::Bool, &mut &bytes[..]),
Err(DecodeError::InvalidBool(val))
);
}
}
}
7 changes: 6 additions & 1 deletion crates/sats/src/bsatn/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,12 @@ impl<'de, 'a, R: BufReader<'de>> de::Deserializer<'de> for Deserializer<'a, R> {
}

fn deserialize_bool(self) -> Result<bool, Self::Error> {
self.reader.get_u8().map(|x| x != 0)
let byte = self.reader.get_u8()?;
match byte {
0 => Ok(false),
1 => Ok(true),
b => Err(DecodeError::InvalidBool(b)),
}
}
fn deserialize_u8(self) -> Result<u8, DecodeError> {
self.reader.get_u8()
Expand Down
7 changes: 5 additions & 2 deletions crates/sats/src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ pub enum DecodeError {
InvalidTag { tag: u8, sum_name: Option<String> },
/// Expected data to be UTF-8 but it wasn't.
InvalidUtf8,
/// Expected the byte to be 0 or 1 to be a valid bool.
InvalidBool(u8),
/// Custom error not in the other variants of `DecodeError`.
Other(String),
}
Expand All @@ -40,6 +42,7 @@ impl fmt::Display for DecodeError {
)
}
DecodeError::InvalidUtf8 => f.write_str("invalid utf8"),
DecodeError::InvalidBool(byte) => write!(f, "byte {byte} not valid as `bool` (must be 0 or 1)"),
DecodeError::Other(err) => f.write_str(err),
}
}
Expand Down Expand Up @@ -158,7 +161,7 @@ pub trait BufReader<'de> {
/// Reads and returns a byte slice of `.len() = size` advancing the cursor.
#[inline]
fn get_slice(&mut self, size: usize) -> Result<&'de [u8], DecodeError> {
self.get_chunk(size).ok_or(DecodeError::BufferLength {
self.get_chunk(size).ok_or_else(|| DecodeError::BufferLength {
for_type: "[u8]",
expected: size,
given: self.remaining(),
Expand All @@ -168,7 +171,7 @@ pub trait BufReader<'de> {
/// Reads an array of type `[u8; N]` from the input.
#[inline]
fn get_array<const N: usize>(&mut self) -> Result<&'de [u8; N], DecodeError> {
self.get_array_chunk().ok_or(DecodeError::BufferLength {
self.get_array_chunk().ok_or_else(|| DecodeError::BufferLength {
for_type: "[u8; _]",
expected: N,
given: self.remaining(),
Expand Down

2 comments on commit 6aa08ce

@github-actions
Copy link

@github-actions github-actions bot commented on 6aa08ce Nov 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmarking failed. Please check the workflow run for details.

@github-actions
Copy link

@github-actions github-actions bot commented on 6aa08ce Nov 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Callgrind benchmark results

Callgrind Benchmark Report

These benchmarks were run using callgrind,
an instruction-level profiler. They allow comparisons between sqlite (sqlite), SpacetimeDB running through a module (stdb_module), and the underlying SpacetimeDB data storage engine (stdb_raw). Callgrind emulates a CPU to collect the below estimates.

Measurement changes larger than five percent are in bold.

In-memory benchmarks

callgrind: empty transaction

db total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw 6396 6432 -0.56% 6516 6540 -0.37%
sqlite 5619 5609 0.18% 6107 6073 0.56%

callgrind: filter

db schema indices count preload _column data_type total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str no_index 64 128 1 u64 74672 74706 -0.05% 75080 75138 -0.08%
stdb_raw u32_u64_str no_index 64 128 2 string 116914 116948 -0.03% 117638 117590 0.04%
stdb_raw u32_u64_str btree_each_column 64 128 2 string 25080 25116 -0.14% 25672 25634 0.15%
stdb_raw u32_u64_str btree_each_column 64 128 1 u64 24048 24084 -0.15% 24508 24544 -0.15%
sqlite u32_u64_str no_index 64 128 2 string 144416 144415 0.00% 146000 145831 0.12%
sqlite u32_u64_str no_index 64 128 1 u64 123764 123763 0.00% 125052 125029 0.02%
sqlite u32_u64_str btree_each_column 64 128 1 u64 131081 131113 -0.02% 132569 132571 -0.00%
sqlite u32_u64_str btree_each_column 64 128 2 string 134223 134222 0.00% 135967 135822 0.11%

callgrind: insert bulk

db schema indices count preload total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str unique_0 64 128 878291 881006 -0.31% 925371 935734 -1.11%
stdb_raw u32_u64_str btree_each_column 64 128 1025894 1033086 -0.70% 1049124 1057652 -0.81%
sqlite u32_u64_str unique_0 64 128 399362 399360 0.00% 417030 418734 -0.41%
sqlite u32_u64_str btree_each_column 64 128 984613 984611 0.00% 1018845 1018529 0.03%

callgrind: iterate

db schema indices count total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str unique_0 1024 138372 138485 -0.08% 138524 138559 -0.03%
stdb_raw u32_u64_str unique_0 64 15797 15910 -0.71% 15941 15972 -0.19%
sqlite u32_u64_str unique_0 1024 1042718 1042718 0.00% 1046184 1046054 0.01%
sqlite u32_u64_str unique_0 64 74704 74704 0.00% 75800 75782 0.02%

callgrind: serialize_product_value

count format total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
64 json 47528 47528 0.00% 50180 50180 0.00%
64 bsatn 25509 25509 0.00% 27719 27719 0.00%
16 bsatn 8200 8200 0.00% 9560 9560 0.00%
16 json 12188 12188 0.00% 14092 14092 0.00%

callgrind: update bulk

db schema indices count preload total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str unique_0 1024 1024 20497363 20571891 -0.36% 21076219 21253947 -0.84%
stdb_raw u32_u64_str unique_0 64 128 1283358 1289401 -0.47% 1355000 1367039 -0.88%
sqlite u32_u64_str unique_0 1024 1024 1802079 1802137 -0.00% 1811245 1811313 -0.00%
sqlite u32_u64_str unique_0 64 128 128482 128540 -0.05% 131312 131492 -0.14%
On-disk benchmarks

callgrind: empty transaction

db total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw 6401 6437 -0.56% 6533 6541 -0.12%
sqlite 5651 5651 0.00% 6123 6141 -0.29%

callgrind: filter

db schema indices count preload _column data_type total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str no_index 64 128 1 u64 74677 74711 -0.05% 75045 75127 -0.11%
stdb_raw u32_u64_str no_index 64 128 2 string 116919 116974 -0.05% 117531 117520 0.01%
stdb_raw u32_u64_str btree_each_column 64 128 2 string 25085 25122 -0.15% 25633 25620 0.05%
stdb_raw u32_u64_str btree_each_column 64 128 1 u64 24053 24089 -0.15% 24465 24537 -0.29%
sqlite u32_u64_str no_index 64 128 1 u64 125703 125684 0.02% 127339 127278 0.05%
sqlite u32_u64_str no_index 64 128 2 string 146337 146336 0.00% 148233 148128 0.07%
sqlite u32_u64_str btree_each_column 64 128 2 string 136419 136418 0.00% 138571 138398 0.13%
sqlite u32_u64_str btree_each_column 64 128 1 u64 133177 133176 0.00% 135065 134958 0.08%

callgrind: insert bulk

db schema indices count preload total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str unique_0 64 128 825868 829601 -0.45% 871990 883459 -1.30%
stdb_raw u32_u64_str btree_each_column 64 128 973880 975974 -0.21% 995272 999630 -0.44%
sqlite u32_u64_str unique_0 64 128 416916 416914 0.00% 433964 435856 -0.43%
sqlite u32_u64_str btree_each_column 64 128 1023160 1023158 0.00% 1057370 1056174 0.11%

callgrind: iterate

db schema indices count total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str unique_0 1024 138377 138490 -0.08% 138509 138576 -0.05%
stdb_raw u32_u64_str unique_0 64 15802 15915 -0.71% 15934 15977 -0.27%
sqlite u32_u64_str unique_0 1024 1045829 1045796 0.00% 1049731 1049672 0.01%
sqlite u32_u64_str unique_0 64 76486 76486 0.00% 77854 77848 0.01%

callgrind: serialize_product_value

count format total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
64 json 47528 47528 0.00% 50180 50180 0.00%
64 bsatn 25509 25509 0.00% 27719 27719 0.00%
16 bsatn 8200 8200 0.00% 9560 9560 0.00%
16 json 12188 12188 0.00% 14092 14092 0.00%

callgrind: update bulk

db schema indices count preload total reads + writes old total reads + writes Δrw estimated cycles old estimated cycles Δcycles
stdb_raw u32_u64_str unique_0 1024 1024 18982899 19057820 -0.39% 19606063 19812746 -1.04%
stdb_raw u32_u64_str unique_0 64 128 1236017 1242001 -0.48% 1305261 1319865 -1.11%
sqlite u32_u64_str unique_0 1024 1024 1809727 1809785 -0.00% 1818357 1818457 -0.01%
sqlite u32_u64_str unique_0 64 128 132662 132687 -0.02% 135740 135783 -0.03%

Please sign in to comment.