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

NPeersForCpl and collapse empty buckets #77

Merged
merged 7 commits into from
May 11, 2020

Conversation

aarshkshah1992
Copy link
Contributor

@aarshkshah1992 aarshkshah1992 commented Apr 21, 2020

In meta-issue libp2p/go-libp2p-kad-dht#556, this if for:

table.go Outdated
Comment on lines 124 to 126
for _, p := range rt.buckets[cpl].peerIds() {
peers = append(peers, p)
}

Choose a reason for hiding this comment

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

Suggested change
for _, p := range rt.buckets[cpl].peerIds() {
peers = append(peers, p)
}
return rt.buckets[cpl].peerIds()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We don't need this function anymore.

@@ -85,6 +85,58 @@ func (rt *RoutingTable) Close() error {
return nil
}

// NPeersForCPL returns the number of peers we have for a given Cpl
func (rt *RoutingTable) NPeersForCpl(cpl uint) int {

Choose a reason for hiding this comment

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

can you get away without this function, and just call
len(GetPeersForCpl) instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Have removed GetPeersForCpl as we don't need it anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We've removed GetPeersForCpl as we don't need it anymore.

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess this is a tiny bit more efficient then just len(GetPeersForCpl) and we can always add GetPeersForCpl back in if we need it. Your call 😄

Copy link
Contributor

@aschmahmann aschmahmann left a comment

Choose a reason for hiding this comment

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

Left a couple comments here. libp2p/go-libp2p-kad-dht#601 is up next.

table.go Outdated
Comment on lines 97 to 98
for _, p := range b.peerIds() {
if CommonPrefixLen(rt.local, ConvertPeerID(p)) == int(cpl) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be using b.peers and p.kadID instead of b.peerIds and ConvertPeerID(p). Gotta cache those hashes 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is done.

table.go Outdated
Comment on lines 118 to 119
for _, p := range b.peerIds() {
if CommonPrefixLen(rt.local, ConvertPeerID(p)) == int(cpl) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be using b.peers and p.kadID instead of b.peerIds and ConvertPeerID(p). Gotta cache those hashes 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We've removed this function.

table.go Show resolved Hide resolved
table.go Outdated
Comment on lines 132 to 133
// IsBucketFull returns true if the Logical bucket for a given Cpl is full
func (rt *RoutingTable) IsBucketFull(cpl uint) bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this function used for anything, or just here for convenience/to be more efficient then len(GetPeersForCpl) == bucketSize? The one place it's used in the libp2p/go-libp2p-kad-dht#601 seems like an oversight to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We've removed this function now.

Comment on lines +172 to +176
// if we're querying the peer first time after adding it, let's give it a
// usefulness bump. This will ONLY happen once.
if peer.LastUsefulAt.IsZero() && queryPeer {
peer.LastUsefulAt = lastUsefulAt
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this fix related to the rest of the PR, or just a "while I'm already here" kind of thing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hey,

This change is not related to the rest of the PR.
I think I wasn't being mindful when I put this change in as I didn't realize I hadn't changed the branch. Apologies.

Copy link
Contributor

Choose a reason for hiding this comment

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

No problem, while you're here and changing this do you mind add more information to the TryAddPeer comment about when we set LastUsefulAt? There is currently only information about when we set LastSuccessfulOutboundQuery

table_test.go Show resolved Hide resolved
table.go Outdated
Comment on lines 299 to 300
// if the second last bucket just became empty, remove and replace it with the last bucket.
if bucketID == len(rt.buckets)-2 && len(bucket.peers()) == 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this is good enough, as is shown in my test comment. What happens if we have buckets 1,2,3,4 and remove the peers from buckets 2 then 3 then 4? Here we'll collapse bucket 4 into bucket 3 and bucket 3 into bucket 2, leaving us with two total buckets instead of just one.

Perhaps doing this in a for loop would be better so we can close all buckets at the end that are empty.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree and this has been fixed.

table.go Outdated
// remove this bucket if it was the last bucket and it's now empty
// provided it isn't the ONLY bucket we have.
if len(rt.buckets) > 1 && bucketID == len(rt.buckets)-1 && len(bucket.peers()) == 0 {
rt.buckets[bucketID] = nil
Copy link
Contributor

Choose a reason for hiding this comment

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

Might be just blanking here, but why are we doing this? Does it help the garbage collector out in some way?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It helps the GC garbage collect the struct pointed to by the slice element as I understand from here:

https://github.com/golang/go/wiki/SliceTricks (Look at the section on Delete).
However, to truly grok the mechanics and reasons behind this, I've posted a question on one of our go forums and will post the answer here when I get one.

@Stebalien Stebalien requested a review from aschmahmann May 4, 2020 06:19
Copy link
Contributor

@aschmahmann aschmahmann left a comment

Choose a reason for hiding this comment

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

Left a brief comment, but otherwise LGTM

Comment on lines +172 to +176
// if we're querying the peer first time after adding it, let's give it a
// usefulness bump. This will ONLY happen once.
if peer.LastUsefulAt.IsZero() && queryPeer {
peer.LastUsefulAt = lastUsefulAt
}
Copy link
Contributor

Choose a reason for hiding this comment

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

No problem, while you're here and changing this do you mind add more information to the TryAddPeer comment about when we set LastUsefulAt? There is currently only information about when we set LastSuccessfulOutboundQuery

@@ -85,6 +85,58 @@ func (rt *RoutingTable) Close() error {
return nil
}

// NPeersForCPL returns the number of peers we have for a given Cpl
func (rt *RoutingTable) NPeersForCpl(cpl uint) int {
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess this is a tiny bit more efficient then just len(GetPeersForCpl) and we can always add GetPeersForCpl back in if we need it. Your call 😄

@aarshkshah1992
Copy link
Contributor Author

@aschmahmann Thanks for the review. I've added better documentation around LastUsefulAt . Merging this !

@aarshkshah1992 aarshkshah1992 merged commit eb2adab into master May 11, 2020
@aarshkshah1992 aarshkshah1992 deleted the feat/npeer-and-collapse-buckets branch May 11, 2020 07:03
@Stebalien Stebalien mentioned this pull request May 26, 2020
77 tasks
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.

3 participants