Skip to content

Commit

Permalink
uv: migrate to rkyv 0.8
Browse files Browse the repository at this point in the history
Recently, rkyv 0.8 was released. Its API is a fair bit simpler now for
higher level uses (like for us in `uv`) and results in us being able to
delete a fair bit of code. This also removes our last dependency on `syn
1.0`, and thus drops that dependency.

Performance (via testing on the `transformers` example) seems to remain
about the same, which is what was expected:

```
$ hyperfine -w5 -r100 'uv lock' 'uv-ag-rkyv-update lock'
Benchmark 1: uv lock
  Time (mean ± σ):      55.6 ms ±   6.4 ms    [User: 30.4 ms, System: 35.1 ms]
  Range (min … max):    43.0 ms …  73.1 ms    100 runs

Benchmark 2: uv-ag-rkyv-update lock
  Time (mean ± σ):      56.5 ms ±   7.2 ms    [User: 30.5 ms, System: 36.3 ms]
  Range (min … max):    39.1 ms …  71.5 ms    100 runs

Summary
  uv lock ran
    1.02 ± 0.18 times faster than uv-ag-rkyv-update lock
```

Closes #7415
  • Loading branch information
BurntSushi committed Sep 18, 2024
1 parent 91a574c commit 1379b53
Show file tree
Hide file tree
Showing 22 changed files with 203 additions and 437 deletions.
192 changes: 77 additions & 115 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ axoupdater = { version = "0.7.2", default-features = false }
backoff = { version = "0.4.0" }
base64 = { version = "0.22.1" }
boxcar = { version = "0.2.5" }
bytecheck = { version = "0.8.0" }
cachedir = { version = "0.3.1" }
cargo-util = { version = "0.2.14" }
clap = { version = "4.5.17" }
Expand Down Expand Up @@ -125,7 +126,7 @@ regex = { version = "1.10.6" }
reqwest = { version = "0.12.7", default-features = false, features = ["json", "gzip", "stream", "rustls-tls", "rustls-tls-native-roots", "socks"] }
reqwest-middleware = { git = "https://github.com/astral-sh/reqwest-middleware", rev = "5e3eaf254b5bd481c75d2710eed055f95b756913" }
reqwest-retry = { git = "https://github.com/astral-sh/reqwest-middleware", rev = "5e3eaf254b5bd481c75d2710eed055f95b756913" }
rkyv = { version = "0.7.45", features = ["strict", "validation"] }
rkyv = { version = "0.8.8", features = ["bytecheck"] }
rmp-serde = { version = "1.3.0" }
rust-netrc = { version = "0.1.1" }
rustc-hash = { version = "2.0.0" }
Expand Down
3 changes: 1 addition & 2 deletions crates/distribution-filename/src/build_tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ pub enum BuildTagError {
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub struct BuildTag(u64, Option<Arc<str>>);

impl FromStr for BuildTag {
Expand Down
3 changes: 1 addition & 2 deletions crates/distribution-filename/src/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ pub enum DistExtension {
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub enum SourceDistExtension {
Zip,
TarGz,
Expand Down
3 changes: 1 addition & 2 deletions crates/distribution-filename/src/source_dist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ use uv_normalize::{InvalidNameError, PackageName};
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub struct SourceDistFilename {
pub name: PackageName,
pub version: Version,
Expand Down
3 changes: 1 addition & 2 deletions crates/distribution-filename/src/wheel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ use uv_normalize::{InvalidNameError, PackageName};
use crate::{BuildTag, BuildTagError};

#[derive(Debug, Clone, Eq, PartialEq, Hash, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub struct WheelFilename {
pub name: PackageName,
pub version: Version,
Expand Down
9 changes: 3 additions & 6 deletions crates/distribution-types/src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ pub enum FileConversionError {
#[derive(
Debug, Clone, Hash, Serialize, Deserialize, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub struct File {
pub dist_info_metadata: bool,
pub filename: String,
Expand Down Expand Up @@ -72,8 +71,7 @@ impl File {
#[derive(
Debug, Clone, Hash, Serialize, Deserialize, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub enum FileLocation {
/// URL relative to the base URL.
RelativeUrl(String, String),
Expand Down Expand Up @@ -150,8 +148,7 @@ impl Display for FileLocation {
rkyv::Serialize,
)]
#[serde(transparent)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub struct UrlString(String);

impl UrlString {
Expand Down
24 changes: 8 additions & 16 deletions crates/pep440-rs/src/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ use std::{
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[rkyv(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[cfg_attr(feature = "pyo3", pyclass)]
pub enum Operator {
/// `== 1.2.3`
Expand Down Expand Up @@ -288,15 +287,13 @@ impl std::fmt::Display for OperatorParseError {
/// let version = Version::from_str("1.19").unwrap();
/// ```
#[derive(Clone, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[rkyv(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
pub struct Version {
inner: Arc<VersionInner>,
}

#[derive(Clone, Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[rkyv(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
enum VersionInner {
Small { small: VersionSmall },
Full { full: VersionFull },
Expand Down Expand Up @@ -885,8 +882,7 @@ impl FromStr for Version {
/// Thankfully, such versions are incredibly rare. Virtually all versions have
/// zero or one pre, dev or post release components.
#[derive(Clone, Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[rkyv(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
struct VersionSmall {
/// The representation discussed above.
repr: u64,
Expand Down Expand Up @@ -1227,8 +1223,7 @@ impl VersionSmall {
/// In general, the "full" representation is rarely used in practice since most
/// versions will fit into the "small" representation.
#[derive(Clone, Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[rkyv(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
struct VersionFull {
/// The [versioning
/// epoch](https://peps.python.org/pep-0440/#version-epochs). Normally
Expand Down Expand Up @@ -1361,8 +1356,7 @@ impl FromStr for VersionPattern {
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[rkyv(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[cfg_attr(feature = "pyo3", pyclass)]
pub struct Prerelease {
/// The kind of pre-release.
Expand All @@ -1387,8 +1381,7 @@ pub struct Prerelease {
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[rkyv(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[cfg_attr(feature = "pyo3", pyclass)]
pub enum PrereleaseKind {
/// alpha pre-release
Expand Down Expand Up @@ -1431,8 +1424,7 @@ impl std::fmt::Display for Prerelease {
///
/// Luckily the default `Ord` implementation for `Vec<LocalSegment>` matches the PEP 440 rules.
#[derive(Eq, PartialEq, Debug, Clone, Hash, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
#[rkyv(derive(Debug, Eq, PartialEq, PartialOrd, Ord))]
pub enum LocalSegment {
/// Not-parseable as integer segment of local version
String(String),
Expand Down
6 changes: 2 additions & 4 deletions crates/pep440-rs/src/version_specifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ use crate::{
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
#[cfg_attr(feature = "pyo3", pyclass(sequence))]
pub struct VersionSpecifiers(Vec<VersionSpecifier>);

Expand Down Expand Up @@ -293,8 +292,7 @@ impl std::error::Error for VersionSpecifiersParseError {}
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
#[cfg_attr(feature = "pyo3", pyclass(get_all))]
pub struct VersionSpecifier {
/// ~=|==|!=|<=|>=|<|>|===, plus whether the version ended with a star
Expand Down
9 changes: 3 additions & 6 deletions crates/pypi-types/src/simple_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,7 @@ impl CoreMetadata {
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
#[serde(untagged)]
pub enum Yanked {
Bool(bool),
Expand Down Expand Up @@ -303,8 +302,7 @@ impl FromStr for Hashes {
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub enum HashAlgorithm {
Md5,
Sha256,
Expand Down Expand Up @@ -352,8 +350,7 @@ impl std::fmt::Display for HashAlgorithm {
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
pub struct HashDigest {
pub algorithm: HashAlgorithm,
pub digest: Box<str>,
Expand Down
2 changes: 1 addition & 1 deletion crates/uv-cache/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,7 @@ impl CacheBucket {
Self::Interpreter => "interpreter-v2",
// Note that when bumping this, you'll also need to bump it
// in crates/uv/tests/cache_clean.rs.
Self::Simple => "simple-v12",
Self::Simple => "simple-v13",
Self::Wheels => "wheels-v1",
Self::Archive => "archive-v0",
Self::Builds => "builds-v0",
Expand Down
1 change: 1 addition & 0 deletions crates/uv-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ anyhow = { workspace = true }
async-trait = { workspace = true }
async_http_range_reader = { workspace = true }
async_zip = { workspace = true }
bytecheck = { workspace = true }
fs-err = { workspace = true, features = ["tokio"] }
futures = { workspace = true }
html-escape = { workspace = true }
Expand Down
10 changes: 7 additions & 3 deletions crates/uv-client/src/cached_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,13 @@ impl<T: Serialize + DeserializeOwned> Cacheable for SerdeCacheable<T> {
/// All `OwnedArchive` values are cacheable.
impl<A> Cacheable for OwnedArchive<A>
where
A: rkyv::Archive + rkyv::Serialize<crate::rkyvutil::Serializer<4096>>,
A::Archived: for<'a> rkyv::CheckBytes<rkyv::validation::validators::DefaultValidator<'a>>
+ rkyv::Deserialize<A, rkyv::de::deserializers::SharedDeserializeMap>,
// A: rkyv::Archive + rkyv::Serialize<crate::rkyvutil::Serializer<4096>>,
// A::Archived: for<'a> rkyv::bytecheck::CheckBytes<rkyv::validation::validators::DefaultValidator<'a>>
// + rkyv::Deserialize<A, rkyv::de::deserializers::SharedDeserializeMap>,
A: rkyv::Archive + for<'a> rkyv::Serialize<crate::rkyvutil::Serializer<'a>>,
A::Archived: rkyv::Portable
+ rkyv::Deserialize<A, crate::rkyvutil::Deserializer>
+ for<'a> rkyv::bytecheck::CheckBytes<crate::rkyvutil::Validator<'a>>,
{
type Target = Self;

Expand Down
2 changes: 1 addition & 1 deletion crates/uv-client/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ pub enum ErrorKind {
ArchiveRead(String),

#[error("Writing to cache archive failed: {0}")]
ArchiveWrite(#[source] crate::rkyvutil::SerializerError),
ArchiveWrite(String),

#[error("Network connectivity is disabled, but the requested data wasn't found in the cache for: `{0}`")]
Offline(String),
Expand Down
3 changes: 1 addition & 2 deletions crates/uv-client/src/httpcache/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ use crate::rkyvutil::OwnedArchive;
rkyv::Deserialize,
rkyv::Serialize,
)]
#[archive(check_bytes)]
#[archive_attr(derive(Debug))]
#[rkyv(derive(Debug))]
#[allow(clippy::struct_excessive_bools)]
pub struct CacheControl {
// directives for requests and responses
Expand Down
Loading

0 comments on commit 1379b53

Please sign in to comment.