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

fix: map ttl reinsert head or tail #14

Merged
merged 4 commits into from
Dec 17, 2024

Conversation

arthhhhh23
Copy link
Contributor

No description provided.

@arthhhhh23 arthhhhh23 force-pushed the fix/ttl-map-orphaned-elements branch from 2422d9b to 0511b16 Compare December 17, 2024 01:46
ttl_test.go Outdated
@@ -174,6 +176,121 @@ func TestTTLScenario(t *testing.T) {
}
}

func TestHeadTailLogicConcurrent(t *testing.T) {
m := NewMapTTLCache[string, string](context.Background(), time.Millisecond, time.Hour)
Copy link
Owner

Choose a reason for hiding this comment

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

I usually use context with deferred cancel to avoid having live goroutine after test is finished (this sometimes causes test to fail, eg when using goleak).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added

t.Errorf("unexpected error in cleanup: %v", err)
}

if m.Len() != 0 {
Copy link
Owner

Choose a reason for hiding this comment

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

Should we also add a check that head and tail are zero values? Just in case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added

Copy link
Owner

Choose a reason for hiding this comment

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

Oh now it found coverage decrease. I can add missing tests later.

c.data[key] = val
return
}

// If it's already the tail, we only need to update the value and timestamp
Copy link
Owner

Choose a reason for hiding this comment

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

Trying to wrap my head around what actually was happening before. Looks like the root issue is that we were overwriting tail with record that had prev = tail?

Choose a reason for hiding this comment

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

I think what happened was when the set key is the head we did not update the head, leaving orphans.

  1. [A, B, C, D] where A is head, D is tail
  2. inserts A again, A becomes tail with no next but still is the head because it was not set to B, this orphans B,C,D as they are no longer part of the linked list

Copy link
Owner

Choose a reason for hiding this comment

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

Updating head should not be a common case when cache is heavily utilised. Updating tail will.

Copy link
Owner

@C-Pro C-Pro Dec 17, 2024

Choose a reason for hiding this comment

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

But both cases were buggy :)

Copy link
Owner

@C-Pro C-Pro left a comment

Choose a reason for hiding this comment

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

LGTM, nice catch! Thanks!

Comment on lines +209 to +212
rec := c.data[c.tail]
rec.timestamp = ts
rec.value = value
c.data[c.tail] = rec

Choose a reason for hiding this comment

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

nit: Why not just this?

Suggested change
rec := c.data[c.tail]
rec.timestamp = ts
rec.value = value
c.data[c.tail] = rec
c.data[c.tail] = val

Copy link
Contributor Author

Choose a reason for hiding this comment

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

because val.prev is the element being inserted itself, so we're losing the link to the actual prev

Copy link

codecov bot commented Dec 17, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 99.17%. Comparing base (0242bfa) to head (112ed3b).
Report is 6 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff             @@
##              main      #14      +/-   ##
===========================================
- Coverage   100.00%   99.17%   -0.83%     
===========================================
  Files            7        7              
  Lines          661      729      +68     
===========================================
+ Hits           661      723      +62     
- Misses           0        4       +4     
- Partials         0        2       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@C-Pro C-Pro merged commit 5192b20 into C-Pro:main Dec 17, 2024
5 checks passed
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