Feature: Add setOrGet Function to Cache Implementation#383
Feature: Add setOrGet Function to Cache Implementation#383ndjuric-bit wants to merge 12 commits intoallegro:mainfrom
setOrGet Function to Cache Implementation#383Conversation
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.
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.
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: