diff --git a/Cargo.lock b/Cargo.lock index 8df1b3dfa50ee..bd1c56dfd07fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -254,26 +254,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" -[[package]] -name = "bincode" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740" -dependencies = [ - "bincode_derive", - "serde", - "unty", -] - -[[package]] -name = "bincode_derive" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf95709a440f45e986983918d0e8a1f30a9b1df04918fc828670606804ac3c09" -dependencies = [ - "virtue", -] - [[package]] name = "bit-set" version = "0.8.0" @@ -357,6 +337,35 @@ version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +[[package]] +name = "bytecheck" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0caa33a2c0edca0419d15ac723dff03f1956f7978329b1e3b5fdaaaed9d3ca8b" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "rancor", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "bytes" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593" + [[package]] name = "cachedir" version = "0.3.1" @@ -2136,6 +2145,26 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "munge" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e17401f259eba956ca16491461b6e8f72913a0a114e39736ce404410f915a0c" +dependencies = [ + "munge_macro", +] + +[[package]] +name = "munge_macro" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "natord" version = "1.0.9" @@ -2660,6 +2689,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "ptr_meta" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9a0cf95a1196af61d4f1cbdab967179516d9a4a4312af1f31948f8f6224a79" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pyproject-toml" version = "0.13.7" @@ -2767,6 +2816,15 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "rancor" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a063ea72381527c2a0561da9c80000ef822bdd7c3241b1cc1b12100e3df081ee" +dependencies = [ + "ptr_meta", +] + [[package]] name = "rand" version = "0.8.5" @@ -2909,6 +2967,45 @@ version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" +[[package]] +name = "rend" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadadef317c2f20755a64d7fdc48f9e7178ee6b0e1f7fce33fa60f1d68a276e6" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "rkyv" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73389e0c99e664f919275ab5b5b0471391fe9a8de61e1dff9b1eaf56a90f16e3" +dependencies = [ + "bytecheck", + "bytes", + "hashbrown 0.17.1", + "indexmap", + "munge", + "ptr_meta", + "rancor", + "rend", + "rkyv_derive", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d2ed0b54125315fb36bd021e82d314d1c126548f871634b483f46b31d13cac6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "ron" version = "0.12.0" @@ -2930,7 +3027,6 @@ dependencies = [ "anyhow", "argfile", "assert_fs", - "bincode", "bitflags 2.13.0", "cachedir", "clap", @@ -2954,6 +3050,7 @@ dependencies = [ "path-absolutize", "rayon", "regex", + "rkyv", "ruff_cache", "ruff_db", "ruff_diagnostics", @@ -3930,6 +4027,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "similar" version = "2.7.0" @@ -4968,12 +5071,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9df2af067a7953e9c3831320f35c1cc0600c30d44d9f7a12b01db1cd88d6b47" -[[package]] -name = "unty" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" - [[package]] name = "url" version = "2.5.8" @@ -5042,12 +5139,6 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "virtue" -version = "0.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "051eb1abcf10076295e815102942cc58f9d5e3b4560e46e53c21e8ff6f3af7b1" - [[package]] name = "vt100" version = "0.16.2" diff --git a/Cargo.toml b/Cargo.toml index 3c87189da21af..eb7c96cacda93 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -69,7 +69,7 @@ anyhow = { version = "1.0.80" } arc-swap = { version = "1.7.1" } argfile = { version = "1.0.0" } assert_fs = { version = "1.1.0" } -bincode = { version = "2.0.0" } +rkyv = { version = "0.8.16" } bitflags = { version = "2.5.0" } bitvec = { version = "1.0.1", default-features = false, features = [ "alloc", diff --git a/crates/ruff/Cargo.toml b/crates/ruff/Cargo.toml index ac670dc2b6c0b..d20357fbad2cf 100644 --- a/crates/ruff/Cargo.toml +++ b/crates/ruff/Cargo.toml @@ -40,7 +40,7 @@ ruff_workspace = { workspace = true } anyhow = { workspace = true } argfile = { workspace = true } -bincode = { workspace = true, features = ["serde"] } +rkyv = { workspace = true } bitflags = { workspace = true } cachedir = { workspace = true } clap = { workspace = true, features = ["derive", "env", "wrap_help"] } diff --git a/crates/ruff/src/cache.rs b/crates/ruff/src/cache.rs index babfc79343183..fc8d756b33637 100644 --- a/crates/ruff/src/cache.rs +++ b/crates/ruff/src/cache.rs @@ -1,7 +1,7 @@ use std::fmt::Debug; -use std::fs::{self, File}; +use std::fs; use std::hash::Hasher; -use std::io::{self, BufReader, Write}; +use std::io::{self, Write}; use std::path::{Path, PathBuf}; use std::sync::Mutex; use std::sync::atomic::{AtomicU64, Ordering}; @@ -97,8 +97,8 @@ impl Cache { let key = format!("{}", cache_key(&package_root, settings)); let path = PathBuf::from_iter([&settings.cache_dir, Path::new(VERSION), Path::new(&key)]); - let file = match File::open(&path) { - Ok(file) => file, + let serialized = match fs::read(&path) { + Ok(serialized) => serialized, Err(err) if err.kind() == io::ErrorKind::NotFound => { // No cache exist yet, return an empty cache. return Cache::empty(path, package_root); @@ -109,8 +109,10 @@ impl Cache { } }; - let mut package: PackageCache = - match bincode::decode_from_reader(BufReader::new(file), bincode::config::standard()) { + let mut package = + match rkyv::access::(&serialized) + .and_then(rkyv::deserialize::) + { Ok(package) => package, Err(err) => { warn_user!("Failed parse cache file `{}`: {err}", path.display()); @@ -167,7 +169,7 @@ impl Cache { // Serialize to in-memory buffer because hyperfine benchmark showed that it's faster than // using a `BufWriter` and our cache files are small enough that streaming isn't necessary. - let serialized = bincode::encode_to_vec(&self.package, bincode::config::standard()) + let serialized = rkyv::to_bytes::(&self.package) .context("Failed to serialize cache data")?; temp_file .write_all(&serialized) @@ -317,19 +319,21 @@ fn tempfile_in(path: &Path) -> io::Result { } /// On disk representation of a cache of a package. -#[derive(bincode::Encode, Debug, bincode::Decode)] +#[derive(rkyv::Archive, Debug, rkyv::Deserialize, rkyv::Serialize)] struct PackageCache { /// Path to the root of the package. /// /// Usually this is a directory, but it can also be a single file in case of /// single file "packages", e.g. scripts. + #[rkyv(with = rkyv::with::AsString)] package_root: PathBuf, /// Mapping of source file path to it's cached data. + #[rkyv(with = rkyv::with::MapKV)] files: FxHashMap, } /// On disk representation of the cache per source file. -#[derive(bincode::Decode, Debug, bincode::Encode)] +#[derive(rkyv::Deserialize, rkyv::Serialize, Debug, rkyv::Archive)] pub(crate) struct FileCache { /// Key that determines if the cached item is still valid. key: u64, @@ -337,6 +341,7 @@ pub(crate) struct FileCache { /// /// Represented as the number of milliseconds since Unix epoch. This will /// break in 1970 + ~584 years (~2554). + #[rkyv(with = rkyv::with::AtomicLoad)] last_seen: AtomicU64, data: FileCacheData, @@ -349,7 +354,7 @@ impl FileCache { } } -#[derive(Debug, Default, bincode::Decode, bincode::Encode)] +#[derive(Debug, Default, rkyv::Deserialize, rkyv::Serialize, rkyv::Archive)] struct FileCacheData { linted: bool, formatted: bool,