-
Notifications
You must be signed in to change notification settings - Fork 601
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
Feature: Add setOrGet
Function to Cache Implementation
#383
base: main
Are you sure you want to change the base?
Conversation
added setIfNotExists
added SetIfNotExists
added test
Codecov Report
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. @@ Coverage Diff @@
## main #383 +/- ##
==========================================
+ Coverage 88.66% 88.94% +0.27%
==========================================
Files 15 15
Lines 794 823 +29
==========================================
+ Hits 704 732 +28
Misses 76 76
- Partials 14 15 +1
Continue to review full report in Codecov by Sentry.
|
shard.go
Outdated
s.lock.RUnlock() | ||
s.lock.Lock() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is problematic. We have a read lock and then we lock to insert something. Another goroutine might hijack our lock in meantime.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for answer
i think i found somewhere that this actions(locks) are atomic and in that case will not be possible to jump between them and with performance in mind i have sent code you have seen. Original code is below it is more readable and if you sad more robust, than i will change request with code below.
Original code was
func (s *cacheShard) setOrGet(key string, hashedKey uint64, entry []byte) (actual []byte, loaded bool, err error) {
s.lock.Lock()
defer s.lock.Unlock()
wrappedEntry, err := s.getWrappedEntry(hashedKey)
if err == nil {
if entryKey := readKeyFromEntry(wrappedEntry); key == entryKey {
actual = readEntry(wrappedEntry)
s.hit(hashedKey)
return actual, true, nil
} else {
s.collision()
if s.isVerbose {
s.logger.Printf("Collision detected. Both %q and %q have the same hash %x", key, entryKey, hashedKey)
}
delete(s.hashmap, hashedKey)
s.onRemove(wrappedEntry, Deleted)
if s.statsEnabled {
delete(s.hashmapStats, hashedKey)
}
resetHashFromEntry(wrappedEntry)
}
} else if !errors.Is(err, ErrEntryNotFound) {
return entry, false, err
}
return entry, false, s.addNewWithoutLock(key, hashedKey, entry)
}
@ndjuric-bit Thanks for this. I think we need to solve issue with concurrent updates during |
- error test added
@janisz Is there something needed from my side more ? |
Overview:
This pull request introduces a new feature to our cache implementation by adding the SetOrGet function. This function allows clients to efficiently set a cache entry if it doesn't exist or retrieve the existing value associated with a given key. It returns the actual value, a boolean indicating whether the entry was loaded from the cache or not, and any potential error.
Function Signature::
SetOrGet(key string, entry []byte) (actual []byte, loaded bool, err error)
Parameters:
Return Values:
Example:
Testing:
This pull request includes unit tests to ensure the correct behavior of the SetOrGet function. The tests cover various scenarios, including cache hits and cache misses.
Impact on Existing Code:
This change introduces a new function to cache system. Existing code that uses the cache may benefit from this function for efficient get-or-set operations, but it should not negatively impact the existing functionality. This change is designed to be backward compatible.
Documentation:
The function's usage has been documented, and code comments have been updated to reflect the introduction of the SetOrGet function.
Reviewer Instructions:
Please review the code changes and documentation to ensure that the SetOrGet function is correctly implemented and well-documented. Verify that the function behaves as expected, handles errors gracefully, and is a useful addition to our cache system.
In case of hash collision behaviour of get function is held plus old data is deleted and new one is stored
Testing Instructions:
Verify that the unit tests pass and consider adding additional test cases as needed to cover any edge cases.
Changelog: