Skip to content

Commit a2d8ff8

Browse files
committed
Merge remote-tracking branch 'upstream/main' into feat/cpp_bindings
2 parents 6793cce + c41d0df commit a2d8ff8

File tree

10 files changed

+710
-12
lines changed

10 files changed

+710
-12
lines changed

CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
## [0.6.1](https://github.com/mamba-org/resolvo/compare/resolvo-v0.6.0...resolvo-v0.6.1) - 2024-06-10
10+
11+
### Added
12+
- add `DependencySnapshot` ([#44](https://github.com/mamba-org/resolvo/pull/44))
13+
14+
### Fixed
15+
- publish state of tool
16+
917
## [0.6.0](https://github.com/mamba-org/resolvo/compare/v0.5.0...v0.6.0) - 2024-06-07
1018

1119
### Other

Cargo.toml

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
[workspace]
2-
members = ["cpp"]
2+
members = ["cpp", "tools/*"]
33
resolver = "2"
44

55
[workspace.package]
6-
version = "0.6.0"
6+
name = "resolvo"
7+
version = "0.6.1"
78
authors = ["Adolfo Ochagavía <github@adolfo.ochagavia.nl>", "Bas Zalmstra <zalmstra.bas@gmail.com>", "Tim de Jager <tdejager89@gmail.com>"]
89
homepage = "https://github.com/mamba-org/resolvo"
910
repository = "https://github.com/mamba-org/resolvo"
@@ -47,3 +48,4 @@ proptest = "1.2"
4748
tracing-test = { version = "0.2.4", features = ["no-env-filter"] }
4849
tokio = { version = "1.35.1", features = ["time", "rt"] }
4950
resolvo = { path = ".", features = ["tokio"] }
51+
serde_json = "1.0"

src/internal/id.rs

+8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use crate::{internal::arena::ArenaId, Interner};
55
/// The id associated to a package name
66
#[repr(transparent)]
77
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
8+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9+
#[cfg_attr(feature = "serde", serde(transparent))]
810
pub struct NameId(pub u32);
911

1012
impl ArenaId for NameId {
@@ -20,6 +22,8 @@ impl ArenaId for NameId {
2022
/// The id associated with a generic string
2123
#[repr(transparent)]
2224
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Ord, PartialOrd)]
25+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
26+
#[cfg_attr(feature = "serde", serde(transparent))]
2327
pub struct StringId(pub u32);
2428

2529
impl ArenaId for StringId {
@@ -35,6 +39,8 @@ impl ArenaId for StringId {
3539
/// The id associated with a VersionSet.
3640
#[repr(transparent)]
3741
#[derive(Clone, Default, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
42+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
43+
#[cfg_attr(feature = "serde", serde(transparent))]
3844
pub struct VersionSetId(pub u32);
3945

4046
impl ArenaId for VersionSetId {
@@ -50,6 +56,8 @@ impl ArenaId for VersionSetId {
5056
/// The id associated to a solvable
5157
#[repr(transparent)]
5258
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Ord, PartialOrd)]
59+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
60+
#[cfg_attr(feature = "serde", serde(transparent))]
5361
pub struct SolvableId(pub u32);
5462

5563
/// Internally used id for solvables that can also represent root and null.

src/internal/mapping.rs

+51-9
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1+
use std::{cmp, iter::FusedIterator, marker::PhantomData};
2+
13
use crate::internal::arena::ArenaId;
2-
use std::cmp;
3-
use std::iter::FusedIterator;
4-
use std::marker::PhantomData;
54

65
const VALUES_PER_CHUNK: usize = 128;
76

8-
/// A `Mapping<TValue>` holds a collection of `TValue`s that can be addressed by `TId`s. You can
9-
/// think of it as a HashMap<TId, TValue>, optimized for the case in which we know the `TId`s are
10-
/// contiguous.
7+
/// A `Mapping<TValue>` holds a collection of `TValue`s that can be addressed by
8+
/// `TId`s. You can think of it as a HashMap<TId, TValue>, optimized for the
9+
/// case in which we know the `TId`s are contiguous.
10+
#[derive(Clone)]
1111
pub struct Mapping<TId, TValue> {
1212
chunks: Vec<[Option<TValue>; VALUES_PER_CHUNK]>,
1313
len: usize,
14+
max: usize,
1415
_phantom: PhantomData<TId>,
1516
}
1617

@@ -35,6 +36,7 @@ impl<TId: ArenaId, TValue> Mapping<TId, TValue> {
3536
Self {
3637
chunks,
3738
len: 0,
39+
max: 0,
3840
_phantom: Default::default(),
3941
}
4042
}
@@ -49,7 +51,8 @@ impl<TId: ArenaId, TValue> Mapping<TId, TValue> {
4951

5052
/// Insert into the mapping with the specific value
5153
pub fn insert(&mut self, id: TId, value: TValue) {
52-
let (chunk, offset) = Self::chunk_and_offset(id.to_usize());
54+
let idx = id.to_usize();
55+
let (chunk, offset) = Self::chunk_and_offset(idx);
5356

5457
// Resize to fit if needed
5558
if chunk >= self.chunks.len() {
@@ -58,6 +61,7 @@ impl<TId: ArenaId, TValue> Mapping<TId, TValue> {
5861
}
5962
self.chunks[chunk][offset] = Some(value);
6063
self.len += 1;
64+
self.max = self.max.max(idx);
6165
}
6266

6367
/// Get a specific value in the mapping with bound checks
@@ -95,7 +99,9 @@ impl<TId: ArenaId, TValue> Mapping<TId, TValue> {
9599
/// Get a specific value in the mapping without bound checks
96100
///
97101
/// # Safety
98-
/// The caller must uphold most of the safety requirements for `get_unchecked`. i.e. the id having been inserted into the Mapping before.
102+
/// The caller must uphold most of the safety requirements for
103+
/// `get_unchecked`. i.e. the id having been inserted into the Mapping
104+
/// before.
99105
pub unsafe fn get_unchecked(&self, id: TId) -> &TValue {
100106
let (chunk, offset) = Self::chunk_and_offset(id.to_usize());
101107
self.chunks
@@ -108,7 +114,9 @@ impl<TId: ArenaId, TValue> Mapping<TId, TValue> {
108114
/// Get a specific value in the mapping without bound checks
109115
///
110116
/// # Safety
111-
/// The caller must uphold most of the safety requirements for `get_unchecked_mut`. i.e. the id having been inserted into the Mapping before.
117+
/// The caller must uphold most of the safety requirements for
118+
/// `get_unchecked_mut`. i.e. the id having been inserted into the Mapping
119+
/// before.
112120
pub unsafe fn get_unchecked_mut(&mut self, id: TId) -> &mut TValue {
113121
let (chunk, offset) = Self::chunk_and_offset(id.to_usize());
114122
self.chunks
@@ -128,6 +136,11 @@ impl<TId: ArenaId, TValue> Mapping<TId, TValue> {
128136
self.len == 0
129137
}
130138

139+
/// Returns the maximum id that has been inserted
140+
pub(crate) fn max(&self) -> usize {
141+
self.max
142+
}
143+
131144
/// Defines the number of slots that can be used
132145
/// theses slots are not initialized
133146
pub fn slots(&self) -> usize {
@@ -177,6 +190,35 @@ impl<'a, TId: ArenaId, TValue> Iterator for MappingIter<'a, TId, TValue> {
177190

178191
impl<'a, TId: ArenaId, TValue> FusedIterator for MappingIter<'a, TId, TValue> {}
179192

193+
#[cfg(feature = "serde")]
194+
impl<K: ArenaId, V: serde::Serialize> serde::Serialize for Mapping<K, V> {
195+
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
196+
self.chunks
197+
.iter()
198+
.flatten()
199+
.take(self.max())
200+
.collect::<Vec<_>>()
201+
.serialize(serializer)
202+
}
203+
}
204+
205+
#[cfg(feature = "serde")]
206+
impl<'de, K: ArenaId, V: serde::Deserialize<'de>> serde::Deserialize<'de> for Mapping<K, V> {
207+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
208+
where
209+
D: serde::Deserializer<'de>,
210+
{
211+
let values = Vec::<Option<V>>::deserialize(deserializer)?;
212+
let mut mapping = Mapping::with_capacity(values.len());
213+
for (i, value) in values.into_iter().enumerate() {
214+
if let Some(value) = value {
215+
mapping.insert(K::from_usize(i), value);
216+
}
217+
}
218+
Ok(mapping)
219+
}
220+
}
221+
180222
#[cfg(test)]
181223
mod tests {
182224
use crate::internal::arena::ArenaId;

src/lib.rs

+12
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
pub(crate) mod internal;
1414
pub mod problem;
1515
pub mod runtime;
16+
pub mod snapshot;
1617
mod solver;
1718
pub mod utils;
1819

@@ -171,6 +172,8 @@ pub struct Candidates {
171172

172173
/// Holds information about the dependencies of a package.
173174
#[derive(Debug, Clone)]
175+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
176+
#[cfg_attr(feature = "serde", serde(untagged))]
174177
pub enum Dependencies {
175178
/// The dependencies are known.
176179
Known(KnownDependencies),
@@ -184,9 +187,14 @@ pub enum Dependencies {
184187

185188
/// Holds information about the dependencies of a package when they are known.
186189
#[derive(Default, Clone, Debug)]
190+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
187191
pub struct KnownDependencies {
188192
/// Defines which packages should be installed alongside the depending
189193
/// package and the constraints applied to the package.
194+
#[cfg_attr(
195+
feature = "serde",
196+
serde(default, skip_serializing_if = "Vec::is_empty")
197+
)]
190198
pub requirements: Vec<VersionSetId>,
191199

192200
/// Defines additional constraints on packages that may or may not be part
@@ -196,5 +204,9 @@ pub struct KnownDependencies {
196204
/// package also added to the solution.
197205
///
198206
/// This is often useful to use for optional dependencies.
207+
#[cfg_attr(
208+
feature = "serde",
209+
serde(default, skip_serializing_if = "Vec::is_empty")
210+
)]
199211
pub constrains: Vec<VersionSetId>,
200212
}

0 commit comments

Comments
 (0)