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

KBucketsTable.applied_pending is confusing #5644

Open
nazar-pc opened this issue Oct 23, 2024 · 1 comment
Open

KBucketsTable.applied_pending is confusing #5644

nazar-pc opened this issue Oct 23, 2024 · 1 comment

Comments

@nazar-pc
Copy link
Contributor

I was looking into #5626 and noticed that all iterators require exclusive (mutable) access to the whole KBucketsTable, moreover, its buckets are being modified during iteration over k-buckets, which is extremely confusing and feels like a completely arbitrary place to do this:

impl<TTarget, TKey, TVal, TMap, TOut> Iterator for ClosestIter<'_, TTarget, TKey, TVal, TMap, TOut>
where
TTarget: AsRef<KeyBytes>,
TKey: Clone + AsRef<KeyBytes>,
TVal: Clone,
TMap: Fn(&KBucket<TKey, TVal>) -> Vec<TOut>,
TOut: AsRef<KeyBytes>,
{
type Item = TOut;
fn next(&mut self) -> Option<Self::Item> {
loop {
match &mut self.iter {
Some(iter) => match iter.next() {
Some(k) => return Some(k),
None => self.iter = None,
},
None => {
if let Some(i) = self.buckets_iter.next() {
let bucket = &mut self.table.buckets[i.get()];
if let Some(applied) = bucket.apply_pending() {
self.table.applied_pending.push_back(applied)
}
let mut v = (self.fmap)(bucket);
v.sort_by(|a, b| {
self.target
.as_ref()
.distance(a.as_ref())
.cmp(&self.target.as_ref().distance(b.as_ref()))
});
self.iter = Some(v.into_iter());
} else {
return None;
}
}
}
}
}
}

Specifically this part:

let bucket = &mut self.table.buckets[i.get()];
if let Some(applied) = bucket.apply_pending() {
self.table.applied_pending.push_back(applied)
}

I did a quick look around, but wasn't able to easily fix this. Someone with better knowledge of the codebase should look into it. It is very hard to maintain the project when code so convoluted.

@guillaumemichel
Copy link
Contributor

I just had a look at the code, and I also find it very convoluted. It can definitely be simplified, but it will take a non negligible amount of refactor.

mergify bot pushed a commit that referenced this issue Oct 24, 2024
## Description

Fixes #5626

## Notes & open questions

This is the nicest way I came up with, I decided to leave
`get_closest_local_peers` as is since it does return all peers, not just
`replication_factor` peers.

Looking at #2436 it is not
clear if @folex really needed all peers returned or it just happened
that way. I'm also happy to change proposed API to return all peers if
that is preferred by others.

It is very unfortunate that `&mut self` is needed for this, I created
#5644 that if resolved will
allow to have `&self` instead.

## Change checklist

- [x] I have performed a self-review of my own code
- [x] I have made corresponding changes to the documentation
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] A changelog entry has been made in the appropriate crates

Co-authored-by: João Oliveira <hello@jxs.pt>
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

No branches or pull requests

2 participants