Skip to content

Commit 4d53b04

Browse files
committed
FAIL: try to rewrite delegate to be map based… (#26)
…but besides completely failing the normalization test which I don't understand, it also doesn't manage to get the correct amount of versions.
1 parent c0c01bb commit 4d53b04

File tree

3 files changed

+34
-37
lines changed

3 files changed

+34
-37
lines changed

src/index/diff/delegate.rs

+26-25
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use std::ops::Range;
77

88
#[derive(Default)]
99
pub(crate) struct Delegate {
10-
changes: Vec<Change>,
11-
deleted_version_ids: BTreeMap<u64, CrateVersion>,
10+
map: BTreeMap<[u8; 32], CrateVersion>,
11+
deletions: Vec<Change>,
1212
err: Option<Error>,
1313
}
1414

@@ -37,7 +37,7 @@ impl Delegate {
3737
if let Some(obj) = entry_data(entry_mode, id)? {
3838
for line in obj.data.lines() {
3939
let version = version_from_json_line(line, change.location)?;
40-
self.changes.push(version.into());
40+
self.map.insert(version.checksum, version.into());
4141
}
4242
}
4343
}
@@ -48,7 +48,7 @@ impl Delegate {
4848
for line in obj.data.lines() {
4949
deleted.push(version_from_json_line(line, change.location)?);
5050
}
51-
self.changes.push(Change::Deleted {
51+
self.deletions.push(Change::Deleted {
5252
name: change.location.to_string(),
5353
versions: deleted,
5454
});
@@ -84,8 +84,7 @@ impl Delegate {
8484
for removed in lines_before {
8585
match version_from_json_line(removed, location) {
8686
Ok(version) => {
87-
self.deleted_version_ids
88-
.insert(version.id(), version);
87+
self.map.insert(version.checksum, version);
8988
}
9089
Err(e) => {
9190
err = Some(e);
@@ -98,7 +97,10 @@ impl Delegate {
9897
(false, true) => {
9998
for inserted in lines_after {
10099
match version_from_json_line(inserted, location) {
101-
Ok(version) => self.changes.push(version.into()),
100+
Ok(version) => {
101+
self.map
102+
.insert(version.checksum, version.into());
103+
}
102104
Err(e) => {
103105
err = Some(e);
104106
break;
@@ -117,11 +119,14 @@ impl Delegate {
117119
.map(|removed| (removed, inserted))
118120
}) {
119121
Ok((removed_version, inserted_version)) => {
120-
if removed_version.yanked
121-
!= inserted_version.yanked
122-
{
123-
self.changes.push(inserted_version.into());
124-
}
122+
self.map.insert(
123+
removed_version.checksum,
124+
removed_version,
125+
);
126+
self.map.insert(
127+
inserted_version.checksum,
128+
inserted_version,
129+
);
125130
}
126131
Err(e) => {
127132
err = Some(e);
@@ -144,22 +149,18 @@ impl Delegate {
144149
Ok(Default::default())
145150
}
146151

147-
pub fn into_result(mut self) -> Result<Vec<Change>, Error> {
152+
pub fn into_result(self) -> Result<Vec<Change>, Error> {
148153
match self.err {
149154
Some(err) => Err(err),
150155
None => {
151-
if !self.deleted_version_ids.is_empty() {
152-
let deleted_version_ids = &mut self.deleted_version_ids;
153-
self.changes.retain(|change| match change {
154-
Change::Added(v) | Change::Yanked(v) => {
155-
deleted_version_ids.remove(&v.id()).is_some()
156-
}
157-
Change::Deleted { .. } => true,
158-
});
159-
self.changes
160-
.extend(self.deleted_version_ids.into_values().map(Into::into))
161-
}
162-
Ok(self.changes)
156+
let mut changes = self.map.into_values().map(Into::into).collect::<Vec<_>>();
157+
changes.sort_by(|a: &Change, b: &Change| {
158+
let a = a.version();
159+
let b = b.version();
160+
a.name.cmp(&b.name).then_with(|| a.version.cmp(&b.version))
161+
});
162+
changes.extend(self.deletions);
163+
Ok(changes)
163164
}
164165
}
165166
}

src/types.rs

+7-11
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ impl Change {
5959
_ => None,
6060
}
6161
}
62+
63+
pub(crate) fn version(&self) -> &CrateVersion {
64+
match self {
65+
Change::Added(v) | Change::Yanked(v) => v,
66+
Change::Deleted { .. } => unreachable!("BUG: must not call this on deletion"),
67+
}
68+
}
6269
}
6370

6471
impl fmt::Display for Change {
@@ -109,17 +116,6 @@ pub struct CrateVersion {
109116
pub dependencies: Vec<Dependency>,
110117
}
111118

112-
impl CrateVersion {
113-
pub(crate) fn id(&self) -> u64 {
114-
let mut s = std::collections::hash_map::DefaultHasher::new();
115-
self.name.hash(&mut s);
116-
self.yanked.hash(&mut s);
117-
self.version.hash(&mut s);
118-
self.checksum.hash(&mut s);
119-
s.finish()
120-
}
121-
}
122-
123119
impl From<CrateVersion> for Change {
124120
fn from(v: CrateVersion) -> Self {
125121
if v.yanked {

tests/baseline.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ fn all_aggregrated_diffs_equal_latest_version(
3535
.collect::<Result<Vec<_>, _>>()?;
3636

3737
// This could be more complex, like jumping to landmarks like 'Delete crate(s)' and so forth.
38-
let partitions = 3;
38+
let partitions = 4;
3939
let chunk_size = (commits.len() / partitions).max(1);
4040
let mut steps = (0..commits.len()).step_by(chunk_size).collect::<Vec<_>>();
4141
if *steps.last().expect("at least 1") != commits.len() - 1 {

0 commit comments

Comments
 (0)