Skip to content

Implement iter_arc method for List #71

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

PoulavBhowmick03
Copy link

Fixes #70

Introduced method iter_arc:

  • Created a new type, ArcIter in iter_arc.rs
  • The iter_arc method iterates over and gets each element of the List wrapped in Arc<T>.
  • Added the method to the List impl in list.rs

@PoulavBhowmick03
Copy link
Author

@michaelsproul is this a good start? do let me know

@michaelsproul
Copy link
Member

Yeah this looks good. I wonder if we could write the ordinary Iter as a wrapper around IterArc? This would save on code duplication.

@michaelsproul
Copy link
Member

It would be great to add a new Op to the proptests as well:

Op::Iter => {
assert!(list.iter().eq(spec.iter()));
}

However it would have to run conditionally on T::tree_hash_type() not being Basic.

@michaelsproul
Copy link
Member

Needs some merge conflicts resolved, I've just been preparing a v0.7.0 release

@PoulavBhowmick03
Copy link
Author

Needs some merge conflicts resolved, I've just been preparing a v0.7.0 release

No problem. Fixing it

@PoulavBhowmick03
Copy link
Author

@michaelsproul fixed the conflict and the clippy warning

@michaelsproul
Copy link
Member

Thanks, will review thoroughly and probably merge tomorrow. Looked good at a glance

@@ -100,6 +103,10 @@ where
self.iter_from(0)
}

pub fn iter_arc(&self) -> Result<ArcIter<'_, T>, Error> {
self.backing.iter_arc(0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might be wrong in the case where there are pending updates. The proptest should have caught this

Copy link
Author

@PoulavBhowmick03 PoulavBhowmick03 Jul 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking to change it to use ArcInterfaceIter, which handles the pending updates. But in that case, I will have to change the ImmList<> and include <U: UpdateMap<T>> to it. what would you suggest is the way to go about this?

@@ -210,6 +213,17 @@ where
Op::Iter => {
assert!(list.iter().eq(spec.iter()));
}
Op::IterArc => {
if <T as TreeHash>::tree_hash_type() != TreeHashType::Basic {
list.apply_updates().unwrap();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be necessary, we should make iter_arc work without it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason being: requiring the caller to keep track and flush pending updates in order for a method to work makes it a footgun. Take a look at InterfaceIter to see how it handles the pending updates. We can do the same for ArcIter.

Eventually I'd like to rethink how pending updates are handled in Milhouse, but I've gotten a bit stuck on previous attempts, see:

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, will take a look into this PR and how pending updates are handled in InterfaceIter as well

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mmm, this is hard. I almost want to try implementing UpdateMap for BTreeMap<usize, Arc<T>> so that we aren't doing useless Arcing

@michaelsproul
Copy link
Member

Thanks for your patience @PoulavBhowmick03 🙏 Left a few more review comments. Sorry they're a bit nitpicky but I think we're getting close!

@PoulavBhowmick03
Copy link
Author

@michaelsproul I have addressed all the issues except for one, left a reply to that, above

@@ -72,6 +75,10 @@ impl<T: Clone> UpdateMap<T> for BTreeMap<usize, T> {
Some(Cow::BTree(cow))
}

fn get_arc(&self, k: usize) -> Option<Arc<T>> {
self.get(&k).cloned().map(Arc::new)
Copy link
Member

@michaelsproul michaelsproul Jul 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unfortunate because it's just creating a new Arc.

Maybe we could have this as a fallback impl, and for maps that support it (like BTreeMap<usize, Arc<T>> we can have an efficient impl). The problem will be overlapping impls. We could get around that with a new type like struct ArcMap<T>(VecMap<usize, Arc<T>>).

This is all turning out to be a bit complicated haha

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add iter_arc
2 participants