Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: total ordering for the dependency provider #892

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
76028d7
nwip: total ordering for the dependency provider
tdejager Oct 4, 2024
7afbe9d
feat: fixes total ordering for rattler
tdejager Oct 4, 2024
76ccd8b
Merge branch 'main' into feat/total-order-for-dependency-provider
tdejager Oct 4, 2024
2fb1f17
Update conda_util.rs
tdejager Oct 4, 2024
b2ab590
fix: remove unused code
tdejager Oct 4, 2024
671d5f8
fix: wrote some more documentation and fixed up some PR comments
tdejager Oct 4, 2024
ebc41f2
fix: compile error
tdejager Oct 4, 2024
31486bc
fix: clippy
tdejager Oct 5, 2024
2cf5add
fix: function rename
tdejager Oct 5, 2024
c9878f6
feat: rename mod so that it makes more sense for what it does
tdejager Oct 5, 2024
65e6539
feat: rename mod so that it makes more sense for what it does
tdejager Oct 5, 2024
f8d791a
fix: more PR comments
tdejager Oct 5, 2024
7122e01
fix: bump typed path
tdejager Oct 5, 2024
930065d
feat: removed seemingly unused code
tdejager Oct 5, 2024
59408db
Merge branch 'main' into feat/total-order-for-dependency-provider
tdejager Oct 5, 2024
75867a4
fix: small performance improvements
tdejager Oct 5, 2024
e76f17b
fix: remove bitset
tdejager Oct 5, 2024
0763229
fix: sorting test should also load dependencies
baszalmstra Oct 7, 2024
442c9b9
Merge branch 'fix/sorting_test' into feat/total-order-for-dependency-…
baszalmstra Oct 7, 2024
8388ab2
wip: new sorting method, contains debug statement for printing
tdejager Oct 7, 2024
3005e07
fix: use sorting based on alphabet
baszalmstra Oct 7, 2024
53436b4
Merge remote-tracking branch 'upstream/main' into feat/total-order-fo…
baszalmstra Oct 7, 2024
c12d3a4
fix: sort by timestamp in reverse
baszalmstra Oct 7, 2024
8c81926
fix: sorting with tracked features
baszalmstra Oct 7, 2024
8e92f49
fix: strategy fixes and small performance improvement
baszalmstra Oct 7, 2024
e2c81d2
perf: make performance really close
baszalmstra Oct 7, 2024
93f9b72
Merge branch 'main' into feat/total-order-for-dependency-provider
tdejager Oct 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ digest = "0.10.7"
dirs = "5.0.1"
dunce = "1.0.4"
enum_dispatch = "0.3.13"
fs-err = { version = "2.11.0", features = ["tokio"] }
fs-err = { version = "2.11.0", features = ["tokio"] }
fslock = "0.2.1"
futures = "0.3.30"
futures-util = "0.3.30"
Expand Down Expand Up @@ -110,7 +110,7 @@ regex = "1.10.4"
reqwest = { version = "0.12.3", default-features = false }
reqwest-middleware = "0.3.0"
reqwest-retry = "0.6.0"
resolvo = { version = "0.8.1" }
resolvo = { version = "0.8.2" }
retry-policies = { version = "0.4.0", default-features = false }
rmp-serde = { version = "1.2.0" }
rstest = { version = "0.21.0" }
Expand Down Expand Up @@ -150,7 +150,7 @@ tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", default-features = false }
tracing-test = { version = "0.2.4" }
trybuild = { version = "1.0.91" }
typed-path = { version = "0.9.0" }
typed-path = { version = "0.9.2" }
url = { version = "2.5.0" }
uuid = { version = "1.8.0", default-features = false }
walkdir = "2.5.0"
Expand Down
62 changes: 1 addition & 61 deletions crates/rattler_conda_types/src/utils/serde.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
use chrono::{DateTime, Utc};
use fxhash::FxHashMap;
use itertools::Itertools;
use serde::de::Error as _;
use serde::ser::Error;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_with::de::DeserializeAsWrap;
use serde_with::ser::SerializeAsWrap;
use serde_with::{DeserializeAs, SerializeAs};
use std::collections::{BTreeMap, HashSet};
use std::hash::{BuildHasher, Hash};
use std::collections::BTreeMap;
use std::marker::PhantomData;
use std::path::{Path, PathBuf};
use url::Url;
Expand Down Expand Up @@ -143,62 +139,6 @@ impl SerializeAs<chrono::DateTime<chrono::Utc>> for Timestamp {
}
}

/// Used with `serde_with` to serialize a collection as a sorted collection.
#[derive(Default)]
pub(crate) struct Ordered<T>(PhantomData<T>);

impl<'de, T: Eq + Hash, S: BuildHasher + Default, TAs> DeserializeAs<'de, HashSet<T, S>>
for Ordered<TAs>
where
TAs: DeserializeAs<'de, T>,
{
fn deserialize_as<D>(deserializer: D) -> Result<HashSet<T, S>, D::Error>
where
D: Deserializer<'de>,
{
let content =
DeserializeAsWrap::<Vec<T>, Vec<TAs>>::deserialize(deserializer)?.into_inner();
Ok(content.into_iter().collect())
}
}

impl<T: Ord, HS, TAs: SerializeAs<T>> SerializeAs<HashSet<T, HS>> for Ordered<TAs> {
fn serialize_as<S>(source: &HashSet<T, HS>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut elements = source.iter().collect_vec();
elements.sort();
SerializeAsWrap::<Vec<&T>, Vec<&TAs>>::new(&elements).serialize(serializer)
}
}

impl<'de, T: Ord, TAs> DeserializeAs<'de, Vec<T>> for Ordered<TAs>
where
TAs: DeserializeAs<'de, T>,
{
fn deserialize_as<D>(deserializer: D) -> Result<Vec<T>, D::Error>
where
D: Deserializer<'de>,
{
let mut content =
DeserializeAsWrap::<Vec<T>, Vec<TAs>>::deserialize(deserializer)?.into_inner();
content.sort();
Ok(content)
}
}

impl<T: Ord, TAs: SerializeAs<T>> SerializeAs<Vec<T>> for Ordered<TAs> {
fn serialize_as<S>(source: &Vec<T>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut elements = source.iter().collect_vec();
elements.sort();
SerializeAsWrap::<Vec<&T>, Vec<&TAs>>::new(&elements).serialize(serializer)
}
}

/// A helper struct to deserialize types from a string without checking the string.
pub struct DeserializeFromStrUnchecked;

Expand Down
57 changes: 52 additions & 5 deletions crates/rattler_conda_types/src/version/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,7 @@ mod test {

use crate::version::StrictVersion;

use super::Version;
use super::{Component, Version};

// Tests are inspired by: https://github.com/conda/conda/blob/33a142c16530fcdada6c377486f1c1a385738a96/tests/models/test_version.py

Expand All @@ -1049,7 +1049,7 @@ mod test {
Restart,
}

let versions = [
let versions_str = [
" 0.4",
"== 0.4.0",
" < 0.4.1.rc",
Expand Down Expand Up @@ -1079,13 +1079,13 @@ mod test {
" < 2!0.4.1", // epoch increased again
];

let ops = versions.iter().map(|&v| {
let (op, version) = if let Some((op, version)) = v.trim().split_once(' ') {
let ops = versions_str.iter().map(|&v| {
let (op, version_str) = if let Some((op, version)) = v.trim().split_once(' ') {
(op, version.trim())
} else {
("", v.trim())
};
let version: Version = version.parse().unwrap();
let version: Version = version_str.parse().unwrap();
let op = match op {
"<" => CmpOp::Less,
"==" => CmpOp::Equal,
Expand Down Expand Up @@ -1397,4 +1397,51 @@ mod test {
expected
);
}

#[test]
fn test_component_total_order() {
// Create instances of each variant
let components = vec![
Component::Dev,
Component::UnderscoreOrDash { is_dash: false },
Component::Iden(Box::from("alpha")),
Component::Iden(Box::from("beta")),
Component::Numeral(1),
Component::Numeral(2),
Component::Post,
];

// Check that each component equals itself
for a in &components {
assert_eq!(a.cmp(a), Ordering::Equal);
}

for (i, a) in components.iter().enumerate() {
for b in components[i + 1..].iter() {
let ord = a.cmp(b);
assert_eq!(
ord,
Ordering::Less,
"Expected {:?} < {:?}, but found {:?}",
a,
b,
ord
);
}
// Check the reverse ordering as well
// I think this should automatically check transitivity
// If a <= b and b <= c, then a <= c
for b in components[..i].iter() {
let ord = a.cmp(b);
assert_eq!(
ord,
Ordering::Greater,
"Expected {:?} > {:?}, but found {:?}",
a,
b,
ord
);
}
}
}
}
Loading
Loading