Skip to content

Commit

Permalink
Bump Rust to 1.77 + fix warnings + use Bound::map (#1020)
Browse files Browse the repository at this point in the history
* bump Rust to 1.77 + fix warnings + use Bound::map

* use .truncate(true) for OpenOptions
  • Loading branch information
Centril authored Mar 25, 2024
1 parent ba8a8d9 commit 9141a42
Show file tree
Hide file tree
Showing 15 changed files with 33 additions and 58 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ debug = true
version = "0.8.2"
edition = "2021"
# update rust-toolchain.toml too!
rust-version = "1.76.0"
rust-version = "1.77.0"

[workspace.dependencies]
spacetimedb = { path = "crates/bindings", version = "0.8.2" }
Expand Down
2 changes: 1 addition & 1 deletion crates/bench/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# See the README for commands to run.

# sync with: ../../rust-toolchain.toml
FROM rust:1.76.0
FROM rust:1.77.0

RUN apt-get update && \
apt-get install -y valgrind protobuf-compiler bash && \
Expand Down
11 changes: 5 additions & 6 deletions crates/client-api/src/routes/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use spacetimedb::messages::control_db::{Database, DatabaseInstance};
use spacetimedb::sql::execute::execute;
use spacetimedb_lib::address::AddressForUrl;
use spacetimedb_lib::identity::AuthCtx;
use spacetimedb_lib::name::{self, DnsLookupResponse, DomainName, DomainParsingError, PublishOp, PublishResult};
use spacetimedb_lib::name::{self, DnsLookupResponse, DomainName, PublishOp, PublishResult};
use spacetimedb_lib::recovery::{RecoveryCode, RecoveryCodeResponse};
use spacetimedb_lib::sats::WithTypespace;
use std::collections::HashMap;
Expand All @@ -38,8 +38,7 @@ use crate::routes::subscribe::generate_random_address;
use crate::util::{ByteStringBody, NameOrAddress};
use crate::{log_and_500, ControlStateDelegate, DatabaseDef, NodeDelegate};

#[derive(derive_more::From)]
pub(crate) struct DomainParsingRejection(pub(crate) DomainParsingError);
pub(crate) struct DomainParsingRejection;

impl IntoResponse for DomainParsingRejection {
fn into_response(self) -> axum::response::Response {
Expand Down Expand Up @@ -608,7 +607,7 @@ pub async fn dns<S: ControlStateDelegate>(
Path(DNSParams { database_name }): Path<DNSParams>,
Query(DNSQueryParams {}): Query<DNSQueryParams>,
) -> axum::response::Result<impl IntoResponse> {
let domain = database_name.parse().map_err(DomainParsingRejection)?;
let domain = database_name.parse().map_err(|_| DomainParsingRejection)?;
let address = ctx.lookup_address(&domain).map_err(log_and_500)?;
let response = if let Some(address) = address {
DnsLookupResponse::Success { domain, address }
Expand Down Expand Up @@ -645,7 +644,7 @@ pub async fn register_tld<S: ControlStateDelegate>(
// so, unless you are the owner, this will fail, hence not using get_or_create
let auth = auth_or_unauth(auth)?;

let tld = tld.parse::<DomainName>().map_err(DomainParsingRejection)?.into();
let tld = tld.parse::<DomainName>().map_err(|_| DomainParsingRejection)?.into();
let result = ctx.register_tld(&auth.identity, tld).await.map_err(log_and_500)?;
Ok(axum::Json(result))
}
Expand Down Expand Up @@ -906,7 +905,7 @@ pub async fn set_name<S: ControlStateDelegate>(
return Err((StatusCode::UNAUTHORIZED, "Identity does not own database.").into());
}

let domain = domain.parse().map_err(DomainParsingRejection)?;
let domain = domain.parse().map_err(|_| DomainParsingRejection)?;
let response = ctx
.create_dns_record(&auth.identity, &domain, &address)
.await
Expand Down
2 changes: 1 addition & 1 deletion crates/client-api/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl NameOrAddress {
domain: None,
}),
Self::Name(name) => {
let domain = name.parse().map_err(DomainParsingRejection)?;
let domain = name.parse().map_err(|_| DomainParsingRejection)?;
let address = ctx.lookup_address(&domain).map_err(log_and_500)?;
match address {
Some(address) => Ok(ResolvedAddress {
Expand Down
7 changes: 6 additions & 1 deletion crates/core/src/db/ostorage/hashmap_object_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,12 @@ impl ObjectDB for HashMapObjectDB {
let filename = hex::encode(&hash.data[1..]);
let path = self.root.join(folder).join(filename);

let mut unsynced = OpenOptions::new().write(true).create(true).open(path).unwrap();
let mut unsynced = OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(path)
.unwrap();
unsynced.write_all(&bytes).unwrap();
self.unsynced.push(unsynced);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl SubscriptionManager {
}

pub fn query(&self, hash: &QueryHash) -> Option<Query> {
self.queries.get(hash).map(Arc::clone)
self.queries.get(hash).cloned()
}

pub fn num_queries(&self) -> usize {
Expand Down
17 changes: 4 additions & 13 deletions crates/core/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use spacetimedb_vm::iterators::RelIter;
use spacetimedb_vm::program::ProgramVm;
use spacetimedb_vm::rel_ops::RelOps;
use spacetimedb_vm::relation::{MemTable, RelValue, Table};
use std::ops::Bound;
use std::sync::Arc;

pub enum TxMode<'a> {
Expand Down Expand Up @@ -88,17 +87,9 @@ pub fn build_query<'a>(
} else {
// For multi-col constraints, these are stored as bounds of product values,
// so we need to project these into single-col bounds and compare against the column.
// TODO: replace with `bound.map(...)` once stable.
fn map<T, U, F: FnOnce(T) -> U>(bound: Bound<T>, f: F) -> Bound<U> {
match bound {
Bound::Unbounded => Bound::Unbounded,
Bound::Included(x) => Bound::Included(f(x)),
Bound::Excluded(x) => Bound::Excluded(f(x)),
}
}
// Project start/end `Bound<AV>`s to `Bound<Vec<AV>>`s.
let start_bound = map(bounds.0.as_ref(), |av| &av.as_product().unwrap().elements);
let end_bound = map(bounds.1.as_ref(), |av| &av.as_product().unwrap().elements);
let start_bound = bounds.0.as_ref().map(|av| &av.as_product().unwrap().elements);
let end_bound = bounds.1.as_ref().map(|av| &av.as_product().unwrap().elements);
// Construct the query:
let iter = result.select(move |row| {
// Go through each column position,
Expand All @@ -107,8 +98,8 @@ pub fn build_query<'a>(
// All columns must match to include the row,
// which is essentially the same as a big `AND` of `ColumnOp`s.
Ok(cols.iter().enumerate().all(|(idx, col)| {
let start_bound = map(start_bound, |pv| &pv[idx]);
let end_bound = map(end_bound, |pv| &pv[idx]);
let start_bound = start_bound.map(|pv| &pv[idx]);
let end_bound = end_bound.map(|pv| &pv[idx]);
let read_col = row.read_column(col.idx()).unwrap();
(start_bound, end_bound).contains(&*read_col)
}))
Expand Down
28 changes: 8 additions & 20 deletions crates/lib/src/name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,14 @@ fn ensure_domain_segment(input: &str) -> Result<(), ParseError> {
}

fn ensure_domain_tld(input: &str) -> Result<(), ParseError> {
DomainTld::try_from(input).map(|_| ())
let DomainSegment(input) = DomainSegment::try_from(input)?;
if input.contains('/') {
Err(ParseError::ContainsSlash { part: input.to_owned() })
} else if is_address(input) {
Err(ParseError::Address { part: input.to_owned() })
} else {
Ok(())
}
}

/// Parsing helper to validate (path) segments of a [`DomainName`], without
Expand All @@ -555,22 +562,3 @@ impl<'a> TryFrom<&'a str> for DomainSegment<'a> {
}
}
}

/// Parsing helper to validate that a [`DomainSegment`] is a valid [`Tld`],
/// without consuming the input.
struct DomainTld<'a>(&'a str);

impl<'a> TryFrom<&'a str> for DomainTld<'a> {
type Error = ParseError;

fn try_from(value: &'a str) -> Result<Self, Self::Error> {
let DomainSegment(value) = DomainSegment::try_from(value)?;
if value.contains('/') {
Err(ParseError::ContainsSlash { part: value.to_owned() })
} else if is_address(value) {
Err(ParseError::Address { part: value.to_owned() })
} else {
Ok(Self(value))
}
}
}
2 changes: 0 additions & 2 deletions crates/sats/src/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@ impl fmt::Debug for Hash {
}
}

pub struct HashFromHexError(usize);

impl hex::FromHex for Hash {
type Error = hex::FromHexError;

Expand Down
2 changes: 1 addition & 1 deletion crates/sdk/src/global_connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ thread_local! {
/// and accesses to the client cache state (e.g. by `TableType::iter`)
/// will inspect the `CURRENT_STATE`, rather than the most-recent state
/// in `global_connection::CONNECTION`.
pub(crate) static CURRENT_STATE: RefCell<Option<ClientCacheView>> = RefCell::new(None);
pub(crate) static CURRENT_STATE: RefCell<Option<ClientCacheView>> = const { RefCell::new(None) };
}

/// If `CURRENT_STATE` is bound,
Expand Down
2 changes: 1 addition & 1 deletion crates/standalone/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
ARG CARGO_PROFILE=release


FROM rust:1.76.0 AS chef
FROM rust:1.77.0 AS chef
RUN rust_target=$(rustc -vV | awk '/^host:/{ print $2 }') && \
curl https://github.com/cargo-bins/cargo-binstall/releases/latest/download/cargo-binstall-$rust_target.tgz -fL | tar xz -C $CARGO_HOME/bin
RUN cargo binstall -y cargo-chef@0.1.56
Expand Down
6 changes: 1 addition & 5 deletions crates/standalone/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,7 @@ fn create_keys(public_key_path: &Path, private_key_path: &Path) -> anyhow::Resul
}

fn get_key_path(env: &str) -> Option<PathBuf> {
let Some(path) = std::env::var_os(env) else {
return None;
};
let path = std::path::PathBuf::from(path);
Some(path)
std::env::var_os(env).map(std::path::PathBuf::from)
}

#[async_trait]
Expand Down
1 change: 1 addition & 0 deletions crates/table/src/pointer_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ impl PointerMap {
// due to `PointerMap::maintains_invariants` being undefined.
// Easily solved by including a stub definition.
#[cfg(not(debug_assertions))]
#[allow(dead_code)]
impl PointerMap {
fn maintains_invariants(&self) -> bool {
unreachable!(
Expand Down
5 changes: 1 addition & 4 deletions crates/table/src/row_type_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,10 +364,7 @@ pub struct VarLenVisitorProgram {
#[inline]
fn next_vlr_offset(program: &[Insn], instr_ptr: &mut u16, read_tag: impl Fn(u16) -> u8) -> Option<PageOffset> {
loop {
let Some(insn) = program.get(*instr_ptr as usize) else {
return None;
};
match insn {
match program.get(*instr_ptr as usize)? {
Insn::VisitOffset(offset) => {
*instr_ptr += 1;
return Some(PageOffset(*offset));
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[toolchain]
# change crates/standalone/Dockerfile and rust-version in Cargo.toml too!
channel = "1.76.0"
channel = "1.77.0"
profile = "default"
targets = ["wasm32-unknown-unknown"]

1 comment on commit 9141a42

@github-actions
Copy link

@github-actions github-actions bot commented on 9141a42 Mar 25, 2024

Choose a reason for hiding this comment

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

Criterion benchmark results

Criterion benchmark report

YOU SHOULD PROBABLY IGNORE THESE RESULTS.

Criterion is a wall time based benchmarking system that is extremely noisy when run on CI. We collect these results for longitudinal analysis, but they are not reliable for comparing individual PRs.

Go look at the callgrind report instead.

empty

db on disk new latency old latency new throughput old throughput
sqlite 💿 422.5±1.17ns 429.4±1.92ns - -
sqlite 🧠 416.5±1.37ns 418.8±2.08ns - -
stdb_raw 💿 718.7±1.37ns 708.5±1.43ns - -
stdb_raw 🧠 685.1±3.69ns 682.9±1.12ns - -

insert_1

db on disk schema indices preload new latency old latency new throughput old throughput

insert_bulk

db on disk schema indices preload count new latency old latency new throughput old throughput
sqlite 💿 u32_u64_str btree_each_column 2048 256 506.4±1.07µs 521.8±0.99µs 1974 tx/sec 1916 tx/sec
sqlite 💿 u32_u64_str unique_0 2048 256 132.7±0.77µs 135.6±0.73µs 7.4 Ktx/sec 7.2 Ktx/sec
sqlite 💿 u32_u64_u64 btree_each_column 2048 256 426.7±41.81µs 425.0±0.91µs 2.3 Ktx/sec 2.3 Ktx/sec
sqlite 💿 u32_u64_u64 unique_0 2048 256 119.2±0.48µs 127.7±0.47µs 8.2 Ktx/sec 7.6 Ktx/sec
sqlite 🧠 u32_u64_str btree_each_column 2048 256 438.9±1.54µs 448.8±1.38µs 2.2 Ktx/sec 2.2 Ktx/sec
sqlite 🧠 u32_u64_str unique_0 2048 256 115.7±0.60µs 121.2±0.53µs 8.4 Ktx/sec 8.1 Ktx/sec
sqlite 🧠 u32_u64_u64 btree_each_column 2048 256 359.0±0.89µs 369.9±1.07µs 2.7 Ktx/sec 2.6 Ktx/sec
sqlite 🧠 u32_u64_u64 unique_0 2048 256 102.0±0.25µs 109.3±0.67µs 9.6 Ktx/sec 8.9 Ktx/sec
stdb_raw 💿 u32_u64_str btree_each_column 2048 256 719.6±0.31µs 723.9±2.27µs 1389 tx/sec 1381 tx/sec
stdb_raw 💿 u32_u64_str unique_0 2048 256 625.9±0.83µs 632.1±0.53µs 1597 tx/sec 1582 tx/sec
stdb_raw 💿 u32_u64_u64 btree_each_column 2048 256 401.6±0.27µs 415.4±0.26µs 2.4 Ktx/sec 2.4 Ktx/sec
stdb_raw 💿 u32_u64_u64 unique_0 2048 256 361.4±0.39µs 368.0±0.21µs 2.7 Ktx/sec 2.7 Ktx/sec
stdb_raw 🧠 u32_u64_str btree_each_column 2048 256 493.1±0.31µs 499.8±1.99µs 2028 tx/sec 2000 tx/sec
stdb_raw 🧠 u32_u64_str unique_0 2048 256 405.1±0.38µs 416.3±0.46µs 2.4 Ktx/sec 2.3 Ktx/sec
stdb_raw 🧠 u32_u64_u64 btree_each_column 2048 256 298.8±0.43µs 312.6±0.81µs 3.3 Ktx/sec 3.1 Ktx/sec
stdb_raw 🧠 u32_u64_u64 unique_0 2048 256 260.8±0.59µs 272.0±0.33µs 3.7 Ktx/sec 3.6 Ktx/sec

iterate

db on disk schema indices new latency old latency new throughput old throughput
sqlite 💿 u32_u64_str unique_0 19.3±0.12µs 21.7±0.14µs 50.6 Ktx/sec 45.0 Ktx/sec
sqlite 💿 u32_u64_u64 unique_0 18.3±0.17µs 19.9±0.13µs 53.5 Ktx/sec 49.1 Ktx/sec
sqlite 🧠 u32_u64_str unique_0 18.6±0.34µs 20.5±0.15µs 52.6 Ktx/sec 47.7 Ktx/sec
sqlite 🧠 u32_u64_u64 unique_0 17.2±0.16µs 18.7±0.08µs 56.7 Ktx/sec 52.2 Ktx/sec
stdb_raw 💿 u32_u64_str unique_0 18.7±0.00µs 18.7±0.00µs 52.3 Ktx/sec 52.3 Ktx/sec
stdb_raw 💿 u32_u64_u64 unique_0 15.9±0.00µs 15.9±0.00µs 61.6 Ktx/sec 61.6 Ktx/sec
stdb_raw 🧠 u32_u64_str unique_0 18.7±0.00µs 18.6±0.00µs 52.3 Ktx/sec 52.4 Ktx/sec
stdb_raw 🧠 u32_u64_u64 unique_0 15.8±0.00µs 15.8±0.00µs 61.7 Ktx/sec 61.8 Ktx/sec

find_unique

db on disk key type preload new latency old latency new throughput old throughput

filter

db on disk key type index strategy load count new latency old latency new throughput old throughput
sqlite 💿 string index 2048 256 65.6±0.20µs 66.4±0.37µs 14.9 Ktx/sec 14.7 Ktx/sec
sqlite 💿 u64 index 2048 256 62.6±0.20µs 62.4±0.19µs 15.6 Ktx/sec 15.6 Ktx/sec
sqlite 🧠 string index 2048 256 64.0±0.10µs 64.3±0.48µs 15.3 Ktx/sec 15.2 Ktx/sec
sqlite 🧠 u64 index 2048 256 58.4±0.28µs 59.0±0.24µs 16.7 Ktx/sec 16.5 Ktx/sec
stdb_raw 💿 string index 2048 256 5.6±0.00µs 5.6±0.00µs 174.7 Ktx/sec 174.9 Ktx/sec
stdb_raw 💿 u64 index 2048 256 5.5±0.00µs 5.5±0.00µs 177.4 Ktx/sec 177.5 Ktx/sec
stdb_raw 🧠 string index 2048 256 5.5±0.00µs 5.5±0.00µs 176.1 Ktx/sec 176.5 Ktx/sec
stdb_raw 🧠 u64 index 2048 256 5.5±0.00µs 5.5±0.00µs 178.8 Ktx/sec 178.8 Ktx/sec

serialize

schema format count new latency old latency new throughput old throughput
u32_u64_str bflatn_to_bsatn_fast_path 100 4.0±0.01µs 4.0±0.01µs 24.0 Mtx/sec 23.9 Mtx/sec
u32_u64_str bflatn_to_bsatn_slow_path 100 3.7±0.01µs 3.8±0.01µs 25.5 Mtx/sec 25.0 Mtx/sec
u32_u64_str bsatn 100 2.5±0.00µs 2.4±0.00µs 38.1 Mtx/sec 39.1 Mtx/sec
u32_u64_str json 100 5.2±0.10µs 5.9±0.04µs 18.4 Mtx/sec 16.1 Mtx/sec
u32_u64_str product_value 100 682.0±2.66ns 655.3±34.16ns 139.8 Mtx/sec 145.5 Mtx/sec
u32_u64_u64 bflatn_to_bsatn_fast_path 100 1360.6±13.99ns 1373.0±2.97ns 70.1 Mtx/sec 69.5 Mtx/sec
u32_u64_u64 bflatn_to_bsatn_slow_path 100 3.0±0.01µs 2.9±0.00µs 32.2 Mtx/sec 32.3 Mtx/sec
u32_u64_u64 bsatn 100 1800.0±73.95ns 1740.2±35.37ns 53.0 Mtx/sec 54.8 Mtx/sec
u32_u64_u64 json 100 3.3±0.17µs 3.0±0.07µs 28.6 Mtx/sec 31.3 Mtx/sec
u32_u64_u64 product_value 100 625.0±0.56ns 562.4±6.83ns 152.6 Mtx/sec 169.6 Mtx/sec
u64_u64_u32 bflatn_to_bsatn_fast_path 100 1160.3±59.16ns 1136.9±0.76ns 82.2 Mtx/sec 83.9 Mtx/sec
u64_u64_u32 bflatn_to_bsatn_slow_path 100 2.9±0.00µs 3.0±0.00µs 32.4 Mtx/sec 31.9 Mtx/sec
u64_u64_u32 bsatn 100 1795.3±37.59ns 1752.9±18.90ns 53.1 Mtx/sec 54.4 Mtx/sec
u64_u64_u32 json 100 3.7±0.04µs 3.1±0.02µs 26.1 Mtx/sec 30.6 Mtx/sec
u64_u64_u32 product_value 100 600.0±0.44ns 600.5±0.38ns 159.0 Mtx/sec 158.8 Mtx/sec

stdb_module_large_arguments

arg size new latency old latency new throughput old throughput
64KiB 85.5±4.88µs 80.4±8.14µs - -

stdb_module_print_bulk

line count new latency old latency new throughput old throughput
1 38.6±7.21µs 37.2±6.75µs - -
100 339.9±4.03µs 350.4±6.74µs - -
1000 2.9±0.03ms 2.3±0.52ms - -

remaining

name new latency old latency new throughput old throughput
sqlite/💿/update_bulk/u32_u64_str/unique_0/load=2048/count=256 45.1±0.19µs 48.9±0.28µs 21.7 Ktx/sec 20.0 Ktx/sec
sqlite/💿/update_bulk/u32_u64_u64/unique_0/load=2048/count=256 39.5±0.13µs 41.3±0.10µs 24.7 Ktx/sec 23.6 Ktx/sec
sqlite/🧠/update_bulk/u32_u64_str/unique_0/load=2048/count=256 38.6±0.11µs 41.1±0.25µs 25.3 Ktx/sec 23.8 Ktx/sec
sqlite/🧠/update_bulk/u32_u64_u64/unique_0/load=2048/count=256 34.3±0.09µs 36.2±0.14µs 28.5 Ktx/sec 27.0 Ktx/sec
stdb_module/💿/update_bulk/u32_u64_str/unique_0/load=2048/count=256 3.0±0.16ms 3.0±0.01ms 332 tx/sec 337 tx/sec
stdb_module/💿/update_bulk/u32_u64_u64/unique_0/load=2048/count=256 1892.1±14.20µs 1921.7±13.69µs 528 tx/sec 520 tx/sec
stdb_raw/💿/update_bulk/u32_u64_str/unique_0/load=2048/count=256 1120.0±1.34µs 1112.4±1.25µs 892 tx/sec 898 tx/sec
stdb_raw/💿/update_bulk/u32_u64_u64/unique_0/load=2048/count=256 729.5±0.70µs 725.6±0.58µs 1370 tx/sec 1378 tx/sec
stdb_raw/🧠/update_bulk/u32_u64_str/unique_0/load=2048/count=256 791.5±0.28µs 788.4±1.17µs 1263 tx/sec 1268 tx/sec
stdb_raw/🧠/update_bulk/u32_u64_u64/unique_0/load=2048/count=256 534.4±0.58µs 532.2±0.24µs 1871 tx/sec 1878 tx/sec

Please sign in to comment.