- Added more detailed explanations of the mechanics related to returning
ErrNotFound(#136)
- Fix inconsistent singleflight results if the key is invalidated on the way (#137)
- Fix panic during concurrent execution of
InvalidateAllandGetunder high contention (#139)
This release focuses on improving the integration experience with pull-based metric collectors.
- Added
IsWeighted,IsRecordingStatsandStatsmethods for cache (#131) - Added
MinusandPlusmethods forstats.Stats - Added
stats.Snapshoterandstats.SnapshotRecorderinterfaces
- Reduced memory consumption of
stats.Counterby 4 times
Getnow returns the value from the loader even when an error is returned. (#132)
- Added
Compute,ComputeIfAbsentandComputeIfPresentmethods - Added
LoadCacheFrom,LoadCacheFromFile,SaveCacheToandSaveCacheToFilefunctions - Added
Clockinterface and option for time mocking - Added
KeysandValuesiterators - Added
HottestandColdestiterators
- Slightly reduced memory consumption
- Cache became significantly faster in cases when it's lightly populated
- Reduced number of allocations during refresh
- Fixed a bug in timer wheel (#64)
- Added usage of
context.WithoutCancelduring refresh execution (#124)
Otter v2 has been completely redesigned for better performance and usability.
Key improvements:
- Completely rethought API for greater flexibility
- Added loading and refreshing features (#26)
- Added entry pinning
- Replaced eviction policy with adaptive W-TinyLFU, enabling Otter to achieve one of the highest hit rates across all workloads.
- Added HashDoS protection against potential attacks
- The task scheduling mechanism has been completely reworked, allowing users to manage it themselves when needed
- Added more efficient write buffer
- Added auto-configurable lossy read buffer
- Optimized hash table
- Test coverage increased to 97%
-
Cache Creation
- Removed
Builderpattern in favor of canonicalOptionsstruct MustBuilderandBuildermethods are replaced withMustandNewfunctionsCostrenamed toWeight- Replaced unified
capacitywith explicitMaximumSizeandMaximumWeightparameters - Replaced
DeletionListenerwithOnDeletionandOnAtomicDeletionhandlers - The ability to create a cache with any combination of features
- Removed
-
Cache API Changes
Getmethod renamed toGetIfPresentSetmethod signature changed to return both value and boolSetIfAbsentmethod signature changed to return both value and boolDeletemethod renamed toInvalidateClearmethod renamed toInvalidateAllSizemethod renamed toEstimatedSizeCapacitymethod renamed toGetMaximumRangemethod removed in favor ofAlliteratorHasmethod removedDeleteByFuncmethod removedStatsmethod removed in favor ofstats.RecorderinterfaceClosemethod removed
-
Expiration
- Expiration API is now more flexible with
ExpiryCalculatorinterface ExpiryCreating,ExpiryWritingandExpiryAccessingfunctions introduced
- Expiration API is now more flexible with
-
Statistics
- Moved statistics to a separate package
stats stats.Recorderinterface andstats.Counterstruct introduced
- Moved statistics to a separate package
-
Extension
Extensionstruct removed in favor of methods fromCache
-
Loading
- Added
Getmethod for obtaining values if necessary - Added
Loaderinterface for retrieving values from the data source - Added
ErrNotFounderror for indicating missing entries
- Added
-
Refresh
- Added flexible refresh API with
RefreshCalculatorinterface RefreshCreating,RefreshWritingfunctions introduced- Added
Refreshmethod for refreshing values asynchronously
- Added flexible refresh API with
-
Bulk Operations
- Added
BulkGetfor loading multiple values at once - Added
BulkRefreshfor refreshing multiple values asynchronously - Added
BulkLoaderinterface for retrieving multiple values from the data source at once
- Added
-
Cache Methods
- Added
Allmethod for iterating over all entries - Added
CleanUpmethod for performing pending maintenance operations - Added
WeightedSizemethod for weight-based caches
- Added
-
Enhanced Configuration
- Added
Executoroption for customizing async operations - Added
Loggerinterface for custom logging
- Added
-
Entry Management
- Added
SetExpiresAfterandSetRefreshableAfterfor per-entry time control - Added
GetEntryandGetEntryQuietlymethods for accessing cache entries - Most
Entry's methods replaced with public fields for direct access.
- Added
-
Deletion Notifications
- Replaced
DeletionListenerwithOnDeletionandOnAtomicDeletionhandlers - Deletion causes renamed for clarity and consistency.
- Added
IsEvictionmethod - Added
DeletionEventstruct
- Replaced
-
Performance Improvements
- Replaced
S3-FIFOwith adaptiveW-TinyLFU - Added more efficient write buffer
- Added auto-configurable lossy read buffer
- The task scheduling mechanism has been completely reworked, allowing users to manage it themselves when needed.
- Replaced
- Added loading and refreshing features (#26)
- You can now pass a custom implementation of the
stats.Recorderinterface (#119) - You can now use a TTL shorter than
time.Second(#115)
- Fixed a bug due to changing gammazero/deque contracts without v2 release. (#112)
- Added collection of eviction statistics for expired entries. (#108)
- Implemented
fmt.Stringerinterface forDeletionReasontype (#100)
- Fixed processing of an expired entry in the
Getmethod (#98) - Fixed inconsistent deletion listener behavior (#98)
- Fixed the behavior of
checkedAddwhen over/underflow (#91)
- Fixed uint32 capacity overflow.
The main innovation of this release is the addition of an Extension, which makes it easy to add a huge number of features to otter.
Usage example:
key := 1
...
entry, ok := cache.Extension().GetEntry(key)
...
key := entry.Key()
value := entry.Value()
cost := entry.Cost()
expiration := entry.Expiration()
ttl := entry.TTL()
hasExpired := entry.HasExpired()- Added support for Go 1.22
- Memory consumption with small cache sizes is reduced to the level of other libraries (#66)
- Fixed alignment issues on 32-bit archs
The main innovation of this release is node code generation. Thanks to it, the cache will no longer consume more memory due to features that it does not use. For example, if you do not need an expiration policy, then otter will not store the expiration time of each entry. It also allows otter to use more effective expiration policies.
Another expected improvement is the correction of minor synchronization problems due to the state machine. Now otter, unlike other contention-free caches in Go, should not have them at all.
- Added
DeleteByFuncfunction to cache (#44) - Added
InitialCapacityfunction to builder (#47) - Added collection of additional statistics (#57)
- Added proactive queue-based and timer wheel-based expiration policies with O(1) time complexity (#55)
- Added node code generation (#55)
- Fixed the race condition when changing the order of events (#59)
- Reduced memory consumption on small caches
- Builder pattern support
- Cleaner API compared to other caches (#40)
- Added
SetIfAbsentandRangefunctions (#27) - Statistics collection (#4)
- Cost based eviction
- Support for generics and any comparable types as keys
- Support ttl (#14)
- Excellent speed (benchmark results)
- O(1) worst case time complexity for S3-FIFO instead of O(n)
- Improved hit ratio of S3-FIFO on many traces (simulator results)