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

chore(DenseSet): defrag all links in a chain #4019

Merged
merged 4 commits into from
Nov 4, 2024
Merged

chore(DenseSet): defrag all links in a chain #4019

merged 4 commits into from
Nov 4, 2024

Conversation

kostasrim
Copy link
Contributor

We did not properly defrag all links in a chain. This PR adds this.

  • add defrag for all nodes in a link chain

@kostasrim kostasrim self-assigned this Oct 30, 2024
bool reallocated = false;
while (ptr->IsLink()) {
reallocated |= body(ptr->AsLink());
ptr = ptr->Next();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Need to add a test, we don't actually hit this condition (and we do not iterate over the links -- and I want this tested.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

IMO kinda hard to test TraverseApply because of how it's encapsulated. So looking for alternatives 😄

Comment on lines 851 to 852
fun(ptr->AsLink());
ptr = ptr->Next();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
fun(ptr->AsLink());
ptr = ptr->Next();
DenseLinkKey* link = ptr->AsLink();
fun(link);
ptr = &link->next;

@@ -840,4 +840,20 @@ size_t DenseSet::SizeSlow() {
return size_;
}

size_t DenseSet::IteratorBase::TraverseApply(DensePtr* ptr, std::function<void(DensePtr*)> fun) {
if (!ptr->IsLink()) {
fun(ptr);
Copy link
Collaborator

Choose a reason for hiding this comment

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

chain link ends with a regular DensePtr, so the way the function is written, it will skip the last node in the chain

Copy link
Contributor Author

@kostasrim kostasrim Oct 31, 2024

Choose a reason for hiding this comment

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

I added LOGS to check TraverseApply with the tests before I pushed and your comment explains why there were links with only one element -- I was missing the last one :/ I fixed this. Also does that mean we have the same issue in Scan ?

    // Check home bucket
    if (!curr->IsEmpty() && !curr->IsDisplaced()) {
      // scanning add all entries in a given chain
      while (true) {
        cb(curr->GetObject());
        if (!curr->IsLink())
          break;
  
        DensePtr* mcurr = const_cast<DensePtr*>(curr);
  
        if (ExpireIfNeeded(mcurr, &mcurr->AsLink()->next) && !mcurr->IsLink()) {
          break;
        }   
        curr = &curr->AsLink()->next;
      }   
    }

cb not called on the last element because we break when if (!curr->IsLink())

Copy link
Collaborator

Choose a reason for hiding this comment

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

seems like it! how come our tests did not catch it?

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 do not know! I will fix it 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

code is correct 🤣 we apply the cb on the last node and GetObject() takes care of that... 🤦

@kostasrim kostasrim requested a review from romange October 31, 2024 08:17
@@ -840,4 +840,27 @@ size_t DenseSet::SizeSlow() {
return size_;
}

size_t DenseSet::IteratorBase::TraverseApply(DensePtr* ptr, std::function<void(DensePtr*)> fun) {
if (!ptr->IsLink()) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

you can simplify the code if you just delete these 3 lines.

@kostasrim kostasrim requested a review from romange November 4, 2024 07:57
if (cb) {
cb((sds)obj, (sds)new_obj);
bool reallocated = false;
auto body = [ratio, &cb, &reallocated](auto* ptr) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: since there are many pointers of differrent types, it could be nice to use explicit DensePtr here and also below in StringMap

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 wanted to do the same, the problem is DensePtr is private in this context so it can't really be used ☹️ Maybe we can make them public ? (I will patch this in a follow up PR with a few boilerplate removed)

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.

2 participants